From 11127e34682e646bb08c807565cf4098c77b0a23 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 10 May 2001 18:55:12 +0000 Subject: [PATCH] Use setpwent()/endpwent() + all the shadow variants to make sure 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 | 47 ++++++++++++++++++++++++++++++++++------------- logging.c | 3 +++ sudo.c | 4 ++++ 3 files changed, 41 insertions(+), 13 deletions(-) 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); -- 2.40.0