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:
29
parse.c
29
parse.c
@@ -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.
|
||||
*/
|
||||
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 *user;
|
||||
struct passwd *pw;
|
||||
{
|
||||
struct group *grp;
|
||||
struct passwd *pw;
|
||||
gid_t pw_gid;
|
||||
char **cur;
|
||||
|
||||
@@ -455,8 +474,8 @@ usergr_matches(group, user)
|
||||
if (*group++ != '%')
|
||||
return(FALSE);
|
||||
|
||||
/* look up user's primary gid in the passwd file (XXX - reduce lookups) */
|
||||
if ((pw = getpwnam(user)) == NULL)
|
||||
/* look up user's primary gid in the passwd file */
|
||||
if (pw == NULL && (pw = getpwnam(user)) == NULL)
|
||||
return(FALSE);
|
||||
pw_gid = pw->pw_gid;
|
||||
|
||||
|
3
parse.h
3
parse.h
@@ -96,6 +96,7 @@ int addr_matches __P((char *));
|
||||
int command_matches __P((char *, char *, char *, char *));
|
||||
int hostname_matches __P((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 */
|
||||
|
16
parse.yacc
16
parse.yacc
@@ -483,9 +483,11 @@ runasspec : /* empty */ {
|
||||
* If this is the first entry in a command list
|
||||
* then check against default runas user.
|
||||
*/
|
||||
if (runas_matches == -1)
|
||||
runas_matches = (strcmp(*user_runas,
|
||||
def_runas_default) == 0);
|
||||
if (runas_matches == -1) {
|
||||
runas_matches =
|
||||
userpw_matches(def_runas_default,
|
||||
*user_runas, runas_pw);
|
||||
}
|
||||
}
|
||||
| RUNAS runaslist {
|
||||
runas_matches = ($2 == TRUE ? TRUE : FALSE);
|
||||
@@ -525,7 +527,7 @@ runasuser : WORD {
|
||||
user_matches == TRUE)
|
||||
append_runas($1, ", ");
|
||||
}
|
||||
if (strcmp($1, *user_runas) == 0)
|
||||
if (userpw_matches($1, *user_runas, runas_pw))
|
||||
$$ = TRUE;
|
||||
else
|
||||
$$ = -1;
|
||||
@@ -539,7 +541,7 @@ runasuser : WORD {
|
||||
user_matches == TRUE)
|
||||
append_runas($1, ", ");
|
||||
}
|
||||
if (usergr_matches($1, *user_runas))
|
||||
if (usergr_matches($1, *user_runas, runas_pw))
|
||||
$$ = TRUE;
|
||||
else
|
||||
$$ = -1;
|
||||
@@ -818,14 +820,14 @@ opuser : user {
|
||||
;
|
||||
|
||||
user : WORD {
|
||||
if (strcmp($1, user_name) == 0)
|
||||
if (userpw_matches($1, user_name, sudo_user.pw))
|
||||
$$ = TRUE;
|
||||
else
|
||||
$$ = -1;
|
||||
free($1);
|
||||
}
|
||||
| USERGROUP {
|
||||
if (usergr_matches($1, user_name))
|
||||
if (usergr_matches($1, user_name, sudo_user.pw))
|
||||
$$ = TRUE;
|
||||
else
|
||||
$$ = -1;
|
||||
|
2
sudo.c
2
sudo.c
@@ -574,6 +574,8 @@ init_vars(sudo_mode)
|
||||
log_error(USE_ERRNO|MSG_ONLY, "can't get hostname");
|
||||
|
||||
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.
|
||||
|
@@ -236,9 +236,24 @@ hostname_matches(shost, lhost, pattern)
|
||||
}
|
||||
|
||||
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 *user;
|
||||
struct passwd *pw;
|
||||
{
|
||||
struct group *grp;
|
||||
char **cur;
|
||||
|
14
visudo.c
14
visudo.c
@@ -82,7 +82,8 @@ int command_matches __P((char *, char *, char *, char *));
|
||||
int addr_matches __P((char *));
|
||||
int hostname_matches __P((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 yyrestart __P((FILE *));
|
||||
|
||||
@@ -496,8 +497,17 @@ hostname_matches(s, l, p)
|
||||
}
|
||||
|
||||
int
|
||||
usergr_matches(g, u)
|
||||
usergr_matches(g, u, pw)
|
||||
char *g, *u;
|
||||
struct passwd *pw;
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
userpw_matches(s, u, pw)
|
||||
char *s, *u;
|
||||
struct passwd *pw;
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
Reference in New Issue
Block a user