]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/nss-mymachines/nss-mymachines.c
nss: drop dummy setup_logging() helpers
[thirdparty/systemd.git] / src / nss-mymachines / nss-mymachines.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
cabb0bc6 2
cabb0bc6 3#include <netdb.h>
07630cea 4#include <nss.h>
e5d5edc3 5#include <pthread.h>
cabb0bc6
LP
6
7#include "sd-bus.h"
8#include "sd-login.h"
07630cea 9
b5efdb8a 10#include "alloc-util.h"
c01ff965 11#include "bus-common-errors.h"
9b71e4ab 12#include "bus-locator.h"
6e32c03e 13#include "env-util.h"
2b2fec7d 14#include "errno-util.h"
ca78ad1d 15#include "format-util.h"
25300b5a 16#include "hostname-util.h"
07630cea 17#include "in-addr-util.h"
e5d5edc3 18#include "log.h"
07630cea 19#include "macro.h"
0a970718 20#include "memory-util.h"
07630cea 21#include "nss-util.h"
0c5eb056 22#include "signal-util.h"
07630cea 23#include "string-util.h"
cabb0bc6 24
e5d5edc3
ZJS
25static void setup_logging_once(void) {
26 static pthread_once_t once = PTHREAD_ONCE_INIT;
56a5f496 27 assert_se(pthread_once(&once, log_parse_environment) == 0);
e5d5edc3
ZJS
28}
29
30#define NSS_ENTRYPOINT_BEGIN \
31 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); \
32 setup_logging_once()
33
cabb0bc6 34NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
c01ff965
LP
35NSS_GETPW_PROTOTYPES(mymachines);
36NSS_GETGR_PROTOTYPES(mymachines);
cabb0bc6 37
0dd25fb9 38static int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
cabb0bc6
LP
39 unsigned c = 0;
40 int r;
41
42 assert(m);
43 assert(ret);
44
3a6fb33c 45 while ((r = sd_bus_message_enter_container(m, 'r', "iay")) > 0) {
0dd25fb9 46 int family;
cabb0bc6 47
0dd25fb9 48 r = sd_bus_message_read(m, "i", &family);
cabb0bc6
LP
49 if (r < 0)
50 return r;
51
52 r = sd_bus_message_skip(m, "ay");
53 if (r < 0)
54 return r;
55
56 r = sd_bus_message_exit_container(m);
57 if (r < 0)
58 return r;
59
60 if (af != AF_UNSPEC && family != af)
61 continue;
62
313cefa1 63 c++;
cabb0bc6
LP
64 }
65 if (r < 0)
66 return r;
67
68 r = sd_bus_message_rewind(m, false);
69 if (r < 0)
70 return r;
71
72 *ret = c;
73 return 0;
74}
75
2f28018c
LP
76static bool avoid_deadlock(void) {
77
78 /* Check whether this lookup might have a chance of deadlocking because we are called from the service manager
79 * code activating systemd-machined.service. After all, we shouldn't synchronously do lookups to
80 * systemd-machined if we are required to finish before it can be started. This of course won't detect all
81 * possible dead locks of this kind, but it should work for the most obvious cases. */
82
83 if (geteuid() != 0) /* Ignore the env vars unless we are privileged. */
84 return false;
85
86 return streq_ptr(getenv("SYSTEMD_ACTIVATION_UNIT"), "systemd-machined.service") &&
87 streq_ptr(getenv("SYSTEMD_ACTIVATION_SCOPE"), "system");
88}
89
cabb0bc6
LP
90enum nss_status _nss_mymachines_gethostbyname4_r(
91 const char *name,
92 struct gaih_addrtuple **pat,
93 char *buffer, size_t buflen,
94 int *errnop, int *h_errnop,
95 int32_t *ttlp) {
96
97 struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
4afd3348
LP
98 _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
99 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
634af566 100 _cleanup_free_ int *ifindices = NULL;
cabb0bc6
LP
101 _cleanup_free_ char *class = NULL;
102 size_t l, ms, idx;
103 unsigned i = 0, c = 0;
104 char *r_name;
634af566 105 int n_ifindices, r;
cabb0bc6 106
06202b9e 107 PROTECT_ERRNO;
e5d5edc3 108 NSS_ENTRYPOINT_BEGIN;
0c5eb056 109
cabb0bc6
LP
110 assert(name);
111 assert(pat);
112 assert(buffer);
113 assert(errnop);
114 assert(h_errnop);
115
116 r = sd_machine_get_class(name, &class);
117 if (r < 0)
118 goto fail;
119 if (!streq(class, "container")) {
120 r = -ENOTTY;
121 goto fail;
122 }
123
634af566
LP
124 n_ifindices = sd_machine_get_ifindices(name, &ifindices);
125 if (n_ifindices < 0) {
126 r = n_ifindices;
cabb0bc6
LP
127 goto fail;
128 }
129
2f28018c
LP
130 if (avoid_deadlock()) {
131 r = -EDEADLK;
132 goto fail;
133 }
134
cabb0bc6
LP
135 r = sd_bus_open_system(&bus);
136 if (r < 0)
137 goto fail;
138
7b389878 139 r = bus_call_method(bus, bus_machine_mgr, "GetMachineAddresses", NULL, &reply, "s", name);
cabb0bc6
LP
140 if (r < 0)
141 goto fail;
142
0dd25fb9 143 r = sd_bus_message_enter_container(reply, 'a', "(iay)");
cabb0bc6
LP
144 if (r < 0)
145 goto fail;
146
147 r = count_addresses(reply, AF_UNSPEC, &c);
148 if (r < 0)
149 goto fail;
150
151 if (c <= 0) {
cabb0bc6
LP
152 *h_errnop = HOST_NOT_FOUND;
153 return NSS_STATUS_NOTFOUND;
154 }
155
156 l = strlen(name);
157 ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
158 if (buflen < ms) {
cdccd29f 159 UNPROTECT_ERRNO;
0192cbdb 160 *errnop = ERANGE;
cda458a5 161 *h_errnop = NETDB_INTERNAL;
cabb0bc6
LP
162 return NSS_STATUS_TRYAGAIN;
163 }
164
165 /* First, append name */
166 r_name = buffer;
167 memcpy(r_name, name, l+1);
168 idx = ALIGN(l+1);
169
170 /* Second, append addresses */
171 r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
0dd25fb9
LP
172 while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
173 int family;
cabb0bc6
LP
174 const void *a;
175 size_t sz;
176
0dd25fb9 177 r = sd_bus_message_read(reply, "i", &family);
cabb0bc6
LP
178 if (r < 0)
179 goto fail;
180
181 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
182 if (r < 0)
183 goto fail;
184
185 r = sd_bus_message_exit_container(reply);
186 if (r < 0)
187 goto fail;
188
555bd6e9
LP
189 if (!IN_SET(family, AF_INET, AF_INET6)) {
190 r = -EAFNOSUPPORT;
191 goto fail;
192 }
193
9d485985 194 if (sz != FAMILY_ADDRESS_SIZE(family)) {
cabb0bc6
LP
195 r = -EINVAL;
196 goto fail;
197 }
198
199 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
200 r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
201 r_tuple->name = r_name;
202 r_tuple->family = family;
634af566 203 r_tuple->scopeid = n_ifindices == 1 ? ifindices[0] : 0;
cabb0bc6
LP
204 memcpy(r_tuple->addr, a, sz);
205
206 idx += ALIGN(sizeof(struct gaih_addrtuple));
207 i++;
208 }
209
210 assert(i == c);
211
212 r = sd_bus_message_exit_container(reply);
213 if (r < 0)
214 goto fail;
215
216 assert(idx == ms);
217
218 if (*pat)
219 **pat = *r_tuple_first;
220 else
221 *pat = r_tuple_first;
222
223 if (ttlp)
224 *ttlp = 0;
225
06202b9e
YW
226 /* Explicitly reset both *h_errnop and h_errno to work around
227 * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
e70df46b
LP
228 *h_errnop = NETDB_SUCCESS;
229 h_errno = 0;
230
cabb0bc6
LP
231 return NSS_STATUS_SUCCESS;
232
233fail:
cdccd29f 234 UNPROTECT_ERRNO;
0192cbdb 235 *errnop = -r;
2b0c1bfd 236 *h_errnop = NO_RECOVERY;
cabb0bc6
LP
237 return NSS_STATUS_UNAVAIL;
238}
239
240enum nss_status _nss_mymachines_gethostbyname3_r(
241 const char *name,
242 int af,
243 struct hostent *result,
244 char *buffer, size_t buflen,
245 int *errnop, int *h_errnop,
246 int32_t *ttlp,
247 char **canonp) {
248
4afd3348
LP
249 _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
250 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
cabb0bc6
LP
251 _cleanup_free_ char *class = NULL;
252 unsigned c = 0, i = 0;
253 char *r_name, *r_aliases, *r_addr, *r_addr_list;
254 size_t l, idx, ms, alen;
255 int r;
256
06202b9e 257 PROTECT_ERRNO;
e5d5edc3 258 NSS_ENTRYPOINT_BEGIN;
0c5eb056 259
cabb0bc6
LP
260 assert(name);
261 assert(result);
262 assert(buffer);
263 assert(errnop);
264 assert(h_errnop);
265
266 if (af == AF_UNSPEC)
267 af = AF_INET;
268
269 if (af != AF_INET && af != AF_INET6) {
270 r = -EAFNOSUPPORT;
271 goto fail;
272 }
273
274 r = sd_machine_get_class(name, &class);
275 if (r < 0)
276 goto fail;
277 if (!streq(class, "container")) {
278 r = -ENOTTY;
279 goto fail;
280 }
281
2f28018c
LP
282 if (avoid_deadlock()) {
283 r = -EDEADLK;
284 goto fail;
285 }
286
cabb0bc6
LP
287 r = sd_bus_open_system(&bus);
288 if (r < 0)
289 goto fail;
290
7b389878 291 r = bus_call_method(bus, bus_machine_mgr, "GetMachineAddresses", NULL, &reply, "s", name);
cabb0bc6
LP
292 if (r < 0)
293 goto fail;
294
0dd25fb9 295 r = sd_bus_message_enter_container(reply, 'a', "(iay)");
cabb0bc6
LP
296 if (r < 0)
297 goto fail;
298
299 r = count_addresses(reply, af, &c);
300 if (r < 0)
301 goto fail;
302
303 if (c <= 0) {
cabb0bc6
LP
304 *h_errnop = HOST_NOT_FOUND;
305 return NSS_STATUS_NOTFOUND;
306 }
307
9d485985 308 alen = FAMILY_ADDRESS_SIZE(af);
cabb0bc6
LP
309 l = strlen(name);
310
66a16e7e 311 ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
cabb0bc6
LP
312
313 if (buflen < ms) {
cdccd29f 314 UNPROTECT_ERRNO;
0192cbdb 315 *errnop = ERANGE;
cda458a5 316 *h_errnop = NETDB_INTERNAL;
cabb0bc6
LP
317 return NSS_STATUS_TRYAGAIN;
318 }
319
320 /* First, append name */
321 r_name = buffer;
322 memcpy(r_name, name, l+1);
323 idx = ALIGN(l+1);
324
325 /* Second, create aliases array */
326 r_aliases = buffer + idx;
327 ((char**) r_aliases)[0] = NULL;
328 idx += sizeof(char*);
329
330 /* Third, append addresses */
331 r_addr = buffer + idx;
0dd25fb9
LP
332 while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
333 int family;
cabb0bc6
LP
334 const void *a;
335 size_t sz;
336
0dd25fb9 337 r = sd_bus_message_read(reply, "i", &family);
cabb0bc6
LP
338 if (r < 0)
339 goto fail;
340
341 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
342 if (r < 0)
343 goto fail;
344
345 r = sd_bus_message_exit_container(reply);
346 if (r < 0)
347 goto fail;
348
349 if (family != af)
350 continue;
351
352 if (sz != alen) {
353 r = -EINVAL;
354 goto fail;
355 }
356
357 memcpy(r_addr + i*ALIGN(alen), a, alen);
358 i++;
359 }
360
361 assert(i == c);
362 idx += c * ALIGN(alen);
363
364 r = sd_bus_message_exit_container(reply);
365 if (r < 0)
366 goto fail;
367
368 /* Third, append address pointer array */
369 r_addr_list = buffer + idx;
370 for (i = 0; i < c; i++)
371 ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
372
373 ((char**) r_addr_list)[i] = NULL;
374 idx += (c+1) * sizeof(char*);
375
376 assert(idx == ms);
377
378 result->h_name = r_name;
379 result->h_aliases = (char**) r_aliases;
380 result->h_addrtype = af;
381 result->h_length = alen;
382 result->h_addr_list = (char**) r_addr_list;
383
384 if (ttlp)
385 *ttlp = 0;
386
387 if (canonp)
388 *canonp = r_name;
389
06202b9e
YW
390 /* Explicitly reset both *h_errnop and h_errno to work around
391 * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
e70df46b
LP
392 *h_errnop = NETDB_SUCCESS;
393 h_errno = 0;
394
cabb0bc6
LP
395 return NSS_STATUS_SUCCESS;
396
397fail:
cdccd29f 398 UNPROTECT_ERRNO;
0192cbdb 399 *errnop = -r;
2b0c1bfd 400 *h_errnop = NO_RECOVERY;
cabb0bc6
LP
401 return NSS_STATUS_UNAVAIL;
402}
403
c01ff965
LP
404NSS_GETHOSTBYNAME_FALLBACKS(mymachines);
405
406enum nss_status _nss_mymachines_getpwnam_r(
407 const char *name,
408 struct passwd *pwd,
409 char *buffer, size_t buflen,
410 int *errnop) {
411
38ccb557 412 return NSS_STATUS_NOTFOUND;
c01ff965
LP
413}
414
415enum nss_status _nss_mymachines_getpwuid_r(
416 uid_t uid,
417 struct passwd *pwd,
418 char *buffer, size_t buflen,
419 int *errnop) {
420
38ccb557 421 return NSS_STATUS_NOTFOUND;
c01ff965
LP
422}
423
424enum nss_status _nss_mymachines_getgrnam_r(
425 const char *name,
426 struct group *gr,
427 char *buffer, size_t buflen,
428 int *errnop) {
429
38ccb557 430 return NSS_STATUS_NOTFOUND;
c01ff965
LP
431}
432
433enum nss_status _nss_mymachines_getgrgid_r(
434 gid_t gid,
435 struct group *gr,
436 char *buffer, size_t buflen,
437 int *errnop) {
438
38ccb557 439 return NSS_STATUS_NOTFOUND;
c01ff965 440}