]> granicus.if.org Git - sudo/commitdiff
Use setpwent()/endpwent() + all the shadow variants to make sure
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 10 May 2001 18:55:12 +0000 (18:55 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 10 May 2001 18:55:12 +0000 (18:55 +0000)
we don't inadvertantly leak an fd to the child.  Apparently Linux's
shadow routines leave the fd open even if you don't call setspent().
Reported by mike@gistnet.com; different patch used.

getspwuid.c
logging.c
sudo.c

index 07286d20c1dfc942eab9cc1fa67cab24b1cd4c65..0e4fa059d396089af4ef16304597c87d5ec57680 100644 (file)
@@ -114,72 +114,93 @@ sudo_getshell(pw)
 }
 
 /*
- * Return the encrypted password for the user described by pw.  If shadow
- * passwords are in use, look in the shadow file.
+ * Return a copy of the encrypted password for the user described by pw.
+ * If shadow passwords are in use, look in the shadow file.
  */
 char *
 sudo_getepw(pw)
     struct passwd *pw;
 {
+    char *epw;
 
     /* If there is a function to check for shadow enabled, use it... */
 #ifdef HAVE_ISCOMSEC
     if (!iscomsec())
-       return(pw->pw_passwd);
+       return(estrdup(pw->pw_passwd));
 #endif /* HAVE_ISCOMSEC */
 #ifdef HAVE_ISSECURE
     if (!issecure())
-       return(pw->pw_passwd);
+       return(estrdup(pw->pw_passwd));
 #endif /* HAVE_ISSECURE */
 
+    epw = NULL;
 #ifdef HAVE_GETPRPWNAM
     {
        struct pr_passwd *spw;
 
-       spw = getprpwnam(pw->pw_name);
-       if (spw != NULL && spw->ufld.fd_encrypt != NULL) {
+       setprpwent();
+       if ((spw = getprpwnam(pw->pw_name)) && spw->ufld.fd_encrypt) {
 # ifdef __alpha
            crypt_type = spw->ufld.fd_oldcrypt;
 # endif /* __alpha */
-           return(spw->ufld.fd_encrypt);
+           epw = estrdup(spw->ufld.fd_encrypt);
        }
+       endprpwent();
+       if (epw)
+           return(epw);
     }
 #endif /* HAVE_GETPRPWNAM */
 #ifdef HAVE_GETSPNAM
     {
        struct spwd *spw;
 
+       setspent();
        if ((spw = getspnam(pw->pw_name)) && spw->sp_pwdp)
-           return(spw->sp_pwdp);
+           epw = estrdup(spw->sp_pwdp);
+       endspent();
+       if (epw)
+           return(epw);
     }
 #endif /* HAVE_GETSPNAM */
 #ifdef HAVE_GETSPWUID
     {
        struct s_passwd *spw;
 
+       setspwent();
        if ((spw = getspwuid(pw->pw_uid)) && spw->pw_passwd)
-           return(spw->pw_passwd);
+           epw = estrdup(spw->pw_passwd);
+       endspwent();
+       if (epw)
+           return(epw);
     }
 #endif /* HAVE_GETSPWUID */
 #ifdef HAVE_GETPWANAM
     {
        struct passwd_adjunct *spw;
 
+       setpwaent();
        if ((spw = getpwanam(pw->pw_name)) && spw->pwa_passwd)
-           return(spw->pwa_passwd);
+           epw = estrdup(spw->pwa_passwd);
+       endpwaent();
+       if (epw)
+           return(epw);
     }
 #endif /* HAVE_GETPWANAM */
 #ifdef HAVE_GETAUTHUID
     {
        AUTHORIZATION *spw;
 
+       setauthent();
        if ((spw = getauthuid(pw->pw_uid)) && spw->a_password)
-           return(spw->a_password);
+           epw = estrdup(spw->a_password);
+       endauthent();
+       if (epw)
+           return(epw);
     }
 #endif /* HAVE_GETAUTHUID */
 
     /* Fall back on normal password. */
-    return(pw->pw_passwd);
+    return(estrdup(pw->pw_passwd));
 }
 
 /*
@@ -210,7 +231,7 @@ sudo_pwdup(pw)
     local_pw->pw_shell = estrdup(sudo_getshell(pw));
 
     /* pw_passwd gets a shadow password if applicable */
-    local_pw->pw_passwd = estrdup(sudo_getepw(pw));
+    local_pw->pw_passwd = sudo_getepw(pw);
 
     return(local_pw);
 }
index 767219671766b51bd638585a455aa34190cdcdbf..dc7f215924c6ffa9e250eb2b7b28194d5420eb5e 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -490,6 +490,9 @@ send_mail(line)
                }
                argv[i] = NULL;
 
+               /* Close password file so we don't leak the fd. */
+               endpwent();
+
                /* Run mailer as root so user cannot kill it. */
                set_perms(PERM_ROOT, 0);
                execv(mpath, argv);
diff --git a/sudo.c b/sudo.c
index b6c5fdf46d84b4a52c006398b6bd2781aa84aace..d57bf0445d2ff46aa6a1c515d41ffedd89e99da2 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -191,6 +191,7 @@ main(argc, argv, envp)
      * Setup signal handlers, turn off core dumps, and close open files.
      */
     initial_setup();
+    setpwent();
 
     /* Parse our arguments. */
     sudo_mode = parse_args();
@@ -338,6 +339,9 @@ main(argc, argv, envp)
                "please report this error at http://courtesan.com/sudo/bugs/");
        }
 
+       /* Close the password file */
+       endpwent();
+
        /* Reset signal mask before we exec. */
 #ifdef POSIX_SIGNALS
        (void) sigprocmask(SIG_SETMASK, &oset, NULL);