cvs commit: patches/Linux-PAM Linux-PAM-0.77-security-4.patch Linux-PAM-0.77-security-3.patch

jim at linuxfromscratch.org jim at linuxfromscratch.org
Thu Jun 10 22:39:22 PDT 2004


jim         04/06/10 23:39:22

  Added:       Linux-PAM Linux-PAM-0.77-security-4.patch
  Removed:     Linux-PAM Linux-PAM-0.77-security-3.patch
  Log:
  Updated: Linux-PAM-0.77-security-4.patch
  
  Revision  Changes    Path
  1.1                  patches/Linux-PAM/Linux-PAM-0.77-security-4.patch
  
  Index: Linux-PAM-0.77-security-4.patch
  ===================================================================
  Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
  Date: 2004-06-09
  Initial Package Version: 0.77
  Origin: PAM CVS
  Upstream Status: Already Applied 
  Description: Two bug fixes in one: don't trust getlogin() and sanely lower the
  	     time the password databases are locked in pam_unix.
  
  	     Go to the url below for more details
  	     http://www.securiteam.com/unixfocus/5UP0J1PAAQ.html
  
  
   
  diff -Naur Linux-PAM-0.77.orig/modules/pam_unix/Makefile Linux-PAM-0.77/modules/pam_unix/Makefile
  --- Linux-PAM-0.77.orig/modules/pam_unix/Makefile	2001-02-11 06:33:53.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_unix/Makefile	2004-06-09 18:28:23.922188125 +0000
  @@ -41,8 +41,10 @@
   
   ########################################################################
   
  -CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS)
  -LDLIBS = $(EXTRALS)
  +CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS) \
  +	 -I../pammodutil/include
  +
  +LDLIBS = $(EXTRALS) -L../pammodutil -lpammodutil
   
   ifdef USE_CRACKLIB
   CRACKLIB = -lcrack
  diff -Naur Linux-PAM-0.77.orig/modules/pam_unix/pam_unix_passwd.c Linux-PAM-0.77/modules/pam_unix/pam_unix_passwd.c
  --- Linux-PAM-0.77.orig/modules/pam_unix/pam_unix_passwd.c	2002-07-09 04:44:18.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_unix/pam_unix_passwd.c	2004-06-09 18:28:24.058164102 +0000
  @@ -88,7 +88,7 @@
    */
   
   #ifdef NEED_LCKPWDF
  -#include "./lckpwdf.-c"
  +# include "./lckpwdf.-c"
   #endif
   
   extern char *bigcrypt(const char *key, const char *salt);
  @@ -471,10 +471,7 @@
   
   	D(("called"));
   
  -	setpwent();
   	pwd = getpwnam(forwho);
  -	endpwent();
  -
   	if (pwd == NULL)
   		return PAM_AUTHTOK_ERR;
   
  @@ -544,6 +541,24 @@
   	if (save_old_password(forwho, fromwhat, remember)) {
   		return PAM_AUTHTOK_ERR;
   	}
  +
  +#ifdef USE_LCKPWDF
  +	/*
  +	 * These values for the number of attempts and the sleep time
  +	 * are, of course, completely arbitrary.
  +	 *
  +	 * My reading of the PAM docs is that, once pam_chauthtok()
  +	 * has been called with PAM_UPDATE_AUTHTOK, we are obliged to
  +	 * take any reasonable steps to make sure the token is
  +	 * updated; so retrying for 1/10 sec. isn't overdoing it.
  +	 */
  +
  +	retval = lckpwdf();
  +	if (retval != 0) {
  +	    return PAM_AUTHTOK_LOCK_BUSY;
  +	}
  +#endif /* def USE_LCKPWDF */
  +	
   	if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) {
   		retval = _update_shadow(forwho, towhat);
   		if (retval == PAM_SUCCESS)
  @@ -552,6 +567,10 @@
   		retval = _update_passwd(pamh, forwho, towhat);
   	}
   
  +#ifdef USE_LCKPWDF
  +	ulckpwdf();
  +#endif /* def USE_LCKPWDF */
  +
   	return retval;
   }
   
  @@ -563,9 +582,7 @@
   	int retval = PAM_SUCCESS;
   
   	/* UNIX passwords area */
  -	setpwent();
   	pwd = getpwnam(user);	/* Get password file entry... */
  -	endpwent();
   	if (pwd == NULL)
   		return PAM_AUTHINFO_UNAVAIL;	/* We don't need to do the rest... */
   
  @@ -679,7 +696,7 @@
   				int argc, const char **argv)
   {
   	unsigned int ctrl, lctrl;
  -	int retval, i;
  +	int retval;
   	int remember = -1;
   
   	/* <DO NOT free() THESE> */
  @@ -689,33 +706,12 @@
   
   	D(("called."));
   
  -#ifdef USE_LCKPWDF
  -	/* our current locking system requires that we lock the
  -	   entire password database.  This avoids both livelock
  -	   and deadlock. */
  -	/* These values for the number of attempts and the sleep time
  -	   are, of course, completely arbitrary.
  -	   My reading of the PAM docs is that, once pam_chauthtok() has been
  -	   called with PAM_UPDATE_AUTHTOK, we are obliged to take any
  -	   reasonable steps to make sure the token is updated; so retrying
  -	   for 1/10 sec. isn't overdoing it.
  -	   The other possibility is to call lckpwdf() on the first
  -	   pam_chauthtok() pass, and hold the lock until released in the
  -	   second pass--but is this guaranteed to work? -SRL */
  -	i=0;
  -	while((retval = lckpwdf()) != 0 && i < 100) {
  -		usleep(1000);
  -	}
  -	if(retval != 0) {
  -		return PAM_AUTHTOK_LOCK_BUSY;
  -	}
  -#endif
   	ctrl = _set_ctrl(pamh, flags, &remember, argc, argv);
   
   	/*
   	 * First get the name of a user
   	 */
  -	retval = pam_get_user(pamh, &user, "Username: ");
  +	retval = pam_get_user(pamh, &user, NULL);
   	if (retval == PAM_SUCCESS) {
   		/*
   		 * Various libraries at various times have had bugs related to
  @@ -725,9 +721,6 @@
   		 */
   		if (user == NULL || !isalnum(*user)) {
   			_log_err(LOG_ERR, pamh, "bad username [%s]", user);
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return PAM_USER_UNKNOWN;
   		}
   		if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
  @@ -737,9 +730,6 @@
   		if (on(UNIX_DEBUG, ctrl))
   			_log_err(LOG_DEBUG, pamh,
   			         "password - could not identify user");
  -#ifdef USE_LCKPWDF
  -		ulckpwdf();
  -#endif
   		return retval;
   	}
   
  @@ -761,9 +751,6 @@
   		D(("prelim check"));
   
   		if (_unix_blankpasswd(ctrl, user)) {
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return PAM_SUCCESS;
   		} else if (off(UNIX__IAMROOT, ctrl)) {
   
  @@ -773,9 +760,6 @@
   			if (Announce == NULL) {
   				_log_err(LOG_CRIT, pamh,
   				         "password - out of memory");
  -#ifdef USE_LCKPWDF
  -				ulckpwdf();
  -#endif
   				return PAM_BUF_ERR;
   			}
   			(void) strcpy(Announce, greeting);
  @@ -795,9 +779,6 @@
   			if (retval != PAM_SUCCESS) {
   				_log_err(LOG_NOTICE, pamh
   				 ,"password - (old) token not obtained");
  -#ifdef USE_LCKPWDF
  -				ulckpwdf();
  -#endif
   				return retval;
   			}
   			/* verify that this is the password for this user */
  @@ -812,9 +793,6 @@
   		if (retval != PAM_SUCCESS) {
   			D(("Authentication failed"));
   			pass_old = NULL;
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return retval;
   		}
   		retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
  @@ -867,17 +845,11 @@
   
   		if (retval != PAM_SUCCESS) {
   			_log_err(LOG_NOTICE, pamh, "user not authenticated");
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return retval;
   		}
   		retval = _unix_verify_shadow(user, ctrl);
   		if (retval != PAM_SUCCESS) {
   			_log_err(LOG_NOTICE, pamh, "user not authenticated 2");
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return retval;
   		}
   		D(("get new password now"));
  @@ -908,9 +880,6 @@
   						 ,"password - new password not obtained");
   				}
   				pass_old = NULL;	/* tidy up */
  -#ifdef USE_LCKPWDF
  -				ulckpwdf();
  -#endif
   				return retval;
   			}
   			D(("returned to _unix_chauthtok"));
  @@ -931,9 +900,6 @@
   			_log_err(LOG_NOTICE, pamh,
   			         "new password not acceptable");
   			pass_new = pass_old = NULL;	/* tidy up */
  -#ifdef USE_LCKPWDF
  -			ulckpwdf();
  -#endif
   			return retval;
   		}
   		/*
  @@ -974,9 +940,6 @@
   					_log_err(LOG_CRIT, pamh,
   					         "out of memory for password");
   					pass_new = pass_old = NULL;	/* tidy up */
  -#ifdef USE_LCKPWDF
  -					ulckpwdf();
  -#endif
   					return PAM_BUF_ERR;
   				}
   				/* copy first 8 bytes of password */
  @@ -998,6 +961,7 @@
   
   		retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
   		                     remember);
  +
   		_pam_delete(tpass);
   		pass_old = pass_new = NULL;
   	} else {		/* something has broken with the module */
  @@ -1008,9 +972,6 @@
   
   	D(("retval was %d", retval));
   
  -#ifdef USE_LCKPWDF
  -	ulckpwdf();
  -#endif
   	return retval;
   }
   
  diff -Naur Linux-PAM-0.77.orig/modules/pam_unix/pam_unix_sess.c Linux-PAM-0.77/modules/pam_unix/pam_unix_sess.c
  --- Linux-PAM-0.77.orig/modules/pam_unix/pam_unix_sess.c	2000-12-20 05:15:05.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_unix/pam_unix_sess.c	2004-06-09 18:28:24.064163042 +0000
  @@ -53,6 +53,7 @@
   
   #include <security/_pam_macros.h>
   #include <security/pam_modules.h>
  +#include <security/_pam_modutil.h>
   
   #ifndef LINUX_PAM
   #include <security/pam_appl.h>
  @@ -71,6 +72,7 @@
   	char *user_name, *service;
   	unsigned int ctrl;
   	int retval;
  +    const char *login_name;
   
   	D(("called."));
   
  @@ -89,9 +91,12 @@
   		         "open_session - error recovering service");
   		return PAM_SESSION_ERR;
   	}
  -	_log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)"
  -		 ,user_name
  -		 ,PAM_getlogin() == NULL ? "" : PAM_getlogin(), getuid());
  +	login_name = _pammodutil_getlogin(pamh);
  +	if (login_name == NULL) {
  +	    login_name = "";
  +	}
  +	_log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)",
  +		 user_name, login_name, getuid());
   
   	return PAM_SUCCESS;
   }
  diff -Naur Linux-PAM-0.77.orig/modules/pam_unix/support.c Linux-PAM-0.77/modules/pam_unix/support.c
  --- Linux-PAM-0.77.orig/modules/pam_unix/support.c	2002-09-23 17:33:22.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_unix/support.c	2004-06-09 18:28:24.096157389 +0000
  @@ -20,6 +20,7 @@
   
   #include <security/_pam_macros.h>
   #include <security/pam_modules.h>
  +#include <security/_pam_modutil.h>
   
   #include "md5.h"
   #include "support.h"
  @@ -107,36 +108,6 @@
   	return retval;
   }
   
  -  /*
  -   * Beacause getlogin() is braindead and sometimes it just
  -   * doesn't work, we reimplement it here.
  -   */
  -char *PAM_getlogin(void)
  -{
  -	struct utmp *ut, line;
  -	char *curr_tty, *retval;
  -	static char curr_user[sizeof(ut->ut_user) + 4];
  -
  -	retval = NULL;
  -
  -	curr_tty = ttyname(0);
  -	if (curr_tty != NULL) {
  -		D(("PAM_getlogin ttyname: %s", curr_tty));
  -		curr_tty += 5;
  -		setutent();
  -		strncpy(line.ut_line, curr_tty, sizeof(line.ut_line));
  -		if ((ut = getutline(&line)) != NULL) {
  -			strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
  -			curr_user[sizeof(curr_user) - 1] = '\0';
  -			retval = curr_user;
  -		}
  -		endutent();
  -	}
  -	D(("PAM_getlogin retval: %s", retval));
  -
  -	return retval;
  -}
  -
   /*
    * set the control flags for the UNIX module.
    */
  @@ -668,10 +639,17 @@
   
   			if (new != NULL) {
   
  -				new->user = x_strdup(name ? name : "");
  +			    const char *login_name;
  +
  +			    login_name = _pammodutil_getlogin(pamh);
  +			    if (login_name == NULL) {
  +				login_name = "";
  +			    }
  +
  +			        new->user = x_strdup(name ? name : "");
   				new->uid = getuid();
   				new->euid = geteuid();
  -				new->name = x_strdup(PAM_getlogin()? PAM_getlogin() : "");
  +				new->name = x_strdup(login_name);
   
   				/* any previous failures for this user ? */
   				pam_get_data(pamh, data_name, (const void **) &old);
  diff -Naur Linux-PAM-0.77.orig/modules/pam_unix/support.h Linux-PAM-0.77/modules/pam_unix/support.h
  --- Linux-PAM-0.77.orig/modules/pam_unix/support.h	2002-07-11 05:43:51.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_unix/support.h	2004-06-09 18:28:24.101156506 +0000
  @@ -125,7 +125,6 @@
   	_pam_drop(xx);		\
   }
   
  -extern char *PAM_getlogin(void);
   extern void _log_err(int err, pam_handle_t *pamh, const char *format,...);
   extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl
   		       ,int type, const char *text);
  diff -Naur Linux-PAM-0.77.orig/modules/pam_wheel/pam_wheel.c Linux-PAM-0.77/modules/pam_wheel/pam_wheel.c
  --- Linux-PAM-0.77.orig/modules/pam_wheel/pam_wheel.c	2002-07-13 05:48:19.000000000 +0000
  +++ Linux-PAM-0.77/modules/pam_wheel/pam_wheel.c	2004-06-09 18:28:24.105155800 +0000
  @@ -43,6 +43,7 @@
   #define PAM_SM_ACCOUNT
   
   #include <security/pam_modules.h>
  +#include <security/_pam_modutil.h>
   
   /* some syslogging */
   
  @@ -110,7 +111,7 @@
   			 const char *use_group)
   {
       const char *username = NULL;
  -    char *fromsu;
  +    const char *fromsu;
       struct passwd *pwd, *tpwd;
       struct group *grp;
       int retval = PAM_AUTH_ERR;
  @@ -142,7 +143,7 @@
   	}
   	fromsu = tpwd->pw_name;
       } else {
  -	fromsu = getlogin();
  +	fromsu = _pammodutil_getlogin(pamh);
   	if (fromsu) {
   	    tpwd = getpwnam(fromsu);
   	}
  diff -Naur Linux-PAM-0.77.orig/modules/pammodutil/Makefile Linux-PAM-0.77/modules/pammodutil/Makefile
  --- Linux-PAM-0.77.orig/modules/pammodutil/Makefile	2001-12-09 22:15:12.000000000 +0000
  +++ Linux-PAM-0.77/modules/pammodutil/Makefile	2004-06-09 18:28:24.107155446 +0000
  @@ -18,7 +18,8 @@
     -DLIBPAM_VERSION_MINOR=$(MINOR_REL)
   
   # all the object files we care about
  -LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o
  +LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o \
  +	modutil_getlogin.o
   
   # static library name
   LIBSTATIC = $(LIBNAME).a
  diff -Naur Linux-PAM-0.77.orig/modules/pammodutil/include/security/_pam_modutil.h Linux-PAM-0.77/modules/pammodutil/include/security/_pam_modutil.h
  --- Linux-PAM-0.77.orig/modules/pammodutil/include/security/_pam_modutil.h	2001-12-09 22:15:12.000000000 +0000
  +++ Linux-PAM-0.77/modules/pammodutil/include/security/_pam_modutil.h	2004-06-09 18:28:24.110154916 +0000
  @@ -15,7 +15,7 @@
    * On systems that simply can't support thread safe programming, these
    * functions don't support it either - sorry.
    *
  - * Copyright (c) 2001 Andrew Morgan <morgan at kernel.org>
  + * Copyright (c) 2001-2002 Andrew Morgan <morgan at kernel.org>
    */
   
   #include <pwd.h>
  @@ -30,4 +30,6 @@
   extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data,
   				int error_status);
   
  +extern const char *_pammodutil_getlogin(pam_handle_t *pamh);
  +
   #endif /* _PAM_MODUTIL_H */
  diff -Naur Linux-PAM-0.77.orig/modules/pammodutil/modutil_getlogin.c Linux-PAM-0.77/modules/pammodutil/modutil_getlogin.c
  --- Linux-PAM-0.77.orig/modules/pammodutil/modutil_getlogin.c	1970-01-01 00:00:00.000000000 +0000
  +++ Linux-PAM-0.77/modules/pammodutil/modutil_getlogin.c	2004-06-09 18:32:32.659204375 +0000
  @@ -0,0 +1,71 @@
  +/*
  + * $Id: Linux-PAM-0.77-security-4.patch,v 1.1 2004/06/11 05:39:22 jim Exp $
  + *
  + * A central point for invoking getlogin(). Hopefully, this is a
  + * little harder to spoof than all the other versions that are out
  + * there.
  + */
  +
  +#include <stdlib.h>
  +#include <unistd.h>
  +#include <utmp.h>
  +
  +#include "pammodutil.h"
  +
  +#define _PAMMODUTIL_GETLOGIN "_pammodutil_getlogin"
  +
  +const char *_pammodutil_getlogin(pam_handle_t *pamh)
  +{
  +    int status;
  +    const char *logname, *curr_tty;
  +    char *curr_user;
  +    struct utmp *ut, line;
  +
  +    status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN,
  +			  (const void **) &logname);
  +    if (status == PAM_SUCCESS) {
  +	return logname;
  +    }
  +
  +    status = pam_get_item(pamh, PAM_TTY, (const void **) &curr_tty);
  +    if ((status != PAM_SUCCESS) || (curr_tty == NULL)) {
  +	curr_tty = ttyname(0);
  +    }
  +
  +    if ((curr_tty == NULL) || memcmp(curr_tty, "/dev/", 5)) {
  +	return NULL;
  +    }
  +
  +    curr_tty += 5;  /* strlen("/dev/") */
  +    logname = NULL;
  +
  +    setutent();
  +    strncpy(line.ut_line, curr_tty, sizeof(line.ut_line));
  +
  +    if ((ut = getutline(&line)) == NULL) {
  +	goto clean_up_and_go_home;
  +    }
  +
  +    curr_user = calloc(sizeof(line.ut_user)+1, 1);
  +    if (curr_user == NULL) {
  +	goto clean_up_and_go_home;
  +    }
  +
  +    strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
  +    curr_user[sizeof(line.ut_user)] = '\0';
  +
  +    status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, logname,
  +			  _pammodutil_cleanup);
  +    if (status != PAM_SUCCESS) {
  +	free(curr_user);
  +	goto clean_up_and_go_home;
  +    }
  +
  +    logname = curr_user;
  +
  +clean_up_and_go_home:
  +
  +    endutent();
  +
  +    return logname;
  +}
  
  
  



More information about the patches mailing list