command line args from sudoers file are now in an array like
ones passed in from the command line
This commit is contained in:
103
parse.c
103
parse.c
@@ -85,7 +85,7 @@ int parse_error = FALSE;
|
|||||||
* Prototypes for static (local) functions
|
* Prototypes for static (local) functions
|
||||||
*/
|
*/
|
||||||
static int has_meta __P((char *));
|
static int has_meta __P((char *));
|
||||||
static int compare_args __P((char *, char *));
|
static int compare_args __P((char **, char **));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this routine is called from the sudo.c module and tries to validate
|
* this routine is called from the sudo.c module and tries to validate
|
||||||
@@ -168,8 +168,11 @@ int validate(check_cmnd)
|
|||||||
* If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
|
* If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
|
||||||
* otherwise, return TRUE if cmnd names one of the inodes in path
|
* otherwise, return TRUE if cmnd names one of the inodes in path
|
||||||
*/
|
*/
|
||||||
int path_matches(cmnd, path)
|
int path_matches(cmnd, user_args, path, sudoers_args)
|
||||||
char *cmnd, *path;
|
char *cmnd;
|
||||||
|
char **user_args;
|
||||||
|
char *path;
|
||||||
|
char **sudoers_args;
|
||||||
{
|
{
|
||||||
int plen;
|
int plen;
|
||||||
struct stat pst;
|
struct stat pst;
|
||||||
@@ -177,7 +180,6 @@ int path_matches(cmnd, path)
|
|||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
char buf[MAXPATHLEN+1];
|
char buf[MAXPATHLEN+1];
|
||||||
static char *c;
|
static char *c;
|
||||||
char *args;
|
|
||||||
|
|
||||||
/* don't bother with pseudo commands like "validate" */
|
/* don't bother with pseudo commands like "validate" */
|
||||||
if (*cmnd != '/')
|
if (*cmnd != '/')
|
||||||
@@ -193,10 +195,6 @@ int path_matches(cmnd, path)
|
|||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the given path has command line args, split them out */
|
|
||||||
if ((args = strchr(path, ' ')))
|
|
||||||
*args++ = '\0';
|
|
||||||
|
|
||||||
plen = strlen(path);
|
plen = strlen(path);
|
||||||
if (path[plen - 1] != '/') {
|
if (path[plen - 1] != '/') {
|
||||||
#ifdef FAST_MATCH
|
#ifdef FAST_MATCH
|
||||||
@@ -214,21 +212,16 @@ int path_matches(cmnd, path)
|
|||||||
if (stat(path, &pst) < 0)
|
if (stat(path, &pst) < 0)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
||||||
/* put things back the way we found 'em */
|
|
||||||
if (args)
|
|
||||||
*(args - 1) = ' ';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true if inode/device matches and there are no args
|
* Return true if inode/device matches and there are no args
|
||||||
* (in sudoers or command) or if the args match;
|
* (in sudoers or command) or if the args match;
|
||||||
* else return false.
|
* else return false.
|
||||||
*/
|
*/
|
||||||
if (cmnd_st.st_dev == pst.st_dev && cmnd_st.st_ino == pst.st_ino) {
|
if (cmnd_st.st_dev == pst.st_dev && cmnd_st.st_ino == pst.st_ino) {
|
||||||
if (!args) {
|
if (!sudoers_args) {
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
} else if (cmnd_args && args) {
|
} else if (user_args && sudoers_args) {
|
||||||
/* return((strcmp(cmnd_args, args) == 0)); */
|
return(compare_args(user_args, sudoers_args));
|
||||||
return(compare_args(args, cmnd_args));
|
|
||||||
} else {
|
} else {
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
@@ -263,6 +256,10 @@ int path_matches(cmnd, path)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if "n" is one of our ip addresses or if
|
||||||
|
* "n" is a network that we are on, else returns FALSE.
|
||||||
|
*/
|
||||||
int addr_matches(n)
|
int addr_matches(n)
|
||||||
char *n;
|
char *n;
|
||||||
{
|
{
|
||||||
@@ -282,6 +279,10 @@ int addr_matches(n)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if the given user belongs to the named group,
|
||||||
|
* else returns FALSE.
|
||||||
|
*/
|
||||||
int usergr_matches(group, user)
|
int usergr_matches(group, user)
|
||||||
char *group;
|
char *group;
|
||||||
char *user;
|
char *user;
|
||||||
@@ -312,6 +313,11 @@ int usergr_matches(group, user)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if "host" and "user" belong to the netgroup "netgr",
|
||||||
|
* else return FALSE. Either of "host" or "user" may be NULL
|
||||||
|
* in which case that argument is not checked...
|
||||||
|
*/
|
||||||
int netgr_matches(netgr, host, user)
|
int netgr_matches(netgr, host, user)
|
||||||
char *netgr;
|
char *netgr;
|
||||||
char *host;
|
char *host;
|
||||||
@@ -353,7 +359,8 @@ int netgr_matches(netgr, host, user)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Does "s" have any meta characters in it?
|
* Returns TRUE if "s" has shell meta characters in it,
|
||||||
|
* else returns FALSE.
|
||||||
*/
|
*/
|
||||||
static int has_meta(s)
|
static int has_meta(s)
|
||||||
char *s;
|
char *s;
|
||||||
@@ -370,56 +377,30 @@ static int has_meta(s)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* Compare two arguments lists and return TRUE if they are
|
||||||
|
* the same (inc. wildcard matches) or FALSE if they differ.
|
||||||
*/
|
*/
|
||||||
static int compare_args(sudoers_args, user_args)
|
static int compare_args(user_args, sudoers_args)
|
||||||
char *sudoers_args, *user_args;
|
char **user_args;
|
||||||
|
char **sudoers_args;
|
||||||
{
|
{
|
||||||
|
char **ua, **sa;
|
||||||
|
|
||||||
if (has_meta(sudoers_args)) {
|
for (ua=user_args, sudoers_args=sa; *ua && *sa; ua++, sa++) {
|
||||||
register char *s_a, *u_a, *s_save, *u_save, *s_a_next, *u_a_next;
|
/* only do wildcard match if there are meta chars */
|
||||||
|
/* XXX - is this really any faster? */
|
||||||
/* XXX - shouldn't need to copy strings */
|
if (has_meta(*sa)) {
|
||||||
s_save = s_a_next = strdup(sudoers_args);
|
if (wildmat(*ua, *sa) != 1)
|
||||||
u_save = u_a_next = strdup(user_args);
|
|
||||||
|
|
||||||
/* XXX - use a saner loop */
|
|
||||||
for (;;) {
|
|
||||||
/* break if end of string */
|
|
||||||
if (!s_a_next || !u_a_next)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* go to next substring */
|
|
||||||
s_a = s_a_next;
|
|
||||||
u_a = u_a_next;
|
|
||||||
|
|
||||||
/* null-terminate end of substring if necesary */
|
|
||||||
if ((s_a_next = strchr(s_a_next, ' ')))
|
|
||||||
*s_a_next++ = '\0';
|
|
||||||
if ((u_a_next = strchr(u_a_next, ' ')))
|
|
||||||
*u_a_next++ = '\0';
|
|
||||||
|
|
||||||
/* XXX - split on non-escaped ',' to allow like: "*,!root"
|
|
||||||
* and keep longest match.
|
|
||||||
*/
|
|
||||||
if (wildmat(u_a, s_a) != 1) {
|
|
||||||
(void) free(s_save);
|
|
||||||
(void) free(u_save);
|
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) free(s_save);
|
|
||||||
(void) free(u_save);
|
|
||||||
|
|
||||||
/* if full match both will be NULL */
|
|
||||||
if (s_a_next || u_a_next)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return((strcmp(sudoers_args, user_args) == 0));
|
if (strcmp(*ua, *sa))
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return false unless we got to the end of each */
|
||||||
|
if (*ua || *sa)
|
||||||
|
return(FALSE);
|
||||||
|
else
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user