From: Todd C. Miller Date: Fri, 6 Aug 2010 17:55:33 +0000 (-0400) Subject: No need to look up shadow password unless we are doing password-style X-Git-Tag: SUDO_1_8_0~291 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96cb890d53bef4b1e989e11f51a766b06b0f257b;p=sudo No need to look up shadow password unless we are doing password-style authentication. This moves the shadow password lookup to the auth functions that need it. --- diff --git a/configure b/configure index 5f53c2c69..c7f8f559f 100755 --- a/configure +++ b/configure @@ -17457,7 +17457,7 @@ fi fi if test ${with_passwd-'no'} != "no"; then - if test -z "$LIB_CRYPT" -a "$with_passwd" != "no"; then + if test -z "$LIB_CRYPT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5 $as_echo_n "checking for library containing crypt... " >&6; } if test "${ac_cv_search_crypt+set}" = set; then : @@ -18207,7 +18207,7 @@ $as_echo "$io_logdir" >&6; } case "$with_passwd" in yes|maybe) - AUTH_OBJS="$AUTH_OBJS passwd.lo" + AUTH_OBJS="$AUTH_OBJS getspwuid.lo passwd.lo" ;; *) $as_echo "#define WITHOUT_PASSWD 1" >>confdefs.h @@ -18218,7 +18218,7 @@ yes|maybe) ;; esac AUTH_OBJS=${AUTH_OBJS# } -_AUTH=`echo "$AUTH_OBJS" | sed 's/\.lo//g'` +_AUTH=`echo "$AUTH_OBJS" | sed -e 's/\.lo//g' -e 's/getspwuid *//'` { $as_echo "$as_me:${as_lineno-$LINENO}: using the following authentication methods: $_AUTH" >&5 $as_echo "$as_me: using the following authentication methods: $_AUTH" >&6;} diff --git a/configure.in b/configure.in index 79eba987e..07981a050 100644 --- a/configure.in +++ b/configure.in @@ -2530,7 +2530,7 @@ if test ${with_passwd-'no'} != "no"; then dnl dnl if crypt(3) not in libc, look elsewhere dnl - if test -z "$LIB_CRYPT" -a "$with_passwd" != "no"; then + if test -z "$LIB_CRYPT"; then AC_SEARCH_LIBS([crypt], [crypt crypt_d ufc], [test -n "$ac_lib" && SUDO_LIBS="${SUDO_LIBS} $ac_res"]) fi @@ -2692,11 +2692,11 @@ SUDO_TIMEDIR SUDO_IO_LOGDIR dnl -dnl Use passwd (and secureware) auth modules? +dnl Use passwd auth module? dnl case "$with_passwd" in yes|maybe) - AUTH_OBJS="$AUTH_OBJS passwd.lo" + AUTH_OBJS="$AUTH_OBJS getspwuid.lo passwd.lo" ;; *) AC_DEFINE(WITHOUT_PASSWD) @@ -2706,7 +2706,7 @@ yes|maybe) ;; esac AUTH_OBJS=${AUTH_OBJS# } -_AUTH=`echo "$AUTH_OBJS" | sed 's/\.lo//g'` +_AUTH=`echo "$AUTH_OBJS" | sed -e 's/\.lo//g' -e 's/getspwuid *//'` AC_MSG_NOTICE([using the following authentication methods: $_AUTH]) dnl diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index 95cfe0d2d..6110a8ecd 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -104,8 +104,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@ LIBSUDOERS_OBJS = alias.lo audit.lo defaults.lo gram.lo match.lo pwutil.lo \ timestr.lo toke.lo redblack.lo @NONUNIX_GROUPS_IMPL@ -SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo \ - plugin_error.lo env.lo getspwuid.lo \ +SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo plugin_error.lo env.lo \ goodpath.lo group_plugin.lo find_path.lo interfaces.lo \ logging.lo parse.lo set_perms.lo sudoers.lo sudo_nss.lo \ iolog.lo @SUDOERS_OBJS@ diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c index 397d38a2c..eaf1f5377 100644 --- a/plugins/sudoers/auth/passwd.c +++ b/plugins/sudoers/auth/passwd.c @@ -55,6 +55,9 @@ passwd_init(struct passwd *pw, char **promptp, sudo_auth *auth) if (skeyaccess(pw, user_tty, NULL, NULL) == 0) return(AUTH_FAILURE); #endif + sudo_setspent(); + auth->data = sudo_getepw(pw); + sudo_endspent(); return(AUTH_SUCCESS); } @@ -62,14 +65,15 @@ int passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth) { char sav, *epass; + char *pw_epasswd = auth->data; size_t pw_len; int error; - pw_len = strlen(pw->pw_passwd); + pw_len = strlen(pw_epasswd); #ifdef HAVE_GETAUTHUID /* Ultrix shadow passwords may use crypt16() */ - error = strcmp(pw->pw_passwd, (char *) crypt16(pass, pw->pw_passwd)); + error = strcmp(pw_epasswd, (char *) crypt16(pass, pw_epasswd)); if (!error) return(AUTH_SUCCESS); #endif /* HAVE_GETAUTHUID */ @@ -79,7 +83,7 @@ passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth) * If this turns out not to be safe we will have to use OS #ifdef's (sigh). */ sav = pass[8]; - if (pw_len == DESLEN || HAS_AGEINFO(pw->pw_passwd, pw_len)) + if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len)) pass[8] = '\0'; /* @@ -87,12 +91,26 @@ passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth) * HP-UX may add aging info (separated by a ',') at the end so * only compare the first DESLEN characters in that case. */ - epass = (char *) crypt(pass, pw->pw_passwd); + epass = (char *) crypt(pass, pw_epasswd); pass[8] = sav; - if (HAS_AGEINFO(pw->pw_passwd, pw_len) && strlen(epass) == DESLEN) - error = strncmp(pw->pw_passwd, epass, DESLEN); + if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN) + error = strncmp(pw_epasswd, epass, DESLEN); else - error = strcmp(pw->pw_passwd, epass); + error = strcmp(pw_epasswd, epass); return(error ? AUTH_FAILURE : AUTH_SUCCESS); } + +int +passwd_cleanup(pw, auth) + struct passwd *pw; + sudo_auth *auth; +{ + char *pw_epasswd = auth->data; + + if (pw_epasswd != NULL) { + zero_bytes(pw_epasswd, strlen(pw_epasswd)); + efree(pw_epasswd); + } + return(AUTH_SUCCESS); +} diff --git a/plugins/sudoers/auth/secureware.c b/plugins/sudoers/auth/secureware.c index 3f518b89c..6ddfae70d 100644 --- a/plugins/sudoers/auth/secureware.c +++ b/plugins/sudoers/auth/secureware.c @@ -61,31 +61,49 @@ secureware_init(struct passwd *pw, char **promptp, sudo_auth *auth) if (crypt_type == INT_MAX) return(AUTH_FAILURE); /* no shadow */ #endif + sudo_setspent(); + auth->data = sudo_getepw(pw); + sudo_endspent(); return(AUTH_SUCCESS); } int secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth) { + char *pw_epasswd = auth->data; #ifdef __alpha extern int crypt_type; # ifdef HAVE_DISPCRYPT - if (strcmp(user_passwd, dispcrypt(pass, user_passwd, crypt_type)) == 0) + if (strcmp(pw_epasswd, dispcrypt(pass, pw_epasswd, crypt_type)) == 0) return(AUTH_SUCCESS); # else if (crypt_type == AUTH_CRYPT_BIGCRYPT) { - if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0) + if (strcmp(pw_epasswd, bigcrypt(pass, pw_epasswd)) == 0) return(AUTH_SUCCESS); } else if (crypt_type == AUTH_CRYPT_CRYPT16) { - if (strcmp(user_passwd, crypt(pass, user_passwd)) == 0) + if (strcmp(pw_epasswd, crypt(pass, pw_epasswd)) == 0) return(AUTH_SUCCESS); } # endif /* HAVE_DISPCRYPT */ #elif defined(HAVE_BIGCRYPT) - if (strcmp(user_passwd, bigcrypt(pass, user_passwd)) == 0) + if (strcmp(pw_epasswd, bigcrypt(pass, pw_epasswd)) == 0) return(AUTH_SUCCESS); #endif /* __alpha */ return(AUTH_FAILURE); } + +int +secureware_cleanup(pw, auth) + struct passwd *pw; + sudo_auth *auth; +{ + char *pw_epasswd = auth->data; + + if (pw_epasswd != NULL) { + zero_bytes(pw_epasswd, strlen(pw_epasswd)); + efree(pw_epasswd); + } + return(AUTH_SUCCESS); +} diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index 1d0b8cf30..99cccecfd 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -71,10 +71,10 @@ static sudo_auth auth_switch[] = { /* Non-standalone entries */ #ifndef WITHOUT_PASSWD - AUTH_ENTRY("passwd", 0, passwd_init, NULL, passwd_verify, NULL, NULL, NULL) + AUTH_ENTRY("passwd", 0, passwd_init, NULL, passwd_verify, passwd_cleanup, NULL, NULL) #endif #if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD) - AUTH_ENTRY("secureware", 0, secureware_init, NULL, secureware_verify, NULL, NULL, NULL) + AUTH_ENTRY("secureware", 0, secureware_init, NULL, secureware_verify, secureware_cleanup, NULL, NULL) #endif #ifdef HAVE_AFS AUTH_ENTRY("afs", 0, NULL, NULL, afs_verify, NULL, NULL, NULL) diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h index 565864a58..91124bfea 100644 --- a/plugins/sudoers/auth/sudo_auth.h +++ b/plugins/sudoers/auth/sudo_auth.h @@ -75,8 +75,10 @@ int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth); /* Prototypes for normal methods */ int passwd_init(struct passwd *pw, char **prompt, sudo_auth *auth); int passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth); +int passwd_cleanup(struct passwd *pw, sudo_auth *auth); int secureware_init(struct passwd *pw, char **prompt, sudo_auth *auth); int secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth); +int secureware_cleanup(struct passwd *pw, sudo_auth *auth); int rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth); int rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth); int afs_verify(struct passwd *pw, char *pass, sudo_auth *auth); diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index 4f25cdb29..453223281 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -206,17 +206,9 @@ static void pw_delref_item(void *v) { struct cache_item *item = v; - struct passwd *pw = item->d.pw; - - if (--item->refcnt == 0) { - if (pw != NULL && pw->pw_passwd != NULL) { - zero_bytes(pw->pw_passwd, strlen(pw->pw_passwd)); - if ((char *)pw->pw_passwd < (char *)pw || - (char *)pw->pw_passwd > (char *)pw->pw_gecos) - efree(pw->pw_passwd); /* free if separate allocation */ - } + + if (--item->refcnt == 0) efree(item); - } } void @@ -234,7 +226,6 @@ sudo_getpwuid(uid_t uid) { struct cache_item key, *item; struct rbnode *node; - char *cp; key.k.uid = uid; if ((node = rbfind(pwcache_byuid, &key)) != NULL) { @@ -249,10 +240,6 @@ sudo_getpwuid(uid_t uid) #endif if ((key.d.pw = getpwuid(uid)) != NULL) { item = make_pwitem(key.d.pw, NULL); - cp = sudo_getepw(item->d.pw); /* get shadow password */ - if (item->d.pw->pw_passwd != NULL) - zero_bytes(item->d.pw->pw_passwd, strlen(item->d.pw->pw_passwd)); - item->d.pw->pw_passwd = cp; if (rbinsert(pwcache_byuid, item) != NULL) errorx(1, "unable to cache uid %lu (%s), already exists", uid, item->d.pw->pw_name); @@ -282,7 +269,6 @@ sudo_getpwnam(const char *name) struct cache_item key, *item; struct rbnode *node; size_t len; - char *cp; key.k.name = (char *) name; if ((node = rbfind(pwcache_byname, &key)) != NULL) { @@ -297,10 +283,6 @@ sudo_getpwnam(const char *name) #endif if ((key.d.pw = getpwnam(name)) != NULL) { item = make_pwitem(key.d.pw, name); - cp = sudo_getepw(key.d.pw); /* get shadow password */ - if (key.d.pw->pw_passwd != NULL) - zero_bytes(key.d.pw->pw_passwd, strlen(key.d.pw->pw_passwd)); - key.d.pw->pw_passwd = cp; if (rbinsert(pwcache_byname, item) != NULL) errorx(1, "unable to cache user %s, already exists", name); } else { @@ -381,7 +363,6 @@ void sudo_setpwent(void) { setpwent(); - sudo_setspent(); if (pwcache_byuid == NULL) pwcache_byuid = rbcreate(cmp_pwuid); if (pwcache_byname == NULL) @@ -405,7 +386,6 @@ void sudo_endpwent(void) { endpwent(); - sudo_endspent(); sudo_freepwcache(); }