diff --git a/Linux-PAM-git-20140109.diff b/Linux-PAM-git-20140109.diff new file mode 100644 index 0000000..359ad59 --- /dev/null +++ b/Linux-PAM-git-20140109.diff @@ -0,0 +1,268 @@ +--- 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, ""); + + 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 --git a/encryption_method_nis.diff b/encryption_method_nis.diff deleted file mode 100644 index 55980bf..0000000 --- a/encryption_method_nis.diff +++ /dev/null @@ -1,77 +0,0 @@ -diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c -index 0cfc0f4..2239206 100644 ---- a/modules/pam_unix/pam_unix_passwd.c -+++ b/modules/pam_unix/pam_unix_passwd.c -@@ -796,6 +796,29 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) - * 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. - */ -diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c -index 19d72e6..dafa9f0 100644 ---- a/modules/pam_unix/support.c -+++ b/modules/pam_unix/support.c -@@ -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 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, - } - - /* 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 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, - - /* 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); -diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h -index 6f5b2eb..a35a8a8 100644 ---- a/modules/pam_unix/support.h -+++ b/modules/pam_unix/support.h -@@ -174,4 +174,5 @@ extern int _unix_read_password(pam_handle_t * pamh - - 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 */ diff --git a/pam.changes b/pam.changes index 8372f47..19f76b7 100644 --- a/pam.changes +++ b/pam.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Fri Jan 10 10:56:24 UTC 2014 - kukuk@suse.com + +- 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 - kukuk@suse.de + +- 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 + ------------------------------------------------------------------- Fri Nov 29 20:25:32 UTC 2013 - schwab@linux-m68k.org diff --git a/pam.spec b/pam.spec index e184fcc..4a5dcb9 100644 --- a/pam.spec +++ b/pam.spec @@ -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 @@ Source7: common-session.pamd 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 @@ building both PAM-aware applications and modules for use with PAM. %prep %setup -q -n Linux-PAM-%{version} -b 1 %patch0 -p1 -%patch1 -p1 +%patch1 -p2 %patch2 -p1 +%patch3 -p1 %build export CFLAGS="%optflags -DNDEBUG" diff --git a/pam_loginuid-part1.diff b/pam_loginuid-part1.diff new file mode 100644 index 0000000..ab621dd --- /dev/null +++ b/pam_loginuid-part1.diff @@ -0,0 +1,115 @@ +commit 5825450540e6620ac331c64345b42fdcbb1d6e87 +Author: Dmitry V. Levin +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 +linux-pam-commits@lists.fedorahosted.org +https://lists.fedorahosted.org/mailman/listinfo/linux-pam-commits diff --git a/pam_loginuid-part2.diff b/pam_loginuid-part2.diff new file mode 100644 index 0000000..0980f1f --- /dev/null +++ b/pam_loginuid-part2.diff @@ -0,0 +1,74 @@ +commit 24f3a88e7de52fbfcb7b8a1ebdae0cdbef420edf +Author: Stéphane Graber +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 + Signed-off-by: Dmitry V. Levin + + 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 +linux-pam-commits@lists.fedorahosted.org +https://lists.fedorahosted.org/mailman/listinfo/linux-pam-commits diff --git a/pam_unix.diff b/pam_unix.diff deleted file mode 100644 index 39bcb29..0000000 --- a/pam_unix.diff +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h -index 6575938..6f5b2eb 100644 ---- a/modules/pam_unix/support.h -+++ b/modules/pam_unix/support.h -@@ -97,8 +97,9 @@ typedef struct { - 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 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = - /* 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 --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c -index 9aae3b0..d5f2540 100644 ---- a/modules/pam_unix/pam_unix_passwd.c -+++ b/modules/pam_unix/pam_unix_passwd.c -@@ -614,7 +614,8 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) - - 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) {