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 |
/*
|