File: | build-scan/../src/nss-systemd/nss-systemd.c |
Warning: | line 579, column 17 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <nss.h> | |||
4 | #include <pthread.h> | |||
5 | ||||
6 | #include "sd-bus.h" | |||
7 | ||||
8 | #include "alloc-util.h" | |||
9 | #include "bus-common-errors.h" | |||
10 | #include "dirent-util.h" | |||
11 | #include "env-util.h" | |||
12 | #include "fd-util.h" | |||
13 | #include "fs-util.h" | |||
14 | #include "list.h" | |||
15 | #include "macro.h" | |||
16 | #include "nss-util.h" | |||
17 | #include "signal-util.h" | |||
18 | #include "stdio-util.h" | |||
19 | #include "string-util.h" | |||
20 | #include "user-util.h" | |||
21 | #include "util.h" | |||
22 | ||||
23 | #define DYNAMIC_USER_GECOS"Dynamic User" "Dynamic User" | |||
24 | #define DYNAMIC_USER_PASSWD"*" "*" /* locked */ | |||
25 | #define DYNAMIC_USER_DIR"/" "/" | |||
26 | #define DYNAMIC_USER_SHELL"/sbin/nologin" "/sbin/nologin" | |||
27 | ||||
28 | static const struct passwd root_passwd = { | |||
29 | .pw_name = (char*) "root", | |||
30 | .pw_passwd = (char*) "x", /* see shadow file */ | |||
31 | .pw_uid = 0, | |||
32 | .pw_gid = 0, | |||
33 | .pw_gecos = (char*) "Super User", | |||
34 | .pw_dir = (char*) "/root", | |||
35 | .pw_shell = (char*) "/bin/sh", | |||
36 | }; | |||
37 | ||||
38 | static const struct passwd nobody_passwd = { | |||
39 | .pw_name = (char*) NOBODY_USER_NAME"nobody", | |||
40 | .pw_passwd = (char*) "*", /* locked */ | |||
41 | .pw_uid = UID_NOBODY((uid_t) 65534U), | |||
42 | .pw_gid = GID_NOBODY((gid_t) 65534U), | |||
43 | .pw_gecos = (char*) "User Nobody", | |||
44 | .pw_dir = (char*) "/", | |||
45 | .pw_shell = (char*) "/sbin/nologin", | |||
46 | }; | |||
47 | ||||
48 | static const struct group root_group = { | |||
49 | .gr_name = (char*) "root", | |||
50 | .gr_gid = 0, | |||
51 | .gr_passwd = (char*) "x", /* see shadow file */ | |||
52 | .gr_mem = (char*[]) { NULL((void*)0) }, | |||
53 | }; | |||
54 | ||||
55 | static const struct group nobody_group = { | |||
56 | .gr_name = (char*) NOBODY_GROUP_NAME"nobody", | |||
57 | .gr_gid = GID_NOBODY((gid_t) 65534U), | |||
58 | .gr_passwd = (char*) "*", /* locked */ | |||
59 | .gr_mem = (char*[]) { NULL((void*)0) }, | |||
60 | }; | |||
61 | ||||
62 | typedef struct UserEntry UserEntry; | |||
63 | typedef struct GetentData GetentData; | |||
64 | ||||
65 | struct UserEntry { | |||
66 | uid_t id; | |||
67 | char *name; | |||
68 | ||||
69 | GetentData *data; | |||
70 | LIST_FIELDS(UserEntry, entries)UserEntry *entries_next, *entries_prev; | |||
71 | }; | |||
72 | ||||
73 | struct GetentData { | |||
74 | /* As explained in NOTES section of getpwent_r(3) as 'getpwent_r() is not really | |||
75 | * reentrant since it shares the reading position in the stream with all other threads', | |||
76 | * we need to protect the data in UserEntry from multithreaded programs which may call | |||
77 | * setpwent(), getpwent_r(), or endpwent() simultaneously. So, each function locks the | |||
78 | * data by using the mutex below. */ | |||
79 | pthread_mutex_t mutex; | |||
80 | ||||
81 | UserEntry *position; | |||
82 | LIST_HEAD(UserEntry, entries)UserEntry *entries; | |||
83 | }; | |||
84 | ||||
85 | static GetentData getpwent_data = { PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, PTHREAD_MUTEX_TIMED_NP, 0, 0, { 0, 0 } } }, NULL((void*)0), NULL((void*)0) }; | |||
86 | static GetentData getgrent_data = { PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, PTHREAD_MUTEX_TIMED_NP, 0, 0, { 0, 0 } } }, NULL((void*)0), NULL((void*)0) }; | |||
87 | ||||
88 | NSS_GETPW_PROTOTYPES(systemd)enum nss_status _nss_systemd_getpwnam_r( const char *name, struct passwd *pwd, char *buffer, size_t buflen, int *errnop) __attribute__ ((visibility("default"))); enum nss_status _nss_systemd_getpwuid_r ( uid_t uid, struct passwd *pwd, char *buffer, size_t buflen, int *errnop) __attribute__ ((visibility("default"))); | |||
89 | NSS_GETGR_PROTOTYPES(systemd)enum nss_status _nss_systemd_getgrnam_r( const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop) __attribute__ ((visibility("default"))); enum nss_status _nss_systemd_getgrgid_r ( gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop) __attribute__ ((visibility("default"))); | |||
90 | enum nss_status _nss_systemd_endpwent(void) _public___attribute__ ((visibility("default"))); | |||
91 | enum nss_status _nss_systemd_setpwent(int stayopen) _public___attribute__ ((visibility("default"))); | |||
92 | enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, size_t buflen, int *errnop) _public___attribute__ ((visibility("default"))); | |||
93 | enum nss_status _nss_systemd_endgrent(void) _public___attribute__ ((visibility("default"))); | |||
94 | enum nss_status _nss_systemd_setgrent(int stayopen) _public___attribute__ ((visibility("default"))); | |||
95 | enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size_t buflen, int *errnop) _public___attribute__ ((visibility("default"))); | |||
96 | ||||
97 | static int direct_lookup_name(const char *name, uid_t *ret) { | |||
98 | _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0); | |||
99 | const char *path; | |||
100 | int r; | |||
101 | ||||
102 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/nss-systemd/nss-systemd.c" , 102, __PRETTY_FUNCTION__); } while (0); | |||
103 | ||||
104 | /* Normally, we go via the bus to resolve names. That has the benefit that it is available from any mount | |||
105 | * namespace and subject to proper authentication. However, there's one problem: if our module is called from | |||
106 | * dbus-daemon itself we really can't use D-Bus to communicate. In this case, resort to a client-side hack, | |||
107 | * and look for the dynamic names directly. This is pretty ugly, but breaks the cyclic dependency. */ | |||
108 | ||||
109 | path = strjoina("/run/systemd/dynamic-uid/direct:", name)({ const char *_appendees_[] = { "/run/systemd/dynamic-uid/direct:" , name }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for ( _i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
110 | r = readlink_malloc(path, &s); | |||
111 | if (r < 0) | |||
112 | return r; | |||
113 | ||||
114 | return parse_uid(s, ret); | |||
115 | } | |||
116 | ||||
117 | static int direct_lookup_uid(uid_t uid, char **ret) { | |||
118 | char path[STRLEN("/run/systemd/dynamic-uid/direct:")(sizeof("""/run/systemd/dynamic-uid/direct:""") - 1) + DECIMAL_STR_MAX(uid_t)(2+(sizeof(uid_t) <= 1 ? 3 : sizeof(uid_t) <= 2 ? 5 : sizeof (uid_t) <= 4 ? 10 : sizeof(uid_t) <= 8 ? 20 : sizeof(int [-2*(sizeof(uid_t) > 8)]))) + 1], *s; | |||
119 | int r; | |||
120 | ||||
121 | xsprintf(path, "/run/systemd/dynamic-uid/direct:" UID_FMT, uid)do { if ((__builtin_expect(!!(!(((size_t) snprintf(path, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (path), typeof(&*(path))), sizeof(path)/sizeof((path)[0]) , ((void)0))), "/run/systemd/dynamic-uid/direct:" "%" "u", uid ) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(path), typeof(&*(path))), sizeof(path)/sizeof((path )[0]), ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "path" "[] must be big enough"), "../src/nss-systemd/nss-systemd.c" , 121, __PRETTY_FUNCTION__); } while (0); | |||
122 | ||||
123 | r = readlink_malloc(path, &s); | |||
124 | if (r < 0) | |||
125 | return r; | |||
126 | if (!valid_user_group_name(s, VALID_USER_RELAX)) { /* extra safety check */ | |||
127 | free(s); | |||
128 | return -EINVAL22; | |||
129 | } | |||
130 | ||||
131 | *ret = s; | |||
132 | return 0; | |||
133 | } | |||
134 | ||||
135 | enum nss_status _nss_systemd_getpwnam_r( | |||
136 | const char *name, | |||
137 | struct passwd *pwd, | |||
138 | char *buffer, size_t buflen, | |||
139 | int *errnop) { | |||
140 | ||||
141 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
142 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message* reply = NULL((void*)0); | |||
143 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); | |||
144 | uint32_t translated; | |||
145 | size_t l; | |||
146 | int bypass, r; | |||
147 | ||||
148 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
149 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 149, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
150 | ||||
151 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/nss-systemd/nss-systemd.c" , 151, __PRETTY_FUNCTION__); } while (0); | |||
152 | assert(pwd)do { if ((__builtin_expect(!!(!(pwd)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("pwd"), "../src/nss-systemd/nss-systemd.c" , 152, __PRETTY_FUNCTION__); } while (0); | |||
153 | ||||
154 | /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't | |||
155 | * generate EINVAL here, because it isn't really out business to complain about invalid user names. */ | |||
156 | if (!valid_user_group_name(name, VALID_USER_RELAX)) | |||
157 | return NSS_STATUS_NOTFOUND; | |||
158 | ||||
159 | /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */ | |||
160 | if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { | |||
161 | if (streq(name, root_passwd.pw_name)(strcmp((name),(root_passwd.pw_name)) == 0)) { | |||
162 | *pwd = root_passwd; | |||
163 | return NSS_STATUS_SUCCESS; | |||
164 | } | |||
165 | if (synthesize_nobody() && | |||
166 | streq(name, nobody_passwd.pw_name)(strcmp((name),(nobody_passwd.pw_name)) == 0)) { | |||
167 | *pwd = nobody_passwd; | |||
168 | return NSS_STATUS_SUCCESS; | |||
169 | } | |||
170 | } | |||
171 | ||||
172 | /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */ | |||
173 | if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) | |||
174 | return NSS_STATUS_NOTFOUND; | |||
175 | ||||
176 | bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); | |||
177 | if (bypass <= 0) { | |||
178 | r = sd_bus_open_system(&bus); | |||
179 | if (r < 0) | |||
180 | bypass = 1; | |||
181 | } | |||
182 | ||||
183 | if (bypass > 0) { | |||
184 | r = direct_lookup_name(name, (uid_t*) &translated); | |||
185 | if (r == -ENOENT2) | |||
186 | return NSS_STATUS_NOTFOUND; | |||
187 | if (r < 0) | |||
188 | goto fail; | |||
189 | } else { | |||
190 | r = sd_bus_call_method(bus, | |||
191 | "org.freedesktop.systemd1", | |||
192 | "/org/freedesktop/systemd1", | |||
193 | "org.freedesktop.systemd1.Manager", | |||
194 | "LookupDynamicUserByName", | |||
195 | &error, | |||
196 | &reply, | |||
197 | "s", | |||
198 | name); | |||
199 | if (r < 0) { | |||
200 | if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER"org.freedesktop.systemd1.NoSuchDynamicUser")) | |||
201 | return NSS_STATUS_NOTFOUND; | |||
202 | ||||
203 | goto fail; | |||
204 | } | |||
205 | ||||
206 | r = sd_bus_message_read(reply, "u", &translated); | |||
207 | if (r < 0) | |||
208 | goto fail; | |||
209 | } | |||
210 | ||||
211 | l = strlen(name); | |||
212 | if (buflen < l+1) { | |||
213 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
214 | *errnop = ERANGE34; | |||
215 | return NSS_STATUS_TRYAGAIN; | |||
216 | } | |||
217 | ||||
218 | memcpy(buffer, name, l+1); | |||
219 | ||||
220 | pwd->pw_name = buffer; | |||
221 | pwd->pw_uid = (uid_t) translated; | |||
222 | pwd->pw_gid = (uid_t) translated; | |||
223 | pwd->pw_gecos = (char*) DYNAMIC_USER_GECOS"Dynamic User"; | |||
224 | pwd->pw_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
225 | pwd->pw_dir = (char*) DYNAMIC_USER_DIR"/"; | |||
226 | pwd->pw_shell = (char*) DYNAMIC_USER_SHELL"/sbin/nologin"; | |||
227 | ||||
228 | return NSS_STATUS_SUCCESS; | |||
229 | ||||
230 | fail: | |||
231 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
232 | *errnop = -r; | |||
233 | return NSS_STATUS_UNAVAIL; | |||
234 | } | |||
235 | ||||
236 | enum nss_status _nss_systemd_getpwuid_r( | |||
237 | uid_t uid, | |||
238 | struct passwd *pwd, | |||
239 | char *buffer, size_t buflen, | |||
240 | int *errnop) { | |||
241 | ||||
242 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
243 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message* reply = NULL((void*)0); | |||
244 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); | |||
245 | _cleanup_free___attribute__((cleanup(freep))) char *direct = NULL((void*)0); | |||
246 | const char *translated; | |||
247 | size_t l; | |||
248 | int bypass, r; | |||
249 | ||||
250 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
251 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 251, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
252 | ||||
253 | if (!uid_is_valid(uid)) | |||
254 | return NSS_STATUS_NOTFOUND; | |||
255 | ||||
256 | /* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */ | |||
257 | if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { | |||
258 | if (uid == root_passwd.pw_uid) { | |||
259 | *pwd = root_passwd; | |||
260 | return NSS_STATUS_SUCCESS; | |||
261 | } | |||
262 | if (synthesize_nobody() && | |||
263 | uid == nobody_passwd.pw_uid) { | |||
264 | *pwd = nobody_passwd; | |||
265 | return NSS_STATUS_SUCCESS; | |||
266 | } | |||
267 | } | |||
268 | ||||
269 | if (!uid_is_dynamic(uid)) | |||
270 | return NSS_STATUS_NOTFOUND; | |||
271 | ||||
272 | if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) | |||
273 | return NSS_STATUS_NOTFOUND; | |||
274 | ||||
275 | bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); | |||
276 | if (bypass <= 0) { | |||
277 | r = sd_bus_open_system(&bus); | |||
278 | if (r < 0) | |||
279 | bypass = 1; | |||
280 | } | |||
281 | ||||
282 | if (bypass > 0) { | |||
283 | r = direct_lookup_uid(uid, &direct); | |||
284 | if (r == -ENOENT2) | |||
285 | return NSS_STATUS_NOTFOUND; | |||
286 | if (r < 0) | |||
287 | goto fail; | |||
288 | ||||
289 | translated = direct; | |||
290 | ||||
291 | } else { | |||
292 | r = sd_bus_call_method(bus, | |||
293 | "org.freedesktop.systemd1", | |||
294 | "/org/freedesktop/systemd1", | |||
295 | "org.freedesktop.systemd1.Manager", | |||
296 | "LookupDynamicUserByUID", | |||
297 | &error, | |||
298 | &reply, | |||
299 | "u", | |||
300 | (uint32_t) uid); | |||
301 | if (r < 0) { | |||
302 | if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER"org.freedesktop.systemd1.NoSuchDynamicUser")) | |||
303 | return NSS_STATUS_NOTFOUND; | |||
304 | ||||
305 | goto fail; | |||
306 | } | |||
307 | ||||
308 | r = sd_bus_message_read(reply, "s", &translated); | |||
309 | if (r < 0) | |||
310 | goto fail; | |||
311 | } | |||
312 | ||||
313 | l = strlen(translated) + 1; | |||
314 | if (buflen < l) { | |||
315 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
316 | *errnop = ERANGE34; | |||
317 | return NSS_STATUS_TRYAGAIN; | |||
318 | } | |||
319 | ||||
320 | memcpy(buffer, translated, l); | |||
321 | ||||
322 | pwd->pw_name = buffer; | |||
323 | pwd->pw_uid = uid; | |||
324 | pwd->pw_gid = uid; | |||
325 | pwd->pw_gecos = (char*) DYNAMIC_USER_GECOS"Dynamic User"; | |||
326 | pwd->pw_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
327 | pwd->pw_dir = (char*) DYNAMIC_USER_DIR"/"; | |||
328 | pwd->pw_shell = (char*) DYNAMIC_USER_SHELL"/sbin/nologin"; | |||
329 | ||||
330 | return NSS_STATUS_SUCCESS; | |||
331 | ||||
332 | fail: | |||
333 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
334 | *errnop = -r; | |||
335 | return NSS_STATUS_UNAVAIL; | |||
336 | } | |||
337 | ||||
338 | #pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess" | |||
339 | ||||
340 | enum nss_status _nss_systemd_getgrnam_r( | |||
341 | const char *name, | |||
342 | struct group *gr, | |||
343 | char *buffer, size_t buflen, | |||
344 | int *errnop) { | |||
345 | ||||
346 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
347 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message* reply = NULL((void*)0); | |||
348 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); | |||
349 | uint32_t translated; | |||
350 | size_t l; | |||
351 | int bypass, r; | |||
352 | ||||
353 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
354 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 354, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
355 | ||||
356 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/nss-systemd/nss-systemd.c" , 356, __PRETTY_FUNCTION__); } while (0); | |||
357 | assert(gr)do { if ((__builtin_expect(!!(!(gr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("gr"), "../src/nss-systemd/nss-systemd.c" , 357, __PRETTY_FUNCTION__); } while (0); | |||
358 | ||||
359 | if (!valid_user_group_name(name, VALID_USER_RELAX)) | |||
360 | return NSS_STATUS_NOTFOUND; | |||
361 | ||||
362 | /* Synthesize records for root and nobody, in case they are missing form /etc/group */ | |||
363 | if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { | |||
364 | if (streq(name, root_group.gr_name)(strcmp((name),(root_group.gr_name)) == 0)) { | |||
365 | *gr = root_group; | |||
366 | return NSS_STATUS_SUCCESS; | |||
367 | } | |||
368 | if (synthesize_nobody() && | |||
369 | streq(name, nobody_group.gr_name)(strcmp((name),(nobody_group.gr_name)) == 0)) { | |||
370 | *gr = nobody_group; | |||
371 | return NSS_STATUS_SUCCESS; | |||
372 | } | |||
373 | } | |||
374 | ||||
375 | if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) | |||
376 | return NSS_STATUS_NOTFOUND; | |||
377 | ||||
378 | bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); | |||
379 | if (bypass <= 0) { | |||
380 | r = sd_bus_open_system(&bus); | |||
381 | if (r < 0) | |||
382 | bypass = 1; | |||
383 | } | |||
384 | ||||
385 | if (bypass > 0) { | |||
386 | r = direct_lookup_name(name, (uid_t*) &translated); | |||
387 | if (r == -ENOENT2) | |||
388 | return NSS_STATUS_NOTFOUND; | |||
389 | if (r < 0) | |||
390 | goto fail; | |||
391 | } else { | |||
392 | r = sd_bus_call_method(bus, | |||
393 | "org.freedesktop.systemd1", | |||
394 | "/org/freedesktop/systemd1", | |||
395 | "org.freedesktop.systemd1.Manager", | |||
396 | "LookupDynamicUserByName", | |||
397 | &error, | |||
398 | &reply, | |||
399 | "s", | |||
400 | name); | |||
401 | if (r < 0) { | |||
402 | if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER"org.freedesktop.systemd1.NoSuchDynamicUser")) | |||
403 | return NSS_STATUS_NOTFOUND; | |||
404 | ||||
405 | goto fail; | |||
406 | } | |||
407 | ||||
408 | r = sd_bus_message_read(reply, "u", &translated); | |||
409 | if (r < 0) | |||
410 | goto fail; | |||
411 | } | |||
412 | ||||
413 | l = sizeof(char*) + strlen(name) + 1; | |||
414 | if (buflen < l) { | |||
415 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
416 | *errnop = ERANGE34; | |||
417 | return NSS_STATUS_TRYAGAIN; | |||
418 | } | |||
419 | ||||
420 | memzero(buffer, sizeof(char*))({ size_t _l_ = (sizeof(char*)); void *_x_ = (buffer); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); }); | |||
421 | strcpy(buffer + sizeof(char*), name); | |||
422 | ||||
423 | gr->gr_name = buffer + sizeof(char*); | |||
424 | gr->gr_gid = (gid_t) translated; | |||
425 | gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
426 | gr->gr_mem = (char**) buffer; | |||
427 | ||||
428 | return NSS_STATUS_SUCCESS; | |||
429 | ||||
430 | fail: | |||
431 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
432 | *errnop = -r; | |||
433 | return NSS_STATUS_UNAVAIL; | |||
434 | } | |||
435 | ||||
436 | enum nss_status _nss_systemd_getgrgid_r( | |||
437 | gid_t gid, | |||
438 | struct group *gr, | |||
439 | char *buffer, size_t buflen, | |||
440 | int *errnop) { | |||
441 | ||||
442 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
443 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message* reply = NULL((void*)0); | |||
444 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); | |||
445 | _cleanup_free___attribute__((cleanup(freep))) char *direct = NULL((void*)0); | |||
446 | const char *translated; | |||
447 | size_t l; | |||
448 | int bypass, r; | |||
449 | ||||
450 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
451 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 451, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
452 | ||||
453 | if (!gid_is_valid(gid)) | |||
454 | return NSS_STATUS_NOTFOUND; | |||
455 | ||||
456 | /* Synthesize records for root and nobody, in case they are missing from /etc/group */ | |||
457 | if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) { | |||
458 | if (gid == root_group.gr_gid) { | |||
459 | *gr = root_group; | |||
460 | return NSS_STATUS_SUCCESS; | |||
461 | } | |||
462 | if (synthesize_nobody() && | |||
463 | gid == nobody_group.gr_gid) { | |||
464 | *gr = nobody_group; | |||
465 | return NSS_STATUS_SUCCESS; | |||
466 | } | |||
467 | } | |||
468 | ||||
469 | if (!gid_is_dynamic(gid)) | |||
470 | return NSS_STATUS_NOTFOUND; | |||
471 | ||||
472 | if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) | |||
473 | return NSS_STATUS_NOTFOUND; | |||
474 | ||||
475 | bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); | |||
476 | if (bypass <= 0) { | |||
477 | r = sd_bus_open_system(&bus); | |||
478 | if (r < 0) | |||
479 | bypass = 1; | |||
480 | } | |||
481 | ||||
482 | if (bypass > 0) { | |||
483 | r = direct_lookup_uid(gid, &direct); | |||
484 | if (r == -ENOENT2) | |||
485 | return NSS_STATUS_NOTFOUND; | |||
486 | if (r < 0) | |||
487 | goto fail; | |||
488 | ||||
489 | translated = direct; | |||
490 | ||||
491 | } else { | |||
492 | r = sd_bus_call_method(bus, | |||
493 | "org.freedesktop.systemd1", | |||
494 | "/org/freedesktop/systemd1", | |||
495 | "org.freedesktop.systemd1.Manager", | |||
496 | "LookupDynamicUserByUID", | |||
497 | &error, | |||
498 | &reply, | |||
499 | "u", | |||
500 | (uint32_t) gid); | |||
501 | if (r < 0) { | |||
502 | if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER"org.freedesktop.systemd1.NoSuchDynamicUser")) | |||
503 | return NSS_STATUS_NOTFOUND; | |||
504 | ||||
505 | goto fail; | |||
506 | } | |||
507 | ||||
508 | r = sd_bus_message_read(reply, "s", &translated); | |||
509 | if (r < 0) | |||
510 | goto fail; | |||
511 | } | |||
512 | ||||
513 | l = sizeof(char*) + strlen(translated) + 1; | |||
514 | if (buflen < l) { | |||
515 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
516 | *errnop = ERANGE34; | |||
517 | return NSS_STATUS_TRYAGAIN; | |||
518 | } | |||
519 | ||||
520 | memzero(buffer, sizeof(char*))({ size_t _l_ = (sizeof(char*)); void *_x_ = (buffer); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); }); | |||
521 | strcpy(buffer + sizeof(char*), translated); | |||
522 | ||||
523 | gr->gr_name = buffer + sizeof(char*); | |||
524 | gr->gr_gid = gid; | |||
525 | gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
526 | gr->gr_mem = (char**) buffer; | |||
527 | ||||
528 | return NSS_STATUS_SUCCESS; | |||
529 | ||||
530 | fail: | |||
531 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
532 | *errnop = -r; | |||
533 | return NSS_STATUS_UNAVAIL; | |||
534 | } | |||
535 | ||||
536 | static void user_entry_free(UserEntry *p) { | |||
537 | if (!p
| |||
538 | return; | |||
539 | ||||
540 | if (p->data) | |||
541 | LIST_REMOVE(entries, p->data->entries, p)do { typeof(*(p->data->entries)) **_head = &(p-> data->entries), *_item = (p); do { if ((__builtin_expect(! !(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "_item"), "../src/nss-systemd/nss-systemd.c", 541, __PRETTY_FUNCTION__ ); } while (0); if (_item->entries_next) _item->entries_next ->entries_prev = _item->entries_prev; if (_item->entries_prev ) _item->entries_prev->entries_next = _item->entries_next ; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0) )) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item" ), "../src/nss-systemd/nss-systemd.c", 541, __PRETTY_FUNCTION__ ); } while (0); *_head = _item->entries_next; } _item-> entries_next = _item->entries_prev = ((void*)0); } while ( 0); | |||
542 | ||||
543 | free(p->name); | |||
544 | free(p); | |||
545 | } | |||
546 | ||||
547 | static int user_entry_add(GetentData *data, const char *name, uid_t id) { | |||
548 | UserEntry *p; | |||
549 | ||||
550 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/nss-systemd/nss-systemd.c" , 550, __PRETTY_FUNCTION__); } while (0); | |||
551 | ||||
552 | /* This happens when User= or Group= already exists statically. */ | |||
553 | if (!uid_is_dynamic(id)) | |||
554 | return -EINVAL22; | |||
555 | ||||
556 | p = new0(UserEntry, 1)((UserEntry*) calloc((1), sizeof(UserEntry))); | |||
557 | if (!p) | |||
558 | return -ENOMEM12; | |||
559 | ||||
560 | p->name = strdup(name); | |||
561 | if (!p->name) { | |||
562 | free(p); | |||
563 | return -ENOMEM12; | |||
564 | } | |||
565 | p->id = id; | |||
566 | p->data = data; | |||
567 | ||||
568 | LIST_PREPEND(entries, data->entries, p)do { typeof(*(data->entries)) **_head = &(data->entries ), *_item = (p); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/nss-systemd/nss-systemd.c" , 568, __PRETTY_FUNCTION__); } while (0); if ((_item->entries_next = *_head)) _item->entries_next->entries_prev = _item; _item ->entries_prev = ((void*)0); *_head = _item; } while (0); | |||
569 | ||||
570 | return 0; | |||
571 | } | |||
572 | ||||
573 | static void systemd_endent(GetentData *data) { | |||
574 | UserEntry *p; | |||
575 | ||||
576 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/nss-systemd/nss-systemd.c" , 576, __PRETTY_FUNCTION__); } while (0); | |||
577 | ||||
578 | while ((p = data->entries)) | |||
579 | user_entry_free(p); | |||
| ||||
580 | ||||
581 | data->position = NULL((void*)0); | |||
582 | } | |||
583 | ||||
584 | static enum nss_status nss_systemd_endent(GetentData *p) { | |||
585 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
586 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 586, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
587 | ||||
588 | assert_se(pthread_mutex_lock(&p->mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_lock(&p-> mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("pthread_mutex_lock(&p->mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 588, __PRETTY_FUNCTION__); } while (0); | |||
589 | systemd_endent(p); | |||
590 | assert_se(pthread_mutex_unlock(&p->mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_unlock(&p-> mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("pthread_mutex_unlock(&p->mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 590, __PRETTY_FUNCTION__); } while (0); | |||
591 | ||||
592 | return NSS_STATUS_SUCCESS; | |||
593 | } | |||
594 | ||||
595 | enum nss_status _nss_systemd_endpwent(void) { | |||
596 | return nss_systemd_endent(&getpwent_data); | |||
597 | } | |||
598 | ||||
599 | enum nss_status _nss_systemd_endgrent(void) { | |||
600 | return nss_systemd_endent(&getgrent_data); | |||
601 | } | |||
602 | ||||
603 | static int direct_enumeration(GetentData *p) { | |||
604 | _cleanup_closedir___attribute__((cleanup(closedirp))) DIR *d = NULL((void*)0); | |||
605 | struct dirent *de; | |||
606 | int r; | |||
607 | ||||
608 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/nss-systemd/nss-systemd.c" , 608, __PRETTY_FUNCTION__); } while (0); | |||
609 | ||||
610 | d = opendir("/run/systemd/dynamic-uid/"); | |||
611 | if (!d) | |||
612 | return -errno(*__errno_location ()); | |||
613 | ||||
614 | FOREACH_DIRENT(de, d, return -errno)for ((*__errno_location ()) = 0, de = readdir(d);; (*__errno_location ()) = 0, de = readdir(d)) if (!de) { if ((*__errno_location ( )) > 0) { return -(*__errno_location ()); } break; } else if (hidden_or_backup_file((de)->d_name)) continue; else { | |||
615 | _cleanup_free___attribute__((cleanup(freep))) char *name = NULL((void*)0); | |||
616 | uid_t uid, verified; | |||
617 | ||||
618 | if (!dirent_is_file(de)) | |||
619 | continue; | |||
620 | ||||
621 | r = parse_uid(de->d_name, &uid); | |||
622 | if (r < 0) | |||
623 | continue; | |||
624 | ||||
625 | r = direct_lookup_uid(uid, &name); | |||
626 | if (r == -ENOMEM12) | |||
627 | return r; | |||
628 | if (r < 0) | |||
629 | continue; | |||
630 | ||||
631 | r = direct_lookup_name(name, &verified); | |||
632 | if (r < 0) | |||
633 | continue; | |||
634 | ||||
635 | if (uid != verified) | |||
636 | continue; | |||
637 | ||||
638 | r = user_entry_add(p, name, uid); | |||
639 | if (r == -ENOMEM12) | |||
640 | return r; | |||
641 | if (r < 0) | |||
642 | continue; | |||
643 | } | |||
644 | ||||
645 | return 0; | |||
646 | } | |||
647 | ||||
648 | static enum nss_status systemd_setent(GetentData *p) { | |||
649 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
650 | _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message* reply = NULL((void*)0); | |||
651 | _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0); | |||
652 | const char *name; | |||
653 | uid_t id; | |||
654 | int bypass, r; | |||
655 | ||||
656 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
657 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 657, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
658 | ||||
659 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/nss-systemd/nss-systemd.c" , 659, __PRETTY_FUNCTION__); } while (0); | |||
660 | ||||
661 | assert_se(pthread_mutex_lock(&p->mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_lock(&p-> mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("pthread_mutex_lock(&p->mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 661, __PRETTY_FUNCTION__); } while (0); | |||
662 | ||||
663 | systemd_endent(p); | |||
664 | ||||
665 | if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0) | |||
666 | goto finish; | |||
667 | ||||
668 | bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS"); | |||
669 | ||||
670 | if (bypass <= 0) { | |||
671 | r = sd_bus_open_system(&bus); | |||
672 | if (r < 0) | |||
673 | bypass = 1; | |||
674 | } | |||
675 | ||||
676 | if (bypass > 0) { | |||
677 | r = direct_enumeration(p); | |||
678 | if (r < 0) | |||
679 | goto fail; | |||
680 | ||||
681 | goto finish; | |||
682 | } | |||
683 | ||||
684 | r = sd_bus_call_method(bus, | |||
685 | "org.freedesktop.systemd1", | |||
686 | "/org/freedesktop/systemd1", | |||
687 | "org.freedesktop.systemd1.Manager", | |||
688 | "GetDynamicUsers", | |||
689 | &error, | |||
690 | &reply, | |||
691 | NULL((void*)0)); | |||
692 | if (r < 0) | |||
693 | goto fail; | |||
694 | ||||
695 | r = sd_bus_message_enter_container(reply, 'a', "(us)"); | |||
696 | if (r < 0) | |||
697 | goto fail; | |||
698 | ||||
699 | while ((r = sd_bus_message_read(reply, "(us)", &id, &name)) > 0) { | |||
700 | r = user_entry_add(p, name, id); | |||
701 | if (r == -ENOMEM12) | |||
702 | goto fail; | |||
703 | if (r < 0) | |||
704 | continue; | |||
705 | } | |||
706 | if (r < 0) | |||
707 | goto fail; | |||
708 | ||||
709 | r = sd_bus_message_exit_container(reply); | |||
710 | if (r < 0) | |||
711 | goto fail; | |||
712 | ||||
713 | finish: | |||
714 | p->position = p->entries; | |||
715 | assert_se(pthread_mutex_unlock(&p->mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_unlock(&p-> mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("pthread_mutex_unlock(&p->mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 715, __PRETTY_FUNCTION__); } while (0); | |||
716 | ||||
717 | return NSS_STATUS_SUCCESS; | |||
718 | ||||
719 | fail: | |||
720 | systemd_endent(p); | |||
721 | assert_se(pthread_mutex_unlock(&p->mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_unlock(&p-> mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("pthread_mutex_unlock(&p->mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 721, __PRETTY_FUNCTION__); } while (0); | |||
722 | ||||
723 | return NSS_STATUS_UNAVAIL; | |||
724 | } | |||
725 | ||||
726 | enum nss_status _nss_systemd_setpwent(int stayopen) { | |||
727 | return systemd_setent(&getpwent_data); | |||
728 | } | |||
729 | ||||
730 | enum nss_status _nss_systemd_setgrent(int stayopen) { | |||
731 | return systemd_setent(&getgrent_data); | |||
| ||||
732 | } | |||
733 | ||||
734 | enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, size_t buflen, int *errnop) { | |||
735 | enum nss_status ret; | |||
736 | UserEntry *p; | |||
737 | size_t len; | |||
738 | ||||
739 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
740 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 740, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
741 | ||||
742 | assert(result)do { if ((__builtin_expect(!!(!(result)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("result"), "../src/nss-systemd/nss-systemd.c" , 742, __PRETTY_FUNCTION__); } while (0); | |||
743 | assert(buffer)do { if ((__builtin_expect(!!(!(buffer)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("buffer"), "../src/nss-systemd/nss-systemd.c" , 743, __PRETTY_FUNCTION__); } while (0); | |||
744 | assert(errnop)do { if ((__builtin_expect(!!(!(errnop)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("errnop"), "../src/nss-systemd/nss-systemd.c" , 744, __PRETTY_FUNCTION__); } while (0); | |||
745 | ||||
746 | assert_se(pthread_mutex_lock(&getpwent_data.mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_lock(&getpwent_data .mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("pthread_mutex_lock(&getpwent_data.mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 746, __PRETTY_FUNCTION__); } while (0); | |||
747 | ||||
748 | LIST_FOREACH(entries, p, getpwent_data.position)for ((p) = (getpwent_data.position); (p); (p) = (p)->entries_next ) { | |||
749 | len = strlen(p->name) + 1; | |||
750 | if (buflen < len) { | |||
751 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
752 | *errnop = ERANGE34; | |||
753 | ret = NSS_STATUS_TRYAGAIN; | |||
754 | goto finalize; | |||
755 | } | |||
756 | ||||
757 | memcpy(buffer, p->name, len); | |||
758 | ||||
759 | result->pw_name = buffer; | |||
760 | result->pw_uid = p->id; | |||
761 | result->pw_gid = p->id; | |||
762 | result->pw_gecos = (char*) DYNAMIC_USER_GECOS"Dynamic User"; | |||
763 | result->pw_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
764 | result->pw_dir = (char*) DYNAMIC_USER_DIR"/"; | |||
765 | result->pw_shell = (char*) DYNAMIC_USER_SHELL"/sbin/nologin"; | |||
766 | break; | |||
767 | } | |||
768 | if (!p) { | |||
769 | ret = NSS_STATUS_NOTFOUND; | |||
770 | goto finalize; | |||
771 | } | |||
772 | ||||
773 | /* On success, step to the next entry. */ | |||
774 | p = p->entries_next; | |||
775 | ret = NSS_STATUS_SUCCESS; | |||
776 | ||||
777 | finalize: | |||
778 | /* Save position for the next call. */ | |||
779 | getpwent_data.position = p; | |||
780 | ||||
781 | assert_se(pthread_mutex_unlock(&getpwent_data.mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_unlock(&getpwent_data .mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("pthread_mutex_unlock(&getpwent_data.mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 781, __PRETTY_FUNCTION__); } while (0); | |||
782 | ||||
783 | return ret; | |||
784 | } | |||
785 | ||||
786 | enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size_t buflen, int *errnop) { | |||
787 | enum nss_status ret; | |||
788 | UserEntry *p; | |||
789 | size_t len; | |||
790 | ||||
791 | PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused )) int _saved_errno_ = (*__errno_location ()); | |||
792 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK)__attribute__((cleanup(block_signals_reset))) __attribute__ ( (unused)) sigset_t _saved_sigset = ({ sigset_t _t; do { if (( __builtin_expect(!!(!(sigprocmask_many(0, &_t, 14,26,13,17 ,20,29,1,10,12,27,23,28, -1) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sigprocmask_many(SIG_BLOCK, &_t, 14,26,13,17,20,29,1,10,12,27,23,28, -1) >= 0" ), "../src/nss-systemd/nss-systemd.c", 792, __PRETTY_FUNCTION__ ); } while (0); _t; }); | |||
793 | ||||
794 | assert(result)do { if ((__builtin_expect(!!(!(result)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("result"), "../src/nss-systemd/nss-systemd.c" , 794, __PRETTY_FUNCTION__); } while (0); | |||
795 | assert(buffer)do { if ((__builtin_expect(!!(!(buffer)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("buffer"), "../src/nss-systemd/nss-systemd.c" , 795, __PRETTY_FUNCTION__); } while (0); | |||
796 | assert(errnop)do { if ((__builtin_expect(!!(!(errnop)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("errnop"), "../src/nss-systemd/nss-systemd.c" , 796, __PRETTY_FUNCTION__); } while (0); | |||
797 | ||||
798 | assert_se(pthread_mutex_lock(&getgrent_data.mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_lock(&getgrent_data .mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("pthread_mutex_lock(&getgrent_data.mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 798, __PRETTY_FUNCTION__); } while (0); | |||
799 | ||||
800 | LIST_FOREACH(entries, p, getgrent_data.position)for ((p) = (getgrent_data.position); (p); (p) = (p)->entries_next ) { | |||
801 | len = sizeof(char*) + strlen(p->name) + 1; | |||
802 | if (buflen < len) { | |||
803 | UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = - 1; } while (0); | |||
804 | *errnop = ERANGE34; | |||
805 | ret = NSS_STATUS_TRYAGAIN; | |||
806 | goto finalize; | |||
807 | } | |||
808 | ||||
809 | memzero(buffer, sizeof(char*))({ size_t _l_ = (sizeof(char*)); void *_x_ = (buffer); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); }); | |||
810 | strcpy(buffer + sizeof(char*), p->name); | |||
811 | ||||
812 | result->gr_name = buffer + sizeof(char*); | |||
813 | result->gr_gid = p->id; | |||
814 | result->gr_passwd = (char*) DYNAMIC_USER_PASSWD"*"; | |||
815 | result->gr_mem = (char**) buffer; | |||
816 | break; | |||
817 | } | |||
818 | if (!p) { | |||
819 | ret = NSS_STATUS_NOTFOUND; | |||
820 | goto finalize; | |||
821 | } | |||
822 | ||||
823 | /* On success, step to the next entry. */ | |||
824 | p = p->entries_next; | |||
825 | ret = NSS_STATUS_SUCCESS; | |||
826 | ||||
827 | finalize: | |||
828 | /* Save position for the next call. */ | |||
829 | getgrent_data.position = p; | |||
830 | ||||
831 | assert_se(pthread_mutex_unlock(&getgrent_data.mutex) == 0)do { if ((__builtin_expect(!!(!(pthread_mutex_unlock(&getgrent_data .mutex) == 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("pthread_mutex_unlock(&getgrent_data.mutex) == 0"), "../src/nss-systemd/nss-systemd.c" , 831, __PRETTY_FUNCTION__); } while (0); | |||
832 | ||||
833 | return ret; | |||
834 | } |