2 This file is part of systemd.
4 Copyright 2016 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "bus-common-errors.h"
28 #include "signal-util.h"
29 #include "user-util.h"
32 NSS_GETPW_PROTOTYPES(systemd
);
33 NSS_GETGR_PROTOTYPES(systemd
);
35 enum nss_status
_nss_systemd_getpwnam_r(
38 char *buffer
, size_t buflen
,
41 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
42 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
* reply
= NULL
;
43 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
48 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK
);
53 /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
54 if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
57 r
= sd_bus_open_system(&bus
);
61 r
= sd_bus_call_method(bus
,
62 "org.freedesktop.systemd1",
63 "/org/freedesktop/systemd1",
64 "org.freedesktop.systemd1.Manager",
65 "LookupDynamicUserByName",
71 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_DYNAMIC_USER
))
77 r
= sd_bus_message_read(reply
, "u", &translated
);
84 return NSS_STATUS_TRYAGAIN
;
87 memcpy(buffer
, name
, l
+1);
89 pwd
->pw_name
= buffer
;
90 pwd
->pw_uid
= (uid_t
) translated
;
91 pwd
->pw_gid
= (uid_t
) translated
;
92 pwd
->pw_gecos
= (char*) "Dynamic User";
93 pwd
->pw_passwd
= (char*) "*"; /* locked */
94 pwd
->pw_dir
= (char*) "/";
95 pwd
->pw_shell
= (char*) "/sbin/nologin";
98 return NSS_STATUS_SUCCESS
;
102 return NSS_STATUS_NOTFOUND
;
106 return NSS_STATUS_UNAVAIL
;
109 enum nss_status
_nss_systemd_getpwuid_r(
112 char *buffer
, size_t buflen
,
115 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
116 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
* reply
= NULL
;
117 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
118 const char *translated
;
122 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK
);
124 if (!uid_is_valid(uid
)) {
129 if (uid
<= SYSTEM_UID_MAX
)
132 if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
135 r
= sd_bus_open_system(&bus
);
139 r
= sd_bus_call_method(bus
,
140 "org.freedesktop.systemd1",
141 "/org/freedesktop/systemd1",
142 "org.freedesktop.systemd1.Manager",
143 "LookupDynamicUserByUID",
149 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_DYNAMIC_USER
))
155 r
= sd_bus_message_read(reply
, "s", &translated
);
159 l
= strlen(translated
) + 1;
162 return NSS_STATUS_TRYAGAIN
;
165 memcpy(buffer
, translated
, l
);
167 pwd
->pw_name
= buffer
;
170 pwd
->pw_gecos
= (char*) "Dynamic User";
171 pwd
->pw_passwd
= (char*) "*"; /* locked */
172 pwd
->pw_dir
= (char*) "/";
173 pwd
->pw_shell
= (char*) "/sbin/nologin";
176 return NSS_STATUS_SUCCESS
;
180 return NSS_STATUS_NOTFOUND
;
184 return NSS_STATUS_UNAVAIL
;
187 enum nss_status
_nss_systemd_getgrnam_r(
190 char *buffer
, size_t buflen
,
193 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
194 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
* reply
= NULL
;
195 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
200 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK
);
205 if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
208 r
= sd_bus_open_system(&bus
);
212 r
= sd_bus_call_method(bus
,
213 "org.freedesktop.systemd1",
214 "/org/freedesktop/systemd1",
215 "org.freedesktop.systemd1.Manager",
216 "LookupDynamicUserByName",
222 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_DYNAMIC_USER
))
228 r
= sd_bus_message_read(reply
, "u", &translated
);
232 l
= sizeof(char*) + strlen(name
) + 1;
235 return NSS_STATUS_TRYAGAIN
;
238 memzero(buffer
, sizeof(char*));
239 strcpy(buffer
+ sizeof(char*), name
);
241 gr
->gr_name
= buffer
+ sizeof(char*);
242 gr
->gr_gid
= (gid_t
) translated
;
243 gr
->gr_passwd
= (char*) "*"; /* locked */
244 gr
->gr_mem
= (char**) buffer
;
247 return NSS_STATUS_SUCCESS
;
251 return NSS_STATUS_NOTFOUND
;
255 return NSS_STATUS_UNAVAIL
;
258 enum nss_status
_nss_systemd_getgrgid_r(
261 char *buffer
, size_t buflen
,
264 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
265 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
* reply
= NULL
;
266 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
267 const char *translated
;
271 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK
);
273 if (!gid_is_valid(gid
)) {
278 if (gid
<= SYSTEM_GID_MAX
)
281 if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
284 r
= sd_bus_open_system(&bus
);
288 r
= sd_bus_call_method(bus
,
289 "org.freedesktop.systemd1",
290 "/org/freedesktop/systemd1",
291 "org.freedesktop.systemd1.Manager",
292 "LookupDynamicUserByUID",
298 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_DYNAMIC_USER
))
304 r
= sd_bus_message_read(reply
, "s", &translated
);
308 l
= sizeof(char*) + strlen(translated
) + 1;
311 return NSS_STATUS_TRYAGAIN
;
314 memzero(buffer
, sizeof(char*));
315 strcpy(buffer
+ sizeof(char*), translated
);
317 gr
->gr_name
= buffer
+ sizeof(char*);
319 gr
->gr_passwd
= (char*) "*"; /* locked */
320 gr
->gr_mem
= (char**) buffer
;
323 return NSS_STATUS_SUCCESS
;
327 return NSS_STATUS_NOTFOUND
;
331 return NSS_STATUS_UNAVAIL
;