diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/ChangeLog new/linux-pam-1.1.8/ChangeLog --- old/Linux-PAM-1.1.8/ChangeLog 2013-09-19 11:33:00.000000000 +0200 +++ new/linux-pam-1.1.8/ChangeLog 2014-01-27 15:04:04.000000000 +0100 @@ -1,3 +1,272 @@ +2014-01-27 Dmitry V. Levin + + Fix gratuitous use of strdup and x_strdup. + There is no need to copy strings passed as arguments to execve, + the only potentially noticeable effect of using strdup/x_strdup + would be a malformed argument list in case of memory allocation error. + + Also, x_strdup, being a thin wrapper around strdup, is of no benefit + when its argument is known to be non-NULL, and should not be used in + such cases. + + * modules/pam_cracklib/pam_cracklib.c (password_check): Use strdup + instead of x_strdup, the latter is of no benefit in this case. + * modules/pam_ftp/pam_ftp.c (lookup): Likewise. + * modules/pam_userdb/pam_userdb.c (user_lookup): Likewise. + * modules/pam_userdb/pam_userdb.h (x_strdup): Remove. + * modules/pam_mkhomedir/pam_mkhomedir.c (create_homedir): Do not use + x_strdup for strings passed as arguments to execve. + * modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary): Likewise. + * modules/pam_unix/pam_unix_passwd.c (_unix_run_update_binary): Likewise. + * modules/pam_unix/support.c (_unix_run_helper_binary): Likewise. + (_unix_verify_password): Use strdup instead of x_strdup, the latter + is of no benefit in this case. + * modules/pam_xauth/pam_xauth.c (run_coprocess): Do not use strdup for + strings passed as arguments to execv. + + pam_userdb: fix password hash comparison. + Starting with commit Linux-PAM-0-77-28-g0b3e583 that introduced hashed + passwords support in pam_userdb, hashes are compared case-insensitively. + This bug leads to accepting hashes for completely different passwords in + addition to those that should be accepted. + + Additionally, commit Linux-PAM-1_1_6-13-ge2a8187 that added support for + modern password hashes with different lengths and settings, did not + update the hash comparison accordingly, which leads to accepting + computed hashes longer than stored hashes when the latter is a prefix + of the former. + + * modules/pam_userdb/pam_userdb.c (user_lookup): Reject the computed + hash whose length differs from the stored hash length. + Compare computed and stored hashes case-sensitively. + Fixes CVE-2013-7041. + + Bug-Debian: http://bugs.debian.org/731368 + +2014-01-24 Dmitry V. Levin + + pam_xauth: log fatal errors preventing xauth process execution. + * modules/pam_xauth/pam_xauth.c (run_coprocess): Log errors from pipe() + and fork() calls. + +2014-01-22 Dmitry V. Levin + + pam_loginuid: cleanup loginuid buffer initialization. + * modules/pam_loginuid/pam_loginuid.c (set_loginuid): Move loginuid + buffer initialization closer to its first use. + + libpam_misc: fix an inconsistency in handling memory allocation errors. + When misc_conv fails to allocate memory for pam_response array, it + returns PAM_CONV_ERR. However, when read_string fails to allocate + memory for a response string, it loses the response string and silently + ignores the error, with net result as if EOF has been read. + + * libpam_misc/misc_conv.c (read_string): Use strdup instead of x_strdup, + the latter is of no benefit in this case. + Do not ignore potential memory allocation errors returned by strdup, + forward them to misc_conv. + +2014-01-20 Dmitry V. Levin + + pam_limits: fix utmp->ut_user handling. + ut_user member of struct utmp is a string that is not necessarily + null-terminated, so extra care should be taken when using it. + + * modules/pam_limits/pam_limits.c (check_logins): Convert ut->UT_USER to + a null-terminated string and consistently use it where a null-terminated + string is expected. + + pam_mkhomedir: check and create home directory for the same user (ticket #22) + Before pam_mkhomedir helper was introduced in commit + 7b14630ef39e71f603aeca0c47edf2f384717176, pam_mkhomedir was checking for + existance and creating the same directory - the home directory of the + user NAME returned by pam_get_item(PAM_USER). + + The change in behaviour accidentally introduced along with + mkhomedir_helper is not consistent: while the module still checks for + getpwnam(NAME)->pw_dir, the directory created by mkhomedir_helper is + getpwnam(getpwnam(NAME)->pw_name)->pw_dir, which is not necessarily + the same as the directory being checked. + + This change brings check and creation back in sync, both handling + getpwnam(NAME)->pw_dir. + + * modules/pam_mkhomedir/pam_mkhomedir.c (create_homedir): Replace + "struct passwd *" argument with user's name and home directory. + Pass user's name to MKHOMEDIR_HELPER. + (pam_sm_open_session): Update create_homedir call. + +2014-01-20 Tomas Mraz + + pam_limits: detect and ignore stale utmp entries. + Original idea by Christopher Hailey + + * modules/pam_limits/pam_limits.c (check_logins): Use kill() to + detect if pid of the utmp entry is still running and ignore the entry + if it is not. + +2014-01-19 Stéphane Graber + + pam_loginuid: Always return PAM_IGNORE in userns. + The previous patch to support user namespaces works fine with containers + that are started from a desktop/terminal session but fails when dealing + with containers that were started from a remote session such as ssh. + + I haven't looked at the exact reason for that in the kernel but on the + userspace side of things, the difference is that containers started from + an ssh session will happily let pam open /proc/self/loginuid read-write, + will let it read its content but will then fail with EPERM when trying + to write to it. + + So to make the userns support bullet proof, this commit moves the userns + check earlier in the function (which means a small performance impact as + it'll now happen everytime on kernels that have userns support) and will + set rc = PAM_IGNORE instead of rc = PAM_ERROR. + + The rest of the code is still executed in the event that PAM is run on a + future kernel where we have some kind of audit namespace that includes a + working loginuid. + +2014-01-15 Steve Langasek + + pam_namespace: don't use bashisms in default namespace.init script. + * modules/pam_namespace/pam_namespace.c: call setuid() before execing the + namespace init script, so that scripts run with maximum privilege regardless + of the shell implementation. + * modules/pam_namespace/namespace.init: drop the '-p' bashism from the + shebang line + + This is not a POSIX standard option, it's a bashism. The bash manpage says + that it's used to prevent the effective user id from being reset to the real + user id on startup, and to ignore certain unsafe variables from the + environment. + + In the case of pam_namespace, the -p is not necessary for environment + sanitizing because the PAM module (properly) sanitizes the environment + before execing the script. + + The stated reason given in CVS history for passing -p is to "preserve euid + when called from setuid apps (su, newrole)." This should be done more + portably, by calling setuid() before spawning the shell. + + Bug-Debian: http://bugs.debian.org/624842 + Bug-Ubuntu: https://bugs.launchpad.net/bugs/1081323 + +2014-01-10 Stéphane Graber + + pam_loginuid: Ignore failure in user namespaces. + When running pam_loginuid in a container using the user namespaces, even + uid 0 isn't allowed to set the loginuid property. + + This change catches the EACCES from opening loginuid, checks if the user + is in the host namespace (by comparing the uid_map with the host's one) + and only if that's the case, sets rc to 1. + + Should uid_map not exist or be unreadable for some reason, it'll be + assumed that the process is running on the host's namespace. + + The initial reason behind this change was failure to ssh into an + unprivileged container (using a 3.13 kernel and current LXC) when using + a standard pam profile for sshd (which requires success from + pam_loginuid). + + I believe this solution doesn't have any drawback and will allow people + to use unprivileged containers normally. An alternative would be to have + all distros set pam_loginuid as optional but that'd be bad for any of + the other potential failure case which people may care about. + + There has also been some discussions to get some of the audit features + tied with the user namespaces but currently none of that has been merged + upstream and the currently proposed implementation doesn't cover + loginuid (nor is it clear how this should even work when loginuid is set + as immutable after initial write). + +2014-01-10 Dmitry V. Levin + + pam_loginuid: return PAM_IGNORE when /proc/self/loginuid does not exist. + When /proc/self/loginuid does not exist, return PAM_IGNORE instead of + PAM_SUCCESS, so that we can distinguish between "loginuid set + successfully" and "loginuid not set, but this is expected". + + Suggested by Steve Langasek. + + * modules/pam_loginuid/pam_loginuid.c (set_loginuid): Change return + code semantics: return PAM_SUCCESS on success, PAM_IGNORE when loginuid + does not exist, PAM_SESSION_ERR in case of any other error. + (_pam_loginuid): Forward the PAM error code returned by set_loginuid. + +2013-11-20 Dmitry V. Levin + + pam_access: fix debug level logging (ticket #19) + * modules/pam_access/pam_access.c (group_match): Log the group token + passed to the function, not an uninitialized data on the stack. + + pam_warn: log flags passed to the module (ticket #25) + * modules/pam_warn/pam_warn.c (log_items): Take "flags" argument and + log it using pam_syslog. + (pam_sm_authenticate, pam_sm_setcred, pam_sm_chauthtok, + pam_sm_acct_mgmt, pam_sm_open_session, pam_sm_close_session): Pass + "flags" argument to log_items. + + Modernize AM_INIT_AUTOMAKE invocation. + Before this change, automake complained that two- and three-arguments + forms of AM_INIT_AUTOMAKE are deprecated. + + * configure.in: Pass PACKAGE and VERSION arguments to AC_INIT instead + of AM_INIT_AUTOMAKE. + + Fix autoconf warnings. + Before this change, autoconf complained that AC_COMPILE_IFELSE + and AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS. + + * configure.in: Call AC_USE_SYSTEM_EXTENSIONS before LT_INIT. + + pam_securetty: check return value of fgets. + Checking return value of fgets not only silences the warning from glibc + but also leads to a cleaner code. + + * modules/pam_securetty/pam_securetty.c (securetty_perform_check): + Check return value of fgets. + + pam_lastlog: fix format string. + gcc -Wformat justly complains: + format '%d' expects argument of type 'int', but argument 5 has type 'time_t' + + * modules/pam_lastlog/pam_lastlog.c (pam_sm_authenticate): Fix format + string. + +2013-11-20 Darren Tucker + + If the correct loginuid is set already, skip writing it. + modules/pam_loginuid/pam_loginuid.c (set_loginuid): Read the current loginuid + and skip writing if already correctly set. + +2013-11-11 Thorsten Kukuk + + Always ask for old password if changing NIS account. + * modules/pam_unix/pam_unix_passwd.c (pam_sm_chauthtok): ask + for old password if NIS account. + +2013-11-08 Thorsten Kukuk + + Allow DES as compatibility option for /etc/login.defs. + * modules/pam_unix/support.h: Add UNIX_DES + +2013-10-14 Tomas Mraz + + Docfix: pam_prompt() and pam_vprompt() return int. + doc/man/pam_prompt.3.xml: pam_prompt() and pam_vprompt() return int. + + Make pam_tty_audit work with old kernels not supporting log_passwd. + modules/pam_tty_audit/pam_tty_audit.c(nl_recv): Pad result with zeros + if message is short from older kernel. + +2013-09-25 Tomas Mraz + + Fix pam_tty_audit log_passwd support and regression. + modules/pam_tty_audit/pam_tty_audit.c: Add missing "config.h" include. + (pam_sm_open_session): Always copy the old status as initialization of new. + 2013-09-19 Thorsten Kukuk Release version 1.1.8. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/doc/man/pam_prompt.3.xml new/linux-pam-1.1.8/doc/man/pam_prompt.3.xml --- old/Linux-PAM-1.1.8/doc/man/pam_prompt.3.xml 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/doc/man/pam_prompt.3.xml 2013-11-08 14:33:32.000000000 +0100 @@ -22,7 +22,7 @@ #include <security/pam_ext.h> - void pam_prompt + int pam_prompt pam_handle_t *pamh int style char **response @@ -30,7 +30,7 @@ ... - void pam_vprompt + int pam_vprompt pam_handle_t *pamh int style char **response @@ -75,7 +75,7 @@ PAM_SUCCESS - Transaction was successful created. + Conversation succeded, response is set. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/libpam_misc/misc_conv.c new/linux-pam-1.1.8/libpam_misc/misc_conv.c --- old/Linux-PAM-1.1.8/libpam_misc/misc_conv.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/libpam_misc/misc_conv.c 2014-01-25 07:35:59.000000000 +0100 @@ -210,8 +210,12 @@ } line[nc] = '\0'; } - *retstr = x_strdup(line); + *retstr = strdup(line); _pam_overwrite(line); + if (!*retstr) { + D(("no memory for response string")); + nc = -1; + } goto cleanexit; /* return malloc()ed string */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_access/pam_access.c new/linux-pam-1.1.8/modules/pam_access/pam_access.c --- old/Linux-PAM-1.1.8/modules/pam_access/pam_access.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_access/pam_access.c 2014-01-09 16:28:39.000000000 +0100 @@ -573,7 +573,7 @@ if (debug) pam_syslog (pamh, LOG_DEBUG, - "group_match: grp=%s, user=%s", grptok, usr); + "group_match: grp=%s, user=%s", tok, usr); if (strlen(tok) < 3) return NO; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_cracklib/pam_cracklib.c new/linux-pam-1.1.8/modules/pam_cracklib/pam_cracklib.c --- old/Linux-PAM-1.1.8/modules/pam_cracklib/pam_cracklib.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_cracklib/pam_cracklib.c 2014-01-27 15:02:50.000000000 +0100 @@ -619,16 +619,16 @@ return msg; } - newmono = str_lower(x_strdup(new)); + newmono = str_lower(strdup(new)); if (!newmono) msg = _("memory allocation error"); - usermono = str_lower(x_strdup(user)); + usermono = str_lower(strdup(user)); if (!usermono) msg = _("memory allocation error"); if (!msg && old) { - oldmono = str_lower(x_strdup(old)); + oldmono = str_lower(strdup(old)); if (oldmono) wrapped = malloc(strlen(oldmono) * 2 + 1); if (wrapped) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_ftp/pam_ftp.c new/linux-pam-1.1.8/modules/pam_ftp/pam_ftp.c --- old/Linux-PAM-1.1.8/modules/pam_ftp/pam_ftp.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_ftp/pam_ftp.c 2014-01-27 15:02:50.000000000 +0100 @@ -81,7 +81,7 @@ char *list_copy, *x; char *sptr = NULL; - list_copy = x_strdup(list); + list_copy = strdup(list); x = list_copy; while (list_copy && (l = strtok_r(x, ",", &sptr))) { x = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c new/linux-pam-1.1.8/modules/pam_lastlog/pam_lastlog.c --- old/Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_lastlog/pam_lastlog.c 2013-11-28 11:37:54.000000000 +0100 @@ -628,7 +628,8 @@ lltime = (time(NULL) - lltime) / (24*60*60); if (lltime > inactive_days) { - pam_syslog(pamh, LOG_INFO, "user %s inactive for %d days - denied", user, lltime); + pam_syslog(pamh, LOG_INFO, "user %s inactive for %ld days - denied", + user, (long) lltime); return PAM_AUTH_ERR; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c new/linux-pam-1.1.8/modules/pam_limits/pam_limits.c --- old/Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_limits/pam_limits.c 2014-01-25 07:35:59.000000000 +0100 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -269,16 +270,27 @@ continue; } if (!pl->flag_numsyslogins) { + char user[sizeof(ut->UT_USER) + 1]; + user[0] = '\0'; + strncat(user, ut->UT_USER, sizeof(ut->UT_USER)); + if (((pl->login_limit_def == LIMITS_DEF_USER) || (pl->login_limit_def == LIMITS_DEF_GROUP) || (pl->login_limit_def == LIMITS_DEF_DEFAULT)) - && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) { + && strcmp(name, user) != 0) { continue; } if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP) - && !pam_modutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) { + && !pam_modutil_user_in_group_nam_nam(pamh, user, pl->login_group)) { continue; } + if (kill(ut->ut_pid, 0) == -1 && errno == ESRCH) { + /* process does not exist anymore */ + pam_syslog(pamh, LOG_WARNING, + "Stale utmp entry (pid %d) for '%s' ignored", + ut->ut_pid, user); + continue; + } } if (++count > limit) { break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c new/linux-pam-1.1.8/modules/pam_loginuid/pam_loginuid.c --- old/Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_loginuid/pam_loginuid.c 2014-01-25 07:35:59.000000000 +0100 @@ -47,25 +47,50 @@ /* * This function writes the loginuid to the /proc system. It returns - * 0 on success and 1 on failure. + * PAM_SUCCESS on success, + * PAM_IGNORE when /proc/self/loginuid does not exist, + * PAM_SESSION_ERR in case of any other error. */ static int set_loginuid(pam_handle_t *pamh, uid_t uid) { - int fd, count, rc = 0; - char loginuid[24]; + int fd, count, rc = PAM_SESSION_ERR; + char loginuid[24], buf[24]; + static const char host_uid_map[] = " 0 0 4294967295\n"; + char uid_map[sizeof(host_uid_map)]; + + /* loginuid in user namespaces currently isn't writable and in some + case, not even readable, so consider any failure as ignorable (but try + anyway, in case we hit a kernel which supports it). */ + fd = open("/proc/self/uid_map", O_RDONLY); + if (fd >= 0) { + count = pam_modutil_read(fd, uid_map, sizeof(uid_map)); + if (strncmp(uid_map, host_uid_map, count) != 0) + rc = PAM_IGNORE; + close(fd); + } - count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid); - fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC); + fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR); if (fd < 0) { - if (errno != ENOENT) { - rc = 1; + if (errno == ENOENT) { + rc = PAM_IGNORE; + } + if (rc != PAM_IGNORE) { pam_syslog(pamh, LOG_ERR, "Cannot open /proc/self/loginuid: %m"); } return rc; } - if (pam_modutil_write(fd, loginuid, count) != count) - rc = 1; + + count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid); + if (pam_modutil_read(fd, buf, sizeof(buf)) == count && + memcmp(buf, loginuid, count) == 0) { + rc = PAM_SUCCESS; + goto done; /* already correct */ + } + if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 && + pam_modutil_write(fd, loginuid, count) == count) + rc = PAM_SUCCESS; + done: close(fd); return rc; } @@ -165,6 +190,7 @@ { const char *user = NULL; struct passwd *pwd; + int ret; #ifdef HAVE_LIBAUDIT int require_auditd = 0; #endif @@ -183,9 +209,14 @@ return PAM_SESSION_ERR; } - if (set_loginuid(pamh, pwd->pw_uid)) { - pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n"); - return PAM_SESSION_ERR; + ret = set_loginuid(pamh, pwd->pw_uid); + switch (ret) { + case PAM_SUCCESS: + case PAM_IGNORE: + break; + default: + pam_syslog(pamh, LOG_ERR, "set_loginuid failed"); + return ret; } #ifdef HAVE_LIBAUDIT @@ -195,11 +226,12 @@ argv++; } - if (require_auditd) - return check_auditd(); - else + if (require_auditd) { + int rc = check_auditd(); + return rc != PAM_SUCCESS ? rc : ret; + } else #endif - return PAM_SUCCESS; + return ret; } /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_mkhomedir/pam_mkhomedir.c new/linux-pam-1.1.8/modules/pam_mkhomedir/pam_mkhomedir.c --- old/Linux-PAM-1.1.8/modules/pam_mkhomedir/pam_mkhomedir.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_mkhomedir/pam_mkhomedir.c 2014-01-27 15:02:50.000000000 +0100 @@ -103,14 +103,14 @@ /* Do the actual work of creating a home dir */ static int create_homedir (pam_handle_t *pamh, options_t *opt, - const struct passwd *pwd) + const char *user, const char *dir) { int retval, child; struct sigaction newsa, oldsa; /* Mention what is happening, if the notification fails that is OK */ if (!(opt->ctrl & MKHOMEDIR_QUIET)) - pam_info(pamh, _("Creating directory '%s'."), pwd->pw_dir); + pam_info(pamh, _("Creating directory '%s'."), dir); D(("called.")); @@ -134,7 +134,7 @@ int i; struct rlimit rlim; static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL, NULL }; + const char *args[] = { NULL, NULL, NULL, NULL, NULL }; if (getrlimit(RLIMIT_NOFILE, &rlim)==0) { if (rlim.rlim_max >= MAX_FD_NO) @@ -145,12 +145,12 @@ } /* exec the mkhomedir helper */ - args[0] = x_strdup(MKHOMEDIR_HELPER); - args[1] = pwd->pw_name; - args[2] = x_strdup(opt->umask); - args[3] = x_strdup(opt->skeldir); + args[0] = MKHOMEDIR_HELPER; + args[1] = user; + args[2] = opt->umask; + args[3] = opt->skeldir; - execve(MKHOMEDIR_HELPER, args, envp); + execve(MKHOMEDIR_HELPER, (char *const *) args, envp); /* should not get here: exit with error */ D(("helper binary is not available")); @@ -181,7 +181,7 @@ if (retval != PAM_SUCCESS && !(opt->ctrl & MKHOMEDIR_QUIET)) { pam_error(pamh, _("Unable to create and initialize directory '%s'."), - pwd->pw_dir); + dir); } D(("returning %d", retval)); @@ -230,7 +230,7 @@ return PAM_SUCCESS; } - return create_homedir(pamh, &opt, pwd); + return create_homedir(pamh, &opt, user, pwd->pw_dir); } /* Ignore */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_namespace/namespace.init new/linux-pam-1.1.8/modules/pam_namespace/namespace.init --- old/Linux-PAM-1.1.8/modules/pam_namespace/namespace.init 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_namespace/namespace.init 2014-01-25 07:35:59.000000000 +0100 @@ -1,4 +1,4 @@ -#!/bin/sh -p +#!/bin/sh # It receives polydir path as $1, the instance path as $2, # a flag whether the instance dir was newly created (0 - no, 1 - yes) in $3, # and user name in $4. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_namespace/pam_namespace.c new/linux-pam-1.1.8/modules/pam_namespace/pam_namespace.c --- old/Linux-PAM-1.1.8/modules/pam_namespace/pam_namespace.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_namespace/pam_namespace.c 2014-01-25 07:35:59.000000000 +0100 @@ -1205,6 +1205,11 @@ _exit(1); } #endif + /* Pass maximum privs when we exec() */ + if (setuid(geteuid()) < 0) { + /* ignore failures, they don't matter */ + } + if (execle(init_script, init_script, polyptr->dir, ipath, newdir?"1":"0", idata->user, NULL, envp) < 0) _exit(1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_securetty/pam_securetty.c new/linux-pam-1.1.8/modules/pam_securetty/pam_securetty.c --- old/Linux-PAM-1.1.8/modules/pam_securetty/pam_securetty.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_securetty/pam_securetty.c 2013-11-28 11:37:54.000000000 +0100 @@ -159,11 +159,10 @@ if (cmdlinefile != NULL) { char line[LINE_MAX], *p; - line[0] = 0; - fgets(line, sizeof(line), cmdlinefile); + p = fgets(line, sizeof(line), cmdlinefile); fclose(cmdlinefile); - for (p = line; p; p = strstr(p+1, "console=")) { + for (; p; p = strstr(p+1, "console=")) { char *e; /* Test whether this is a beginning of a word? */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c new/linux-pam-1.1.8/modules/pam_tty_audit/pam_tty_audit.c --- old/Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c 2013-08-28 10:53:40.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_tty_audit/pam_tty_audit.c 2013-11-08 14:33:32.000000000 +0100 @@ -36,6 +36,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" #include #include #include @@ -108,7 +109,7 @@ struct msghdr msg; struct nlmsghdr nlm; struct iovec iov[2]; - ssize_t res; + ssize_t res, resdiff; again: iov[0].iov_base = &nlm; @@ -160,12 +161,17 @@ res = recvmsg (fd, &msg, 0); if (res == -1) return -1; - if ((size_t)res != NLMSG_LENGTH (size) + resdiff = NLMSG_LENGTH(size) - (size_t)res; + if (resdiff < 0 || nlm.nlmsg_type != type) { errno = EIO; return -1; } + else if (resdiff > 0) + { + memset((char *)buf + size - resdiff, 0, resdiff); + } return 0; } @@ -275,6 +281,8 @@ return PAM_SESSION_ERR; } + memcpy(&new_status, old_status, sizeof(new_status)); + new_status.enabled = (command == CMD_ENABLE ? 1 : 0); #ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD new_status.log_passwd = log_passwd; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c new/linux-pam-1.1.8/modules/pam_unix/pam_unix_acct.c --- old/Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c 2013-09-16 11:11:51.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_unix/pam_unix_acct.c 2014-01-27 15:02:50.000000000 +0100 @@ -101,7 +101,7 @@ int i=0; struct rlimit rlim; static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL }; + const char *args[] = { NULL, NULL, NULL, NULL }; /* reopen stdout as pipe */ dup2(fds[1], STDOUT_FILENO); @@ -130,11 +130,11 @@ } /* exec binary helper */ - args[0] = x_strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); - args[2] = x_strdup("chkexpiry"); + args[0] = CHKPWD_HELPER; + args[1] = user; + args[2] = "chkexpiry"; - execve(CHKPWD_HELPER, args, envp); + execve(CHKPWD_HELPER, (char *const *) args, envp); pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m"); /* should not get here: exit with error */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_unix/pam_unix_passwd.c new/linux-pam-1.1.8/modules/pam_unix/pam_unix_passwd.c --- old/Linux-PAM-1.1.8/modules/pam_unix/pam_unix_passwd.c 2013-09-16 11:09:47.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_unix/pam_unix_passwd.c 2014-01-27 15:02:50.000000000 +0100 @@ -204,7 +204,7 @@ int i=0; struct rlimit rlim; static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; + const char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; char buffer[16]; /* XXX - should really tidy up PAM here too */ @@ -222,18 +222,18 @@ } /* exec binary helper */ - args[0] = x_strdup(UPDATE_HELPER); - args[1] = x_strdup(user); - args[2] = x_strdup("update"); + args[0] = UPDATE_HELPER; + args[1] = user; + args[2] = "update"; if (on(UNIX_SHADOW, ctrl)) - args[3] = x_strdup("1"); + args[3] = "1"; else - args[3] = x_strdup("0"); + args[3] = "0"; snprintf(buffer, sizeof(buffer), "%d", remember); - args[4] = x_strdup(buffer); + args[4] = buffer; - execve(UPDATE_HELPER, args, envp); + execve(UPDATE_HELPER, (char *const *) args, envp); /* should not get here: exit with error */ D(("helper binary is not available")); @@ -614,7 +614,8 @@ if (_unix_blankpasswd(pamh, ctrl, user)) { return PAM_SUCCESS; - } else if (off(UNIX__IAMROOT, ctrl)) { + } else if (off(UNIX__IAMROOT, ctrl) || + (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, user, 0, 1))) { /* instruct user what is happening */ if (asprintf(&Announce, _("Changing password for %s."), user) < 0) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_unix/support.c new/linux-pam-1.1.8/modules/pam_unix/support.c --- old/Linux-PAM-1.1.8/modules/pam_unix/support.c 2013-09-16 11:11:51.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_unix/support.c 2014-01-27 15:02:50.000000000 +0100 @@ -567,7 +567,7 @@ int i=0; struct rlimit rlim; static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL }; + const char *args[] = { NULL, NULL, NULL, NULL }; /* XXX - should really tidy up PAM here too */ @@ -593,15 +593,15 @@ } /* exec binary helper */ - args[0] = strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); + args[0] = CHKPWD_HELPER; + args[1] = user; if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */ - args[2]=strdup("nullok"); + args[2]="nullok"; } else { - args[2]=strdup("nonull"); + args[2]="nonull"; } - execve(CHKPWD_HELPER, args, envp); + execve(CHKPWD_HELPER, (char *const *) args, envp); /* should not get here: exit with error */ D(("helper binary is not available")); @@ -788,10 +788,10 @@ login_name = ""; } - new->user = x_strdup(name ? name : ""); + new->user = strdup(name ? name : ""); new->uid = getuid(); new->euid = geteuid(); - new->name = x_strdup(login_name); + new->name = strdup(login_name); /* any previous failures for this user ? */ if (pam_get_data(pamh, data_name, &void_old) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_unix/support.h new/linux-pam-1.1.8/modules/pam_unix/support.h --- old/Linux-PAM-1.1.8/modules/pam_unix/support.h 2013-06-18 16:24:05.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_unix/support.h 2014-01-27 15:02:38.000000000 +0100 @@ -97,8 +97,9 @@ password hash algorithms */ #define UNIX_BLOWFISH_PASS 26 /* new password hashes will use blowfish */ #define UNIX_MIN_PASS_LEN 27 /* min length for password */ +#define UNIX_DES 28 /* DES, default */ /* -------------- */ -#define UNIX_CTRLS_ 28 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 29 /* number of ctrl arguments defined */ #define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)) @@ -135,6 +136,7 @@ /* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, /* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000, 1}, /* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, +/* UNIX_DES */ {"des", _ALL_ON_^(0260420000), 0, 1}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) .\" ----------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.c new/linux-pam-1.1.8/modules/pam_userdb/pam_userdb.c --- old/Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_userdb/pam_userdb.c 2014-01-27 15:02:50.000000000 +0100 @@ -184,7 +184,7 @@ else key.dsize = strlen(key.dptr); } else { - key.dptr = x_strdup(user); + key.dptr = strdup(user); key.dsize = strlen(user); } @@ -222,12 +222,15 @@ } else { cryptpw = crypt (pass, data.dptr); - if (cryptpw) { - compare = strncasecmp (data.dptr, cryptpw, data.dsize); + if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) { + compare = memcmp(data.dptr, cryptpw, data.dsize); } else { compare = -2; if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); + if (cryptpw) + pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ"); + else + pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); } }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.h new/linux-pam-1.1.8/modules/pam_userdb/pam_userdb.h --- old/Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.h 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_userdb/pam_userdb.h 2014-01-27 15:02:50.000000000 +0100 @@ -15,9 +15,6 @@ #define PAM_USE_FPASS_ARG 0x0040 #define PAM_TRY_FPASS_ARG 0x0080 -/* Useful macros */ -#define x_strdup(s) ( (s) ? strdup(s):NULL ) - /* The name of the module we are compiling */ #ifndef MODULE_NAME #define MODULE_NAME "pam_userdb" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_warn/pam_warn.c new/linux-pam-1.1.8/modules/pam_warn/pam_warn.c --- old/Linux-PAM-1.1.8/modules/pam_warn/pam_warn.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_warn/pam_warn.c 2013-11-28 11:37:54.000000000 +0100 @@ -33,7 +33,7 @@ value = value ? value : default_value ; \ } while (0) -static void log_items(pam_handle_t *pamh, const char *function) +static void log_items(pam_handle_t *pamh, const char *function, int flags) { const void *service=NULL, *user=NULL, *terminal=NULL, *rhost=NULL, *ruser=NULL; @@ -45,8 +45,8 @@ OBTAIN(PAM_RHOST, rhost, ""); pam_syslog(pamh, LOG_NOTICE, - "function=[%s] service=[%s] terminal=[%s] user=[%s]" - " ruser=[%s] rhost=[%s]\n", function, + "function=[%s] flags=%#x service=[%s] terminal=[%s] user=[%s]" + " ruser=[%s] rhost=[%s]\n", function, flags, (const char *) service, (const char *) terminal, (const char *) user, (const char *) ruser, (const char *) rhost); @@ -55,52 +55,52 @@ /* --- authentication management functions (only) --- */ PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, +int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, +int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } /* password updating functions */ PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags UNUSED, +int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, +pam_sm_open_session(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, +pam_sm_close_session(pam_handle_t *pamh, int flags, int argc UNUSED, const char **argv UNUSED) { - log_items(pamh, __FUNCTION__); + log_items(pamh, __FUNCTION__, flags); return PAM_IGNORE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Linux-PAM-1.1.8/modules/pam_xauth/pam_xauth.c new/linux-pam-1.1.8/modules/pam_xauth/pam_xauth.c --- old/Linux-PAM-1.1.8/modules/pam_xauth/pam_xauth.c 2013-06-18 16:11:21.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_xauth/pam_xauth.c 2014-01-27 15:02:50.000000000 +0100 @@ -103,9 +103,11 @@ /* Create stdio pipery. */ if (pipe(ipipe) == -1) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); return -1; } if (pipe(opipe) == -1) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); close(ipipe[0]); close(ipipe[1]); return -1; @@ -114,6 +116,7 @@ /* Fork off a child. */ child = fork(); if (child == -1) { + pam_syslog(pamh, LOG_ERR, "Could not fork: %m"); close(ipipe[0]); close(ipipe[1]); close(opipe[0]); @@ -124,8 +127,7 @@ if (child == 0) { /* We're the child. */ size_t j; - char *args[10]; - const char *tmp; + const char *args[10]; int maxopened; /* Drop privileges. */ if (setgid(gid) == -1) @@ -163,16 +165,15 @@ } /* Convert the varargs list into a regular array of strings. */ va_start(ap, command); - args[0] = strdup(command); + args[0] = command; for (j = 1; j < ((sizeof(args) / sizeof(args[0])) - 1); j++) { - tmp = va_arg(ap, const char*); - if (tmp == NULL) { + args[j] = va_arg(ap, const char*); + if (args[j] == NULL) { break; } - args[j] = strdup(tmp); } /* Run the command. */ - execv(command, args); + execv(command, (char *const *) args); /* Never reached. */ _exit(1); }