From a79fcbf38c25ebb4e89ff77c5bdcc66d30ba89a5 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 6 Aug 2010 10:02:02 -0400 Subject: [PATCH] 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. --HG-- branch : 1.7 --- Makefile.in | 2 +- auth/passwd.c | 32 +++++++++++++++++++++++++------- auth/secureware.c | 26 ++++++++++++++++++++++---- auth/sudo_auth.c | 4 ++-- auth/sudo_auth.h | 2 ++ configure | 4 ++-- configure.in | 6 +++--- pwutil.c | 24 ++---------------------- 8 files changed, 59 insertions(+), 41 deletions(-) diff --git a/Makefile.in b/Makefile.in index 425bbdfec..dbfb1b165 100644 --- a/Makefile.in +++ b/Makefile.in @@ -136,7 +136,7 @@ COMMON_OBJS = alias.o alloc.o defaults.o error.o gram.o \ term.o zero_bytes.o @COMMON_OBJS@ SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o boottime.o check.o env.o \ - exec.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ + exec.o gettime.o goodpath.o fileops.o find_path.o \ interfaces.o lbuf.o logging.o parse.o parse_args.o set_perms.o \ sudo.o sudo_edit.o sudo_nss.o tgetpass.o diff --git a/auth/passwd.c b/auth/passwd.c index 4f9efb8a2..c644ec222 100644 --- a/auth/passwd.c +++ b/auth/passwd.c @@ -59,6 +59,9 @@ passwd_init(pw, promptp, 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); } @@ -69,14 +72,15 @@ passwd_verify(pw, pass, auth) 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 */ @@ -86,7 +90,7 @@ passwd_verify(pw, pass, 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'; /* @@ -94,12 +98,26 @@ passwd_verify(pw, pass, 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/auth/secureware.c b/auth/secureware.c index e7148d3f7..5076856dd 100644 --- a/auth/secureware.c +++ b/auth/secureware.c @@ -64,6 +64,9 @@ secureware_init(pw, promptp, auth) if (crypt_type == INT_MAX) return(AUTH_FAILURE); /* no shadow */ #endif + sudo_setspent(); + auth->data = sudo_getepw(pw); + sudo_endspent(); return(AUTH_SUCCESS); } @@ -73,25 +76,40 @@ secureware_verify(pw, pass, auth) 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/auth/sudo_auth.c b/auth/sudo_auth.c index f17ae8d0f..a269d0c81 100644 --- a/auth/sudo_auth.c +++ b/auth/sudo_auth.c @@ -53,10 +53,10 @@ sudo_auth auth_switch[] = { AUTH_STANDALONE #else # ifndef WITHOUT_PASSWD - AUTH_ENTRY(0, "passwd", passwd_init, NULL, passwd_verify, NULL) + AUTH_ENTRY(0, "passwd", passwd_init, NULL, passwd_verify, passwd_cleanup) # endif # if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD) - AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL) + AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, secureware_cleanup) # endif # ifdef HAVE_AFS AUTH_ENTRY(0, "afs", NULL, NULL, afs_verify, NULL) diff --git a/auth/sudo_auth.h b/auth/sudo_auth.h index a4efe1412..50249552b 100644 --- a/auth/sudo_auth.h +++ b/auth/sudo_auth.h @@ -64,8 +64,10 @@ int bsdauth_cleanup __P((struct passwd *pw, sudo_auth *auth)); /* Prototypes for normal methods */ int passwd_init __P((struct passwd *pw, char **prompt, sudo_auth *auth)); int passwd_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); +int passwd_cleanup __P((struct passwd *pw, sudo_auth *auth)); int secureware_init __P((struct passwd *pw, char **prompt, sudo_auth *auth)); int secureware_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); +int secureware_cleanup __P((struct passwd *pw, sudo_auth *auth)); int rfc1938_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth)); int rfc1938_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); int afs_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); diff --git a/configure b/configure index a4de2e7d4..960060880 100755 --- a/configure +++ b/configure @@ -17574,7 +17574,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 : @@ -18399,7 +18399,7 @@ fi case "$with_passwd" in yes|maybe) - AUTH_OBJS="$AUTH_OBJS passwd.o" + AUTH_OBJS="$AUTH_OBJS getspwuid.o passwd.o" ;; *) $as_echo "#define WITHOUT_PASSWD 1" >>confdefs.h diff --git a/configure.in b/configure.in index fce5fbd0c..4dfdf37f4 100644 --- a/configure.in +++ b/configure.in @@ -2526,7 +2526,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 @@ -2720,11 +2720,11 @@ if test "${with_iologdir-yes}" != "no"; then fi 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.o" + AUTH_OBJS="$AUTH_OBJS getspwuid.o passwd.o" ;; *) AC_DEFINE(WITHOUT_PASSWD) diff --git a/pwutil.c b/pwutil.c index fdf301f7d..b9929ee1c 100644 --- a/pwutil.c +++ b/pwutil.c @@ -214,17 +214,9 @@ pw_delref_item(v) 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 @@ -244,7 +236,6 @@ sudo_getpwuid(uid) { struct cache_item key, *item; struct rbnode *node; - char *cp; key.k.uid = uid; if ((node = rbfind(pwcache_byuid, &key)) != NULL) { @@ -259,10 +250,6 @@ sudo_getpwuid(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); @@ -293,7 +280,6 @@ sudo_getpwnam(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) { @@ -308,10 +294,6 @@ sudo_getpwnam(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 { @@ -394,7 +376,6 @@ void sudo_setpwent() { setpwent(); - sudo_setspent(); if (pwcache_byuid == NULL) pwcache_byuid = rbcreate(cmp_pwuid); if (pwcache_byname == NULL) @@ -418,7 +399,6 @@ void sudo_endpwent() { endpwent(); - sudo_endspent(); sudo_freepwcache(); } -- 2.50.1