~ubuntu-branches/ubuntu/wily/pam/wily

95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
1
Author: Stéphane Graber <stgraber@ubuntu.com>
2
Description: pam_loginuid: Ignore failure in user namespaces
3
    When running pam_loginuid in a container using the user namespaces, even
4
    uid 0 isn't allowed to set the loginuid property.
5
 .
6
    This change catches the EACCES from opening loginuid, checks if the user
7
    is in the host namespace (by comparing the uid_map with the host's one)
8
    and only if that's the case, sets rc to 1.
9
 .
10
    Should uid_map not exist or be unreadable for some reason, it'll be
11
    assumed that the process is running on the host's namespace.
12
 .
13
    The initial reason behind this change was failure to ssh into an
14
    unprivileged container (using a 3.13 kernel and current LXC) when using
15
    a standard pam profile for sshd (which requires success from
16
    pam_loginuid).
17
 .
18
    I believe this solution doesn't have any drawback and will allow people
19
    to use unprivileged containers normally. An alternative would be to have
20
    all distros set pam_loginuid as optional but that'd be bad for any of
21
    the other potential failure case which people may care about.
22
 .
23
    There has also been some discussions to get some of the audit features
24
    tied with the user namespaces but currently none of that has been merged
25
    upstream and the currently proposed implementation doesn't cover
26
    loginuid (nor is it clear how this should even work when loginuid is set
27
    as immutable after initial write).
28
 .
29
    Signed-off-by: Steve Langasek <vorlon@debian.org>
30
    Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
31
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
32
Index: ubuntu/modules/pam_loginuid/pam_loginuid.c
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
33
===================================================================
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
34
--- ubuntu.orig/modules/pam_loginuid/pam_loginuid.c	2014-01-31 21:07:08.665185675 +0000
35
+++ ubuntu/modules/pam_loginuid/pam_loginuid.c	2014-01-31 21:05:05.000000000 +0000
36
@@ -47,25 +47,56 @@
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
37
 
38
 /*
39
  * This function writes the loginuid to the /proc system. It returns
40
- * 0 on success and 1 on failure.
41
+ * PAM_SUCCESS on success,
42
+ * PAM_IGNORE when /proc/self/loginuid does not exist,
43
+ * PAM_SESSION_ERR in case of any other error.
44
  */
45
 static int set_loginuid(pam_handle_t *pamh, uid_t uid)
46
 {
47
-	int fd, count, rc = 0;
48
-	char loginuid[24];
49
+	int fd, count, rc = PAM_SESSION_ERR;
50
+	char loginuid[24], buf[24];
51
+	static const char host_uid_map[] = "         0          0 4294967295\n";
52
+	char uid_map[sizeof(host_uid_map)];
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
53
+
54
+	/* loginuid in user namespaces currently isn't writable and in some
55
+	   case, not even readable, so consider any failure as ignorable (but try
56
+	   anyway, in case we hit a kernel which supports it). */
57
+	fd = open("/proc/self/uid_map", O_RDONLY);
58
+	if (fd >= 0) {
59
+		count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
60
+		if (strncmp(uid_map, host_uid_map, count) != 0)
61
+			rc = PAM_IGNORE;
62
+		close(fd);
63
+	}
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
64
 
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
65
-	count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
66
-	fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
67
+	fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR);
68
 	if (fd < 0) {
69
-		if (errno != ENOENT) {
70
-			rc = 1;
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
71
-			pam_syslog(pamh, LOG_ERR,
72
-				   "Cannot open /proc/self/loginuid: %m");
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
73
+		if (errno == ENOENT) {
74
+			rc = PAM_IGNORE;
75
+		}
76
+		if (rc != PAM_IGNORE) {
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
77
+			pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
78
+				   "/proc/self/loginuid");
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
79
 		}
80
 		return rc;
81
 	}
82
-	if (pam_modutil_write(fd, loginuid, count) != count)
83
-		rc = 1;
84
+
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
85
+	count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
86
+	if (pam_modutil_read(fd, buf, sizeof(buf)) == count &&
87
+	    memcmp(buf, loginuid, count) == 0) {
88
+		rc = PAM_SUCCESS;
89
+		goto done;	/* already correct */
90
+	}
91
+	if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
92
+	    pam_modutil_write(fd, loginuid, count) == count) {
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
93
+		rc = PAM_SUCCESS;
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
94
+	} else {
95
+		if (rc != PAM_IGNORE) {
96
+			pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
97
+				   "/proc/self/loginuid");
98
+		}
99
+	}
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
100
+ done:
101
 	close(fd);
102
 	return rc;
103
 }
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
104
@@ -165,6 +196,7 @@
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
105
 {
106
         const char *user = NULL;
107
 	struct passwd *pwd;
108
+	int ret;
109
 #ifdef HAVE_LIBAUDIT
110
 	int require_auditd = 0;
111
 #endif
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
112
@@ -183,9 +215,14 @@
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
113
 		return PAM_SESSION_ERR;
114
 	}
115
 
116
-	if (set_loginuid(pamh, pwd->pw_uid)) {
117
-		pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n");
118
-		return PAM_SESSION_ERR;
119
+	ret = set_loginuid(pamh, pwd->pw_uid);
120
+	switch (ret) {
121
+		case PAM_SUCCESS:
122
+		case PAM_IGNORE:
123
+			break;
124
+		default:
125
+			pam_syslog(pamh, LOG_ERR, "set_loginuid failed");
126
+			return ret;
127
 	}
128
 
129
 #ifdef HAVE_LIBAUDIT
97 by Stéphane Graber
debian/patches-applied/pam-loginuid-in-containers: pam_loginuid:
130
@@ -195,11 +232,12 @@
95 by Steve Langasek
* Merge from Debian unstable, remaining changes:
131
 		argv++;
132
 	}
133
 
134
-	if (require_auditd)
135
-		return check_auditd();
136
-	else
137
+	if (require_auditd) {
138
+		int rc = check_auditd();
139
+		return rc != PAM_SUCCESS ? rc : ret;
140
+	} else
141
 #endif
142
-		return PAM_SUCCESS;
143
+		return ret;
144
 }
145
 
146
 /*