152 lines
4.6 KiB
Diff
152 lines
4.6 KiB
Diff
|
diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c
|
||
|
--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container 2013-06-18 16:11:21.000000000 +0200
|
||
|
+++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c 2014-01-27 17:24:53.000000000 +0100
|
||
|
@@ -47,25 +47,56 @@
|
||
|
|
||
|
/*
|
||
|
* 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;
|
||
|
- pam_syslog(pamh, LOG_ERR,
|
||
|
- "Cannot open /proc/self/loginuid: %m");
|
||
|
+ if (errno == ENOENT) {
|
||
|
+ rc = PAM_IGNORE;
|
||
|
+ }
|
||
|
+ if (rc != PAM_IGNORE) {
|
||
|
+ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
|
||
|
+ "/proc/self/loginuid");
|
||
|
}
|
||
|
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;
|
||
|
+ } else {
|
||
|
+ if (rc != PAM_IGNORE) {
|
||
|
+ pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
|
||
|
+ "/proc/self/loginuid");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ done:
|
||
|
close(fd);
|
||
|
return rc;
|
||
|
}
|
||
|
@@ -165,6 +196,7 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||
|
{
|
||
|
const char *user = NULL;
|
||
|
struct passwd *pwd;
|
||
|
+ int ret;
|
||
|
#ifdef HAVE_LIBAUDIT
|
||
|
int require_auditd = 0;
|
||
|
#endif
|
||
|
@@ -183,9 +215,14 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||
|
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 +232,12 @@ _pam_loginuid(pam_handle_t *pamh, int fl
|
||
|
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 -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml
|
||
|
--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container 2013-06-18 16:11:21.000000000 +0200
|
||
|
+++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml 2014-05-22 11:33:14.000000000 +0200
|
||
|
@@ -69,14 +69,31 @@
|
||
|
<para>
|
||
|
<variablelist>
|
||
|
<varlistentry>
|
||
|
+ <term>PAM_SUCCESS</term>
|
||
|
+ <listitem>
|
||
|
+ <para>
|
||
|
+ The loginuid value is set and auditd is running if check requested.
|
||
|
+ </para>
|
||
|
+ </listitem>
|
||
|
+ </varlistentry>
|
||
|
+ <varlistentry>
|
||
|
+ <term>PAM_IGNORE</term>
|
||
|
+ <listitem>
|
||
|
+ <para>
|
||
|
+ The /proc/self/loginuid file is not present on the system or the
|
||
|
+ login process runs inside uid namespace and kernel does not support
|
||
|
+ overwriting loginuid.
|
||
|
+ </para>
|
||
|
+ </listitem>
|
||
|
+ </varlistentry>
|
||
|
+ <varlistentry>
|
||
|
<term>PAM_SESSION_ERR</term>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
- An error occurred during session management.
|
||
|
+ Any other error prevented setting loginuid or auditd is not running.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</varlistentry>
|
||
|
-
|
||
|
</variablelist>
|
||
|
</para>
|
||
|
</refsect1>
|