From 6d6eebcafec81d696b621d8453b13d55a1f9be1d Mon Sep 17 00:00:00 2001 From: Sebastien Tricaud Date: Tue, 16 Nov 2004 14:27:40 +0000 Subject: Applied debian patches --- CHANGELOG | 14 ++++ modules/pam_access/access.conf | 7 ++ modules/pam_access/pam_access.c | 13 ++-- modules/pam_env/pam_env.conf-example | 4 ++ modules/pam_filter/pam_filter.c | 18 ++--- modules/pam_mail/pam_mail.c | 2 +- modules/pam_mkhomedir/pam_mkhomedir.c | 125 +++++++++++++++++++++++++++++++++- modules/pam_rhosts/pam_rhosts_auth.c | 12 ++++ modules/pam_securetty/pam_securetty.c | 4 +- modules/pam_unix/pam_unix_passwd.c | 2 +- modules/pam_unix/unix_chkpwd.c | 13 ++-- 11 files changed, 188 insertions(+), 26 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e72e4db9..2b00ebf6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,6 +63,20 @@ BerliOS Bugs are marked with (BerliOS #XXXX). 0.78: please submit patches for this section with actual code/doc patches! +* pam_unix: remove the use of openlog (from debian - toady) +* pam_unix: NIS cleanup (patch from Philippe Troin) +* pam_access: you can now authenticate an explicit user on an explicit + tty (from debian - toady) +* pam_limits, pam_rhosts, pam_unix: fixed hurd portability issues + (patch from Igor Khavkine) +* pam_env: added comments in the configuration file to avoid errors + (from debian - toady) +* pam_mail: check PAM_NO_ENV to know if we can delete the environment + variable (from debian - toady) +* pam_filter: s/termio/termios/g (from debian - toady) +* pam_mkhomedir: no maxpathlen required (from debian - toady) +* pam_limits: applied patch to allow explicit limits for root + and remove limits on su. (from debian - toady) * pam_unix: severe denial of service possible with this module since it locked too aggressively. Bug report and testing help from Sascha Loetz. (Bug 664290 - agmorgan) diff --git a/modules/pam_access/access.conf b/modules/pam_access/access.conf index dbaadf67..cec2be0c 100644 --- a/modules/pam_access/access.conf +++ b/modules/pam_access/access.conf @@ -40,8 +40,15 @@ # logged-in user. Both the user's primary group is matched, as well as # groups in which users are explicitly listed. # +# TTY NAMES: Must be in the form returned by ttyname(3) less the initial +# "/dev" (e.g. tty1 or vc/1) +# ############################################################################## # +# Disallow non-root logins on tty1 +# +#-:ALL EXCEPT root:tty1 +# # Disallow console logins to all but a few accounts. # #-:ALL EXCEPT wheel shutdown sync:LOCAL diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c index 42e03527..4f6cf574 100644 --- a/modules/pam_access/pam_access.c +++ b/modules/pam_access/pam_access.c @@ -194,10 +194,11 @@ login_access (pam_handle_t *pamh, struct login_info *item) line[end] = 0; /* strip trailing whitespace */ if (line[0] == 0) /* skip blank lines */ continue; + + /* Allow trailing: in last field fo froms */ if (!(perm = strtok(line, fs)) || !(users = strtok((char *) 0, fs)) - || !(froms = strtok((char *) 0, fs)) - || strtok((char *) 0, fs)) { + || !(froms = strtok((char *) 0, fs))) { _log_err("%s: line %d: bad field count", item->config_file, lineno); continue; @@ -438,10 +439,12 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc return PAM_ABORT; } } - if (strncmp("/dev/",from,5) == 0) { /* strip leading /dev/ */ - from += 5; - } + if (from[0] == '/') { /* full path */ + from++; + from = strchr(from, '/'); + from++; + } } if ((user_pw=_pammodutil_getpwnam(pamh, user))==NULL) return (PAM_USER_UNKNOWN); diff --git a/modules/pam_env/pam_env.conf-example b/modules/pam_env/pam_env.conf-example index c2c4333f..02116639 100644 --- a/modules/pam_env/pam_env.conf-example +++ b/modules/pam_env/pam_env.conf-example @@ -43,6 +43,10 @@ # be used in values using the @{string} syntax. Both the $ and @ # characters can be backslash escaped to be used as literal values # values can be delimited with "", escaped " not supported. +# Note that many environment variables that you would like to use +# may not be set by the time the module is called. +# For example, HOME is used below several times, but +# many PAM applications don't make it available by the time you need it. # # # First, some special variables diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c index d3462f40..328fec87 100644 --- a/modules/pam_filter/pam_filter.c +++ b/modules/pam_filter/pam_filter.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include @@ -287,7 +287,7 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl { int status=-1; char terminal[TERMINAL_LEN]; - struct termio stored_mode; /* initial terminal mode settings */ + struct termios stored_mode; /* initial terminal mode settings */ int fd[2], child=0, child2=0, aterminal; if (filtername == NULL || *filtername != '/') { @@ -314,15 +314,15 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl /* set terminal into raw mode.. remember old mode so that we can revert to it after the child has quit. */ - /* this is termio terminal handling... */ + /* this is termios terminal handling... */ - if (ioctl(STDIN_FILENO, TCGETA, (char *) &stored_mode ) < 0) { + if ( tcgetattr(STDIN_FILENO, &stored_mode) < 0 ) { /* in trouble, so close down */ close(fd[0]); _pam_log(LOG_CRIT, "couldn't copy terminal mode"); return PAM_ABORT; } else { - struct termio t_mode = stored_mode; + struct termios t_mode = stored_mode; t_mode.c_iflag = 0; /* no input control */ t_mode.c_oflag &= ~OPOST; /* no ouput post processing */ @@ -335,7 +335,7 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl t_mode.c_cc[VMIN] = 1; /* number of chars to satisfy a read */ t_mode.c_cc[VTIME] = 0; /* 0/10th second for chars */ - if (ioctl(STDIN_FILENO, TCSETA, (char *) &t_mode) < 0) { + if ( tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_mode) < 0 ) { close(fd[0]); _pam_log(LOG_WARNING, "couldn't put terminal in RAW mode"); return PAM_ABORT; @@ -365,7 +365,7 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl _pam_log(LOG_WARNING,"first fork failed"); if (aterminal) { - (void) ioctl(STDIN_FILENO, TCSETA, (char *) &stored_mode); + (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &stored_mode); } return PAM_AUTH_ERR; @@ -407,7 +407,7 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl /* initialize the child's terminal to be the way the parent's was before we set it into RAW mode */ - if (ioctl(fd[1], TCSETA, (char *) &stored_mode) < 0) { + if ( tcsetattr(fd[1], TCSANOW, &stored_mode) < 0 ) { _pam_log(LOG_WARNING,"cannot set slave terminal mode; %s" ,terminal); close(fd[1]); @@ -581,7 +581,7 @@ static int set_filter(pam_handle_t *pamh, int flags, int ctrl if (aterminal) { /* reset to initial terminal mode */ - (void) ioctl(STDIN_FILENO, TCSETA, (char *) &stored_mode); + (void) tcsetattr(STDIN_FILENO, TCSANOW, &stored_mode); } if (ctrl & FILTER_DEBUG) { diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c index 6cd173b4..2c4b641a 100644 --- a/modules/pam_mail/pam_mail.c +++ b/modules/pam_mail/pam_mail.c @@ -474,7 +474,7 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc, } /* Delete environment variable? */ - if (!est) + if ( ! est && ! (ctrl & PAM_NO_ENV) ) (void) pam_putenv(pamh, MAIL_ENV_NAME); _pam_overwrite(folder); /* clean up */ diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index 6814056f..f2f92974 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -221,7 +221,14 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, int DestFd; int Res; struct stat St; +#ifndef PATH_MAX + char *newsource = NULL; *newdest = NULL; + /* track length of buffers */ + int nslen = 0, ndlen = 0; + slen = strlen(source), dlen = strlen(dest); +#else char newsource[PATH_MAX], newdest[PATH_MAX]; +#endif /* Skip some files.. */ if (strcmp(Dir->d_name,".") == 0 || @@ -229,17 +236,56 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, continue; /* Determine what kind of file it is. */ +#ifndef PATH_MAX + if ( ( nslen <= 0 ) || ( ndlen <= 0) ) + return PAM_BUF_ERR; + + nslen = slen + strlen(Dir->d_name) + 2; + + if ( (newsource = malloc(nslen)) == NULL ) + return PAM_BUF_ERR; + + sprintf(newsource, "%s/%s", source, Dir->d_name); +#else snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name); +#endif + if (lstat(newsource,&St) != 0) +#ifndef PATH_MAX + { + free(newsource); + newsource = NULL; + continue; + } +#else continue; +#endif + /* We'll need the new file's name. */ +#ifndef PATH_MAX + ndlen = dlen + strlen(Dir->d_name)+2; + + if ( (newdest = (int *) malloc(ndlen)) == NULL ) { + free(newsource); + return PAM_BUF_ERR; + } + + sprintf(newdest, "%s/%s", dest, Dir->d_name); +#else snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name); +#endif /* If it's a directory, recurse. */ if (S_ISDIR(St.st_mode)) { int retval = create_homedir(pamh, ctrl, pwd, newsource, newdest); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + if (retval != PAM_SUCCESS) { closedir(D); return retval; @@ -250,21 +296,61 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, /* If it's a symlink, create a new link. */ if (S_ISLNK(St.st_mode)) { + int pointedlen = 0; +#ifndef PATH_MAX + char *pointed = NULL; + { + int size = 100; + + while (1) { + pointed = (char *) malloc(size); + if ( ! pointed ) { + free(newsource); + free(newdest); + return PAM_BUF_ERR; + } + pointedlen = readlink (newsource, pointed, size); + if ( pointedlen < 0 ) break; + if ( pointedlen < size ) break; + free (pointed); + size *= 2; + } + } + if ( pointedlen < 0 ) + free(pointed); + else + pointed[pointedlen] = 0; +#else char pointed[PATH_MAX]; memset(pointed, 0, sizeof(pointed)); - if(readlink(newsource, pointed, sizeof(pointed) - 1) != -1) - { + + pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); +#endif + + if ( pointedlen >= 0 ) { if(symlink(pointed, newdest) == 0) { if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0) { closedir(D); - _log_err(LOG_DEBUG, "unable to chang perms on link %s", + _log_err(LOG_DEBUG, "unable to change perms on link %s", newdest); +#ifndef PATH_MAX + free(pointed); + free(newsource); + free(newdest); +#endif return PAM_PERM_DENIED; } } +#ifndef PATH_MAX + free(pointed); +#endif } +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif continue; } @@ -272,6 +358,10 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, * the new device node, FIFO, or whatever it is. */ if (!S_ISREG(St.st_mode)) { +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif continue; } @@ -280,6 +370,12 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, { closedir(D); _log_err(LOG_DEBUG, "unable to open src file %s",newsource); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + return PAM_PERM_DENIED; } stat(newsource,&St); @@ -290,6 +386,11 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, close(SrcFd); closedir(D); _log_err(LOG_DEBUG, "unable to open dest file %s",newdest); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif return PAM_PERM_DENIED; } @@ -303,6 +404,12 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, close(DestFd); closedir(D); _log_err(LOG_DEBUG, "unable to chang perms on copy %s",newdest); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + return PAM_PERM_DENIED; } @@ -325,11 +432,23 @@ static int create_homedir(pam_handle_t * pamh, int ctrl, close(DestFd); closedir(D); _log_err(LOG_DEBUG, "unable to perform IO"); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + return PAM_PERM_DENIED; } while (Res != 0); close(SrcFd); close(DestFd); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + } closedir(D); diff --git a/modules/pam_rhosts/pam_rhosts_auth.c b/modules/pam_rhosts/pam_rhosts_auth.c index b41b708d..979580ec 100644 --- a/modules/pam_rhosts/pam_rhosts_auth.c +++ b/modules/pam_rhosts/pam_rhosts_auth.c @@ -50,6 +50,10 @@ #include #endif /* HAVE_SYS_FSUID_H */ +#ifdef HAVE_NET_IF_H +#include +#endif + #include #include #include @@ -92,6 +96,14 @@ int innetgr(const char *, const char *, const char *,const char *); #include #include +#ifdef _ISOC9X_SOURCE +#include +#define U32 uint32_t +#else +/* to the best of my knowledge, all modern UNIX boxes have 32 bits integers */ +#define U32 unsigned int +#endif /* _ISOC9X_SOURCE */ + /* Use the C99 type; older platforms will need this to be typedef'ed elsewhere */ #define U32 uint32_t diff --git a/modules/pam_securetty/pam_securetty.c b/modules/pam_securetty/pam_securetty.c index 8abbcb94..3a9ae421 100644 --- a/modules/pam_securetty/pam_securetty.c +++ b/modules/pam_securetty/pam_securetty.c @@ -161,12 +161,10 @@ static int securetty_perform_check(pam_handle_t *pamh, int flags, int ctrl, fclose(ttyfile); if (retval) { - if (ctrl & PAM_DEBUG_ARG) { _pam_log(LOG_WARNING, "access denied: tty '%s' is not secure !", uttyname); - } - retval = PAM_AUTH_ERR; + retval = PAM_AUTH_ERR; } else { if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG)) { _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'", diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 7c602766..816668f5 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -580,7 +580,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, yppwd.newpw.pw_gecos = pwd->pw_gecos; yppwd.newpw.pw_dir = pwd->pw_dir; yppwd.newpw.pw_shell = pwd->pw_shell; - yppwd.oldpass = fromwhat; + yppwd.oldpass = fromwhat ? fromwhat : ""; yppwd.newpw.pw_passwd = towhat; D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho)); diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c index e65728d8..ff1d1bff 100644 --- a/modules/pam_unix/unix_chkpwd.c +++ b/modules/pam_unix/unix_chkpwd.c @@ -77,6 +77,11 @@ static int _unix_shadowed(const struct passwd *pwd) static void su_sighandler(int sig) { +#ifndef SA_RESETHAND + /* emulate the behaviour of the SA_RESETHAND flag */ + if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) + signal(sig, SIG_DFL); +#endif if (sig > 0) { _log_err(LOG_NOTICE, "caught signal %d.", sig); exit(sig); @@ -92,7 +97,9 @@ static void setup_signals(void) */ (void) memset((void *) &action, 0, sizeof(action)); action.sa_handler = su_sighandler; +#ifdef SA_RESETHAND action.sa_flags = SA_RESETHAND; +#endif (void) sigaction(SIGILL, &action, NULL); (void) sigaction(SIGTRAP, &action, NULL); (void) sigaction(SIGBUS, &action, NULL); @@ -153,12 +160,10 @@ static int _unix_verify_password(const char *name, const char *p, int nullok) } salt_len = strlen(salt); - if (salt_len == 0) { + if (salt_len == 0) return (nullok == 0) ? UNIX_FAILED : UNIX_PASSED; - } - if (p == NULL) { + else if (p == NULL || strlen(p) == 0) return UNIX_FAILED; - } /* the moment of truth -- do we agree with the password? */ retval = UNIX_FAILED; -- cgit v1.2.3