If the user specified a uid with the -u flag and the uid exists in

the passwd file, set runas_user to the name, not the uid.

When comparing usernames in sudoers, if a name is really a uid (starts
with '#') compare it numerically to pw_uid.
This commit is contained in:
Todd C. Miller
2004-03-24 23:06:34 +00:00
parent 631cbc2857
commit 6190f376c1
6 changed files with 65 additions and 16 deletions

29
parse.c
View File

@@ -438,16 +438,35 @@ hostname_matches(shost, lhost, pattern)
} }
/* /*
* Returns TRUE if the given user belongs to the named group, * Returns TRUE if the user/uid from sudoers matches the specified user/uid,
* else returns FALSE. * else returns FALSE.
*/ */
int int
usergr_matches(group, user) userpw_matches(sudoers_user, user, pw)
char *sudoers_user;
char *user;
struct passwd *pw;
{
if (pw != NULL && *sudoers_user == '#') {
uid_t uid = atoi(sudoers_user + 1);
if (uid == pw->pw_uid)
return(1);
}
return(strcmp(sudoers_user, user) == 0);
}
/*
* Returns TRUE if the given user belongs to the named group,
* else returns FALSE.
* XXX - reduce the number of passwd/group lookups
*/
int
usergr_matches(group, user, pw)
char *group; char *group;
char *user; char *user;
struct passwd *pw;
{ {
struct group *grp; struct group *grp;
struct passwd *pw;
gid_t pw_gid; gid_t pw_gid;
char **cur; char **cur;
@@ -455,8 +474,8 @@ usergr_matches(group, user)
if (*group++ != '%') if (*group++ != '%')
return(FALSE); return(FALSE);
/* look up user's primary gid in the passwd file (XXX - reduce lookups) */ /* look up user's primary gid in the passwd file */
if ((pw = getpwnam(user)) == NULL) if (pw == NULL && (pw = getpwnam(user)) == NULL)
return(FALSE); return(FALSE);
pw_gid = pw->pw_gid; pw_gid = pw->pw_gid;

View File

@@ -96,6 +96,7 @@ int addr_matches __P((char *));
int command_matches __P((char *, char *, char *, char *)); int command_matches __P((char *, char *, char *, char *));
int hostname_matches __P((char *, char *, char *)); int hostname_matches __P((char *, char *, char *));
int netgr_matches __P((char *, char *, char *, char *)); int netgr_matches __P((char *, char *, char *, char *));
int usergr_matches __P((char *, char *)); int userpw_matches __P((char *, char *, struct passwd *));
int usergr_matches __P((char *, char *, struct passwd *));
#endif /* _SUDO_PARSE_H */ #endif /* _SUDO_PARSE_H */

View File

@@ -483,9 +483,11 @@ runasspec : /* empty */ {
* If this is the first entry in a command list * If this is the first entry in a command list
* then check against default runas user. * then check against default runas user.
*/ */
if (runas_matches == -1) if (runas_matches == -1) {
runas_matches = (strcmp(*user_runas, runas_matches =
def_runas_default) == 0); userpw_matches(def_runas_default,
*user_runas, runas_pw);
}
} }
| RUNAS runaslist { | RUNAS runaslist {
runas_matches = ($2 == TRUE ? TRUE : FALSE); runas_matches = ($2 == TRUE ? TRUE : FALSE);
@@ -525,7 +527,7 @@ runasuser : WORD {
user_matches == TRUE) user_matches == TRUE)
append_runas($1, ", "); append_runas($1, ", ");
} }
if (strcmp($1, *user_runas) == 0) if (userpw_matches($1, *user_runas, runas_pw))
$$ = TRUE; $$ = TRUE;
else else
$$ = -1; $$ = -1;
@@ -539,7 +541,7 @@ runasuser : WORD {
user_matches == TRUE) user_matches == TRUE)
append_runas($1, ", "); append_runas($1, ", ");
} }
if (usergr_matches($1, *user_runas)) if (usergr_matches($1, *user_runas, runas_pw))
$$ = TRUE; $$ = TRUE;
else else
$$ = -1; $$ = -1;
@@ -818,14 +820,14 @@ opuser : user {
; ;
user : WORD { user : WORD {
if (strcmp($1, user_name) == 0) if (userpw_matches($1, user_name, sudo_user.pw))
$$ = TRUE; $$ = TRUE;
else else
$$ = -1; $$ = -1;
free($1); free($1);
} }
| USERGROUP { | USERGROUP {
if (usergr_matches($1, user_name)) if (usergr_matches($1, user_name, sudo_user.pw))
$$ = TRUE; $$ = TRUE;
else else
$$ = -1; $$ = -1;

2
sudo.c
View File

@@ -574,6 +574,8 @@ init_vars(sudo_mode)
log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); log_error(USE_ERRNO|MSG_ONLY, "can't get hostname");
set_runaspw(*user_runas); /* may call log_error() */ set_runaspw(*user_runas); /* may call log_error() */
if (*user_runas[0] == '#' && runas_pw->pw_name && runas_pw->pw_name[0])
*user_runas = estrdup(runas_pw->pw_name);
/* /*
* Get current working directory. Try as user, fall back to root. * Get current working directory. Try as user, fall back to root.

View File

@@ -236,9 +236,24 @@ hostname_matches(shost, lhost, pattern)
} }
int int
usergr_matches(group, user) userpw_matches(sudoers_user, user, pw)
char *sudoers_user;
char *user;
struct passwd *pw;
{
if (pw != NULL && *sudoers_user == '#') {
uid_t uid = atoi(sudoers_user + 1);
if (uid == pw->pw_uid)
return(1);
}
return(strcmp(sudoers_user, user) == 0);
}
int
usergr_matches(group, user, pw)
char *group; char *group;
char *user; char *user;
struct passwd *pw;
{ {
struct group *grp; struct group *grp;
char **cur; char **cur;

View File

@@ -82,7 +82,8 @@ int command_matches __P((char *, char *, char *, char *));
int addr_matches __P((char *)); int addr_matches __P((char *));
int hostname_matches __P((char *, char *, char *)); int hostname_matches __P((char *, char *, char *));
int netgr_matches __P((char *, char *, char *, char *)); int netgr_matches __P((char *, char *, char *, char *));
int usergr_matches __P((char *, char *)); int usergr_matches __P((char *, char *, struct passwd *));
int userpw_matches __P((char *, char *, struct passwd *));
void init_parser __P((void)); void init_parser __P((void));
void yyrestart __P((FILE *)); void yyrestart __P((FILE *));
@@ -496,8 +497,17 @@ hostname_matches(s, l, p)
} }
int int
usergr_matches(g, u) usergr_matches(g, u, pw)
char *g, *u; char *g, *u;
struct passwd *pw;
{
return(TRUE);
}
int
userpw_matches(s, u, pw)
char *s, *u;
struct passwd *pw;
{ {
return(TRUE); return(TRUE);
} }