diff --git a/getspwuid.c b/getspwuid.c index 07286d20c..0e4fa059d 100644 --- a/getspwuid.c +++ b/getspwuid.c @@ -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); } diff --git a/logging.c b/logging.c index 767219671..dc7f21592 100644 --- 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 b6c5fdf46..d57bf0445 100644 --- 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);