]> granicus.if.org Git - sudo/commitdiff
If the user specified a uid with the -u flag and the uid exists in
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 24 Mar 2004 23:06:34 +0000 (23:06 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 24 Mar 2004 23:06:34 +0000 (23:06 +0000)
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.

parse.c
parse.h
parse.yacc
sudo.c
testsudoers.c
visudo.c

diff --git a/parse.c b/parse.c
index 64a9fbec3178f01345b4725c1f4a83735d95cb11..33a77021b4990577bfa026c6660cf02330c79b8f 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -437,17 +437,36 @@ hostname_matches(shost, lhost, pattern)
     }
 }
 
+/*
+ *  Returns TRUE if the user/uid from sudoers matches the specified user/uid,
+ *  else returns FALSE.
+ */
+int
+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)
+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;
 
diff --git a/parse.h b/parse.h
index 1f49c0be33d717b9b7fcfc51ba1be904bb824d17..dc0bec93744ad32d220858221748344a9f38479c 100644 (file)
--- a/parse.h
+++ b/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 */
index f4e1cc4c2061ddeabbda45cc2453c9456dc353c3..e4c7f184e33bd301942f70cb8fcd06c48ccbdfda 100644 (file)
@@ -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;
diff --git a/sudo.c b/sudo.c
index fa053a913547991554aa5e45e63a5502756c993a..427d58b2408440d2677b39628f9a0bffe40ef993 100644 (file)
--- a/sudo.c
+++ b/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.
index ce7d24f093a32a66c929fb2525a31ad97361a81c..72067a0772faccb0dda367d00d376d3b76477b65 100644 (file)
@@ -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;
index 113995552845527fd15fbb79315d39caac8a464c..75943cc341fc56b595e2cbed0133ead505dadf0a 100644 (file)
--- a/visudo.c
+++ b/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);
 }