]> granicus.if.org Git - sudo/commitdiff
Flesh out the fake passwd entry used for running commands as a uid not
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Jul 2008 10:27:57 +0000 (10:27 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Jul 2008 10:27:57 +0000 (10:27 +0000)
listed in the passwd database.  Fixes an issue with some PAM modules.

pwutil.c
sudo.c
sudo.h
testsudoers.c

index 6fb49b59397795dcf8b6477da2e33fc482f59d23..941b3267c59d42aebd2d2e02b5a4d0aff0cf5a0b 100644 (file)
--- a/pwutil.c
+++ b/pwutil.c
@@ -270,52 +270,35 @@ sudo_getpwnam(name)
     }
 }
 
-/*
- * Take a uid and return a faked up passwd struct.
- */
-struct passwd *
-sudo_fakepwuid(uid)
-    uid_t uid;
-{
-    struct passwd *pw;
-    struct rbnode *node;
-
-    pw = emalloc(sizeof(struct passwd) + MAX_UID_T_LEN + 1);
-    memset(pw, 0, sizeof(struct passwd));
-    pw->pw_uid = uid;
-    pw->pw_name = (char *)pw + sizeof(struct passwd);
-    (void) snprintf(pw->pw_name, MAX_UID_T_LEN + 1, "#%lu",
-       (unsigned long) uid);
-
-    /* Store by uid and by name, overwriting cached version. */
-    if ((node = rbinsert(pwcache_byuid, pw)) != NULL) {
-       efree(node->data);
-       node->data = (void *) pw;
-    }
-    if ((node = rbinsert(pwcache_byname, pw)) != NULL) {
-       efree(node->data);
-       node->data = (void *) pw;
-    }
-    return(pw);
-}
-
 /*
  * Take a uid in string form "#123" and return a faked up passwd struct.
  */
 struct passwd *
-sudo_fakepwnam(user)
+sudo_fakepwnam(user, gid)
     const char *user;
+    gid_t gid;
 {
     struct passwd *pw;
     struct rbnode *node;
     size_t len;
 
     len = strlen(user);
-    pw = emalloc(sizeof(struct passwd) + len + 1);
+    pw = emalloc(sizeof(struct passwd) + len + 1 /* pw_name */ +
+       sizeof("*") /* pw_passwd */ + sizeof("") /* pw_gecos */ +
+       sizeof("/") /* pw_dir */ + sizeof(_PATH_BSHELL));
     memset(pw, 0, sizeof(struct passwd));
     pw->pw_uid = (uid_t) atoi(user + 1);
+    pw->pw_gid = gid;
     pw->pw_name = (char *)pw + sizeof(struct passwd);
-    strlcpy(pw->pw_name, user, len + 1);
+    memcpy(pw->pw_name, user, len + 1);
+    pw->pw_passwd = pw->pw_name + len + 1;
+    memcpy(pw->pw_passwd, "*", 2);
+    pw->pw_gecos = pw->pw_passwd + 2;
+    pw->pw_gecos[0] = '\0';
+    pw->pw_dir = pw->pw_gecos + 1;
+    memcpy(pw->pw_dir, "/", 2);
+    pw->pw_shell = pw->pw_dir + 2;
+    memcpy(pw->pw_shell, _PATH_BSHELL, sizeof(_PATH_BSHELL));
 
     /* Store by uid and by name, overwriting cached version. */
     if ((node = rbinsert(pwcache_byuid, pw)) != NULL) {
diff --git a/sudo.c b/sudo.c
index 0f094a527d0a44384fc5f6c9a6cd3827b0629510..6698e189d1ad0e03c08a0cbb3392f070466479e6 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -297,11 +297,8 @@ main(argc, argv, envp)
     set_loginclass(sudo_user.pw);
 
     /* Update initial shell now that runas is set. */
-    if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
-       if (runas_pw->pw_shell == NULL)
-           errorx(1, "no login shell for user %s!", runas_pw->pw_name);
+    if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
        NewArgv[0] = runas_pw->pw_shell;
-    }
 
     /* This goes after sudoers is parsed since it may have timestamp options. */
     if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
@@ -1311,7 +1308,7 @@ set_runaspw(user)
 {
     if (*user == '#') {
        if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
-           runas_pw = sudo_fakepwnam(user);
+           runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
     } else {
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
            log_error(NO_MAIL|MSG_ONLY, "unknown user: %s", user);
diff --git a/sudo.h b/sudo.h
index f7e7af208a89e53f9257cb3e5f8b5518ebfc21ad..9429fc0ce5d88324247c2e448d1716bdd534d01f 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -308,9 +308,8 @@ void sudo_setspent  __P((void));
 void sudo_endspent     __P((void));
 void cleanup           __P((int));
 struct passwd *sudo_getpwnam __P((const char *));
-struct passwd *sudo_fakepwnam __P((const char *));
+struct passwd *sudo_fakepwnam __P((const char *, gid_t));
 struct passwd *sudo_getpwuid __P((uid_t));
-struct passwd *sudo_fakepwuid __P((uid_t));
 struct group *sudo_getgrnam __P((const char *));
 struct group *sudo_fakegrnam __P((const char *));
 struct group *sudo_getgrgid __P((gid_t));
index e9a0d908c543697283a1ecaf715e8c8abd5bd977..f7b1282f74b352b2960907d89d5a51d252a4866c 100644 (file)
@@ -314,7 +314,7 @@ set_runaspw(user)
 {
     if (*user == '#') {
        if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
-           runas_pw = sudo_fakepwnam(user);
+           runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
     } else {
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
            errorx(1, "unknown user: %s", user);