Hello community, here is the log from the commit of package pam for openSUSE:Factory checked in at 2014-01-11 11:12:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pam (Old) and /work/SRC/openSUSE:Factory/.pam.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pam" Changes: -------- --- /work/SRC/openSUSE:Factory/pam/pam.changes 2013-12-19 13:35:18.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.pam.new/pam.changes 2014-01-11 11:12:12.000000000 +0100 @@ -1,0 +2,17 @@ +Fri Jan 10 10:56:24 UTC 2014 - [email protected] + +- Add pam_loginuid-part1.diff: Ignore missing /proc/self/loginuid +- Add pam_loginuid-part2.diff: Workaround to run pam_loginuid inside lxc + +------------------------------------------------------------------- +Thu Jan 9 17:31:27 CET 2014 - [email protected] + +- Update to current git (Linux-PAM-git-20140109.diff, which + replaces pam_unix.diff and encryption_method_nis.diff) + - pam_access: fix debug level logging + - pam_warn: log flags passed to the module + - pam_securetty: check return value of fgets + - pam_lastlog: fix format string + - pam_loginuid: If the correct loginuid is already set, skip writing it + +------------------------------------------------------------------- Old: ---- encryption_method_nis.diff pam_unix.diff New: ---- Linux-PAM-git-20140109.diff pam_loginuid-part1.diff pam_loginuid-part2.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pam.spec ++++++ --- /var/tmp/diff_new_pack.8yCJ2P/_old 2014-01-11 11:12:13.000000000 +0100 +++ /var/tmp/diff_new_pack.8yCJ2P/_new 2014-01-11 11:12:13.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package pam # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -53,8 +53,9 @@ Source8: etc.environment Source9: baselibs.conf Patch0: fix-man-links.dif -Patch1: pam_unix.diff -Patch2: encryption_method_nis.diff +Patch1: Linux-PAM-git-20140109.diff +Patch2: pam_loginuid-part1.diff +Patch3: pam_loginuid-part2.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -99,8 +100,9 @@ %prep %setup -q -n Linux-PAM-%{version} -b 1 %patch0 -p1 -%patch1 -p1 +%patch1 -p2 %patch2 -p1 +%patch3 -p1 %build export CFLAGS="%optflags -DNDEBUG" ++++++ Linux-PAM-git-20140109.diff ++++++ --- 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; --- 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; } --- 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 2013-11-28 11:37:54.000000000 +0100 @@ -52,10 +52,10 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid) { int fd, count, rc = 0; - char loginuid[24]; + char loginuid[24], buf[24]; 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; @@ -64,8 +64,13 @@ } return rc; } - if (pam_modutil_write(fd, loginuid, count) != count) + if (pam_modutil_read(fd, buf, sizeof(buf)) == count && + memcmp(buf, loginuid, count) == 0) + goto done; /* already correct */ + if (lseek(fd, 0, SEEK_SET) == -1 || (ftruncate(fd, 0) == -1 || + pam_modutil_write(fd, loginuid, count) != count)) rc = 1; + done: close(fd); return rc; } --- 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? */ --- 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 2013-11-12 13:05:47.000000000 +0100 @@ -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) { @@ -795,6 +796,29 @@ * rebuild the password database file. */ + + /* if it is a NIS account, check for special hash algo */ + if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, user, 0, 1)) { + /* preset encryption method with value from /etc/login.defs */ + int j; + char *val = _unix_search_key ("ENCRYPT_METHOD_NIS", LOGIN_DEFS); + if (val) { + for (j = 0; j < UNIX_CTRLS_; ++j) { + if (unix_args[j].token && unix_args[j].is_hash_algo + && !strncasecmp(val, unix_args[j].token, strlen(unix_args[j].token))) { + break; + } + } + if (j >= UNIX_CTRLS_) { + pam_syslog(pamh, LOG_WARNING, "unrecognized ENCRYPT_METHOD_NIS value [%s]", val); + } else { + ctrl &= unix_args[j].mask; /* for turning things off */ + ctrl |= unix_args[j].flag; /* for turning things on */ + } + free (val); + } + } + /* * First we encrypt the new password. */ --- old/Linux-PAM-1.1.8/modules/pam_unix/README 2013-09-19 10:02:20.000000000 +0200 +++ new/linux-pam-1.1.8/modules/pam_unix/README 2014-01-09 16:29:02.000000000 +0100 @@ -36,7 +36,8 @@ The password component of this module performs the task of updating the user's password. The default encryption hash is taken from the ENCRYPT_METHOD variable -from /etc/login.defs +from /etc/login.defs. For NIS accounts, the ENCRYPT_METHOD_NIS variable from / +etc/login.defs is preferred. The session component of this module logs when a user logins or leave the system. --- 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 2013-11-12 13:05:24.000000000 +0100 @@ -37,8 +37,8 @@ #define SELINUX_ENABLED 0 #endif -static char * -search_key (const char *key, const char *filename) +char * +_unix_search_key (const char *key, const char *filename) { FILE *fp; char *buf = NULL; @@ -159,7 +159,7 @@ } /* preset encryption method with value from /etc/login.defs */ - val = search_key ("ENCRYPT_METHOD", LOGIN_DEFS); + val = _unix_search_key ("ENCRYPT_METHOD", LOGIN_DEFS); if (val) { for (j = 0; j < UNIX_CTRLS_; ++j) { if (unix_args[j].token && unix_args[j].is_hash_algo @@ -177,7 +177,7 @@ /* read number of rounds for crypt algo */ if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) { - val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); + val=_unix_search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); if (val) { *rounds = strtol(val, NULL, 10); --- 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 2013-11-12 13:05:04.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) @@ -172,4 +174,5 @@ extern int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, int *daysleft); +extern char *_unix_search_key(const char *key, const char *filename); #endif /* _PAM_UNIX_SUPPORT_H */ --- 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, "<unknown>"); 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; } ++++++ pam_loginuid-part1.diff ++++++ commit 5825450540e6620ac331c64345b42fdcbb1d6e87 Author: Dmitry V. Levin <[email protected]> Date: Wed Jan 8 15:53:30 2014 -0800 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. modules/pam_loginuid/pam_loginuid.c | 43 ++++++++++++++++++++++------------ 1 files changed, 28 insertions(+), 15 deletions(-) --- diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c index a903845..96f8ffa 100644 --- a/modules/pam_loginuid/pam_loginuid.c +++ b/modules/pam_loginuid/pam_loginuid.c @@ -47,29 +47,35 @@ /* * 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; + int fd, count, rc = PAM_SESSION_ERR; char loginuid[24], buf[24]; count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid); fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR); if (fd < 0) { - if (errno != ENOENT) { - rc = 1; + if (errno == ENOENT) { + rc = PAM_IGNORE; + } else { pam_syslog(pamh, LOG_ERR, "Cannot open /proc/self/loginuid: %m"); } return rc; } + if (pam_modutil_read(fd, buf, sizeof(buf)) == count && - memcmp(buf, loginuid, count) == 0) + memcmp(buf, loginuid, count) == 0) { + rc = PAM_SUCCESS; goto done; /* already correct */ - if (lseek(fd, 0, SEEK_SET) == -1 || (ftruncate(fd, 0) == -1 || - pam_modutil_write(fd, loginuid, count) != count)) - rc = 1; + } + 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; @@ -170,6 +176,7 @@ _pam_loginuid(pam_handle_t *pamh, int flags UNUSED, { const char *user = NULL; struct passwd *pwd; + int ret; #ifdef HAVE_LIBAUDIT int require_auditd = 0; #endif @@ -188,9 +195,14 @@ _pam_loginuid(pam_handle_t *pamh, int flags UNUSED, 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 @@ -200,11 +212,12 @@ _pam_loginuid(pam_handle_t *pamh, int flags UNUSED, 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; } /* _______________________________________________ linux-pam-commits mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/linux-pam-commits ++++++ pam_loginuid-part2.diff ++++++ commit 24f3a88e7de52fbfcb7b8a1ebdae0cdbef420edf Author: Stéphane Graber <[email protected]> Date: Tue Jan 7 16:12:03 2014 -0800 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). Signed-off-by: Steve Langasek <[email protected]> Signed-off-by: Dmitry V. Levin <[email protected]> modules/pam_loginuid/pam_loginuid.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-) --- diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c index 96f8ffa..54ae6f0 100644 --- a/modules/pam_loginuid/pam_loginuid.c +++ b/modules/pam_loginuid/pam_loginuid.c @@ -55,13 +55,26 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid) { 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)]; count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid); fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR); if (fd < 0) { if (errno == ENOENT) { rc = PAM_IGNORE; - } else { + } else if (errno == EACCES) { + 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); + } + if (rc != PAM_IGNORE) + errno = EACCES; + } + if (rc != PAM_IGNORE) { pam_syslog(pamh, LOG_ERR, "Cannot open /proc/self/loginuid: %m"); } _______________________________________________ linux-pam-commits mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/linux-pam-commits -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
