]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/nss-resolve/nss-resolve.c
Remove systemd-firstboot --force entry from TODO
[thirdparty/systemd.git] / src / nss-resolve / nss-resolve.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
4d1cf1e2 2
4d1cf1e2 3#include <errno.h>
07630cea
LP
4#include <netdb.h>
5#include <nss.h>
4d1cf1e2 6#include <stdlib.h>
ca78ad1d
ZJS
7#include <sys/types.h>
8#include <unistd.h>
4d1cf1e2
LP
9
10#include "sd-bus.h"
07630cea 11
96aad8d1 12#include "bus-common-errors.h"
a63d7e7b 13#include "bus-util.h"
2b2fec7d 14#include "errno-util.h"
07630cea 15#include "in-addr-util.h"
4d1cf1e2
LP
16#include "macro.h"
17#include "nss-util.h"
4cbfd62b 18#include "resolved-def.h"
0c5eb056 19#include "signal-util.h"
2b2fec7d 20#include "string-util.h"
4d1cf1e2
LP
21
22NSS_GETHOSTBYNAME_PROTOTYPES(resolve);
23NSS_GETHOSTBYADDR_PROTOTYPES(resolve);
24
7c2a5e26
LP
25static bool bus_error_shall_fallback(sd_bus_error *e) {
26 return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
27 sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) ||
28 sd_bus_error_has_name(e, SD_BUS_ERROR_NO_REPLY) ||
8baaf650
LP
29 sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED) ||
30 sd_bus_error_has_name(e, SD_BUS_ERROR_DISCONNECTED) ||
31 sd_bus_error_has_name(e, SD_BUS_ERROR_TIMEOUT);
7c2a5e26
LP
32}
33
0dd25fb9 34static int count_addresses(sd_bus_message *m, int af, const char **canonical) {
78c6a153 35 int c = 0, r;
4d1cf1e2
LP
36
37 assert(m);
309e9d86
LP
38 assert(canonical);
39
78c6a153 40 r = sd_bus_message_enter_container(m, 'a', "(iiay)");
309e9d86
LP
41 if (r < 0)
42 return r;
4d1cf1e2 43
78c6a153
LP
44 while ((r = sd_bus_message_enter_container(m, 'r', "iiay")) > 0) {
45 int family, ifindex;
51323288 46
78c6a153 47 assert_cc(sizeof(int32_t) == sizeof(int));
4d1cf1e2 48
78c6a153 49 r = sd_bus_message_read(m, "ii", &ifindex, &family);
4d1cf1e2
LP
50 if (r < 0)
51 return r;
52
51323288 53 r = sd_bus_message_skip(m, "ay");
4d1cf1e2
LP
54 if (r < 0)
55 return r;
56
57 r = sd_bus_message_exit_container(m);
58 if (r < 0)
59 return r;
60
61 if (af != AF_UNSPEC && family != af)
62 continue;
63
313cefa1 64 c++;
4d1cf1e2
LP
65 }
66 if (r < 0)
67 return r;
68
309e9d86
LP
69 r = sd_bus_message_exit_container(m);
70 if (r < 0)
71 return r;
72
73 r = sd_bus_message_read(m, "s", canonical);
4d1cf1e2
LP
74 if (r < 0)
75 return r;
76
309e9d86
LP
77 r = sd_bus_message_rewind(m, true);
78 if (r < 0)
79 return r;
80
81 return c;
4d1cf1e2
LP
82}
83
27007eff
LP
84static uint32_t ifindex_to_scopeid(int family, const void *a, int ifindex) {
85 struct in6_addr in6;
86
87 if (family != AF_INET6)
88 return 0;
89
90 /* Some apps can't deal with the scope ID attached to non-link-local addresses. Hence, let's suppress that. */
91
11814bbb 92 assert(sizeof(in6) == FAMILY_ADDRESS_SIZE(AF_INET6));
27007eff
LP
93 memcpy(&in6, a, sizeof(struct in6_addr));
94
95 return IN6_IS_ADDR_LINKLOCAL(&in6) ? ifindex : 0;
96}
97
2f28018c
LP
98static bool avoid_deadlock(void) {
99
100 /* Check whether this lookup might have a chance of deadlocking because we are called from the service manager
101 * code activating systemd-resolved.service. After all, we shouldn't synchronously do lookups to
102 * systemd-resolved if we are required to finish before it can be started. This of course won't detect all
103 * possible dead locks of this kind, but it should work for the most obvious cases. */
104
105 if (geteuid() != 0) /* Ignore the env vars unless we are privileged. */
106 return false;
107
108 return streq_ptr(getenv("SYSTEMD_ACTIVATION_UNIT"), "systemd-resolved.service") &&
109 streq_ptr(getenv("SYSTEMD_ACTIVATION_SCOPE"), "system");
110}
111
4d1cf1e2
LP
112enum nss_status _nss_resolve_gethostbyname4_r(
113 const char *name,
114 struct gaih_addrtuple **pat,
115 char *buffer, size_t buflen,
116 int *errnop, int *h_errnop,
117 int32_t *ttlp) {
118
4afd3348
LP
119 _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
120 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e2 121 struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
4afd3348 122 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
309e9d86 123 const char *canonical = NULL;
4d1cf1e2
LP
124 size_t l, ms, idx;
125 char *r_name;
78c6a153 126 int c, r, i = 0;
4d1cf1e2 127
06202b9e 128 PROTECT_ERRNO;
0c5eb056
LP
129 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
130
4d1cf1e2
LP
131 assert(name);
132 assert(pat);
133 assert(buffer);
134 assert(errnop);
135 assert(h_errnop);
136
2f28018c
LP
137 if (avoid_deadlock()) {
138 r = -EDEADLK;
139 goto fail;
140 }
141
4d1cf1e2
LP
142 r = sd_bus_open_system(&bus);
143 if (r < 0)
5486a31d 144 goto fail;
4d1cf1e2 145
a63d7e7b 146 r = bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveHostname");
4d1cf1e2
LP
147 if (r < 0)
148 goto fail;
149
150 r = sd_bus_message_set_auto_start(req, false);
151 if (r < 0)
152 goto fail;
153
51323288 154 r = sd_bus_message_append(req, "isit", 0, name, AF_UNSPEC, (uint64_t) 0);
4d1cf1e2
LP
155 if (r < 0)
156 goto fail;
157
4cbfd62b 158 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
4d1cf1e2 159 if (r < 0) {
547fde47 160 if (!bus_error_shall_fallback(&error))
06202b9e 161 goto not_found;
4d1cf1e2 162
5486a31d
ZJS
163 /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails,
164 allowing falling back to other nss modules. Treat all other error conditions as
165 NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this
5238e957 166 case so that the nsswitch.conf configuration can distinguish such executed but
5486a31d 167 negative replies from complete failure to talk to resolved). */
a464cf80 168 goto fail;
4d1cf1e2
LP
169 }
170
309e9d86
LP
171 c = count_addresses(reply, AF_UNSPEC, &canonical);
172 if (c < 0) {
173 r = c;
4d1cf1e2 174 goto fail;
309e9d86 175 }
06202b9e
YW
176 if (c == 0)
177 goto not_found;
4d1cf1e2 178
309e9d86
LP
179 if (isempty(canonical))
180 canonical = name;
181
182 l = strlen(canonical);
4d1cf1e2
LP
183 ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
184 if (buflen < ms) {
cdccd29f 185 UNPROTECT_ERRNO;
0192cbdb 186 *errnop = ERANGE;
e36c6e48 187 *h_errnop = NETDB_INTERNAL;
4d1cf1e2
LP
188 return NSS_STATUS_TRYAGAIN;
189 }
190
191 /* First, append name */
192 r_name = buffer;
309e9d86 193 memcpy(r_name, canonical, l+1);
4d1cf1e2
LP
194 idx = ALIGN(l+1);
195
196 /* Second, append addresses */
197 r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
309e9d86 198
78c6a153 199 r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
309e9d86
LP
200 if (r < 0)
201 goto fail;
202
78c6a153
LP
203 while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
204 int family, ifindex;
4d1cf1e2 205 const void *a;
4d1cf1e2
LP
206 size_t sz;
207
78c6a153
LP
208 assert_cc(sizeof(int32_t) == sizeof(int));
209
210 r = sd_bus_message_read(reply, "ii", &ifindex, &family);
4d1cf1e2
LP
211 if (r < 0)
212 goto fail;
213
78c6a153
LP
214 if (ifindex < 0) {
215 r = -EINVAL;
216 goto fail;
217 }
218
4d1cf1e2
LP
219 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
220 if (r < 0)
221 goto fail;
222
4d1cf1e2
LP
223 r = sd_bus_message_exit_container(reply);
224 if (r < 0)
225 goto fail;
226
227 if (!IN_SET(family, AF_INET, AF_INET6))
228 continue;
229
9d485985 230 if (sz != FAMILY_ADDRESS_SIZE(family)) {
4d1cf1e2
LP
231 r = -EINVAL;
232 goto fail;
233 }
234
4d1cf1e2
LP
235 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
236 r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
237 r_tuple->name = r_name;
238 r_tuple->family = family;
27007eff 239 r_tuple->scopeid = ifindex_to_scopeid(family, a, ifindex);
4d1cf1e2
LP
240 memcpy(r_tuple->addr, a, sz);
241
242 idx += ALIGN(sizeof(struct gaih_addrtuple));
243 i++;
244 }
4d1cf1e2
LP
245 if (r < 0)
246 goto fail;
247
309e9d86 248 assert(i == c);
4d1cf1e2
LP
249 assert(idx == ms);
250
251 if (*pat)
252 **pat = *r_tuple_first;
253 else
254 *pat = r_tuple_first;
255
256 if (ttlp)
257 *ttlp = 0;
258
06202b9e
YW
259 /* Explicitly reset both *h_errnop and h_errno to work around
260 * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
e70df46b
LP
261 *h_errnop = NETDB_SUCCESS;
262 h_errno = 0;
263
4d1cf1e2
LP
264 return NSS_STATUS_SUCCESS;
265
266fail:
cdccd29f 267 UNPROTECT_ERRNO;
0192cbdb 268 *errnop = -r;
a464cf80 269 *h_errnop = NO_RECOVERY;
954cba66 270 return NSS_STATUS_UNAVAIL;
06202b9e
YW
271
272not_found:
273 *h_errnop = HOST_NOT_FOUND;
274 return NSS_STATUS_NOTFOUND;
4d1cf1e2
LP
275}
276
277enum nss_status _nss_resolve_gethostbyname3_r(
278 const char *name,
279 int af,
280 struct hostent *result,
281 char *buffer, size_t buflen,
282 int *errnop, int *h_errnop,
283 int32_t *ttlp,
284 char **canonp) {
285
4afd3348
LP
286 _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
287 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e2 288 char *r_name, *r_aliases, *r_addr, *r_addr_list;
4afd3348 289 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
4d1cf1e2 290 size_t l, idx, ms, alen;
309e9d86 291 const char *canonical;
78c6a153 292 int c, r, i = 0;
4d1cf1e2 293
06202b9e 294 PROTECT_ERRNO;
0c5eb056
LP
295 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
296
4d1cf1e2
LP
297 assert(name);
298 assert(result);
299 assert(buffer);
300 assert(errnop);
301 assert(h_errnop);
302
303 if (af == AF_UNSPEC)
304 af = AF_INET;
305
4c701096 306 if (!IN_SET(af, AF_INET, AF_INET6)) {
4d1cf1e2
LP
307 r = -EAFNOSUPPORT;
308 goto fail;
309 }
310
2f28018c
LP
311 if (avoid_deadlock()) {
312 r = -EDEADLK;
313 goto fail;
314 }
315
4d1cf1e2
LP
316 r = sd_bus_open_system(&bus);
317 if (r < 0)
5486a31d 318 goto fail;
4d1cf1e2 319
a63d7e7b 320 r = bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveHostname");
4d1cf1e2
LP
321 if (r < 0)
322 goto fail;
323
324 r = sd_bus_message_set_auto_start(req, false);
325 if (r < 0)
326 goto fail;
327
51323288 328 r = sd_bus_message_append(req, "isit", 0, name, af, (uint64_t) 0);
4d1cf1e2
LP
329 if (r < 0)
330 goto fail;
331
4cbfd62b 332 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
4d1cf1e2 333 if (r < 0) {
547fde47 334 if (!bus_error_shall_fallback(&error))
06202b9e 335 goto not_found;
7c2a5e26 336
a464cf80 337 goto fail;
4d1cf1e2
LP
338 }
339
309e9d86
LP
340 c = count_addresses(reply, af, &canonical);
341 if (c < 0) {
342 r = c;
4d1cf1e2 343 goto fail;
309e9d86 344 }
06202b9e
YW
345 if (c == 0)
346 goto not_found;
4d1cf1e2 347
309e9d86
LP
348 if (isempty(canonical))
349 canonical = name;
350
9d485985 351 alen = FAMILY_ADDRESS_SIZE(af);
309e9d86 352 l = strlen(canonical);
4d1cf1e2 353
66a16e7e 354 ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
4d1cf1e2
LP
355
356 if (buflen < ms) {
cdccd29f 357 UNPROTECT_ERRNO;
0192cbdb 358 *errnop = ERANGE;
e36c6e48 359 *h_errnop = NETDB_INTERNAL;
4d1cf1e2
LP
360 return NSS_STATUS_TRYAGAIN;
361 }
362
363 /* First, append name */
364 r_name = buffer;
309e9d86 365 memcpy(r_name, canonical, l+1);
4d1cf1e2
LP
366 idx = ALIGN(l+1);
367
309e9d86 368 /* Second, create empty aliases array */
4d1cf1e2
LP
369 r_aliases = buffer + idx;
370 ((char**) r_aliases)[0] = NULL;
371 idx += sizeof(char*);
372
373 /* Third, append addresses */
374 r_addr = buffer + idx;
309e9d86 375
78c6a153 376 r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
51323288
LP
377 if (r < 0)
378 goto fail;
379
78c6a153
LP
380 while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
381 int ifindex, family;
4d1cf1e2 382 const void *a;
4d1cf1e2
LP
383 size_t sz;
384
78c6a153 385 r = sd_bus_message_read(reply, "ii", &ifindex, &family);
4d1cf1e2
LP
386 if (r < 0)
387 goto fail;
388
78c6a153
LP
389 if (ifindex < 0) {
390 r = -EINVAL;
391 goto fail;
392 }
393
4d1cf1e2
LP
394 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
395 if (r < 0)
396 goto fail;
397
4d1cf1e2
LP
398 r = sd_bus_message_exit_container(reply);
399 if (r < 0)
400 goto fail;
401
402 if (family != af)
403 continue;
404
405 if (sz != alen) {
406 r = -EINVAL;
407 goto fail;
408 }
409
4d1cf1e2
LP
410 memcpy(r_addr + i*ALIGN(alen), a, alen);
411 i++;
412 }
309e9d86
LP
413 if (r < 0)
414 goto fail;
4d1cf1e2
LP
415
416 assert(i == c);
417 idx += c * ALIGN(alen);
418
309e9d86 419 /* Fourth, append address pointer array */
4d1cf1e2
LP
420 r_addr_list = buffer + idx;
421 for (i = 0; i < c; i++)
422 ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
423
424 ((char**) r_addr_list)[i] = NULL;
425 idx += (c+1) * sizeof(char*);
426
427 assert(idx == ms);
428
429 result->h_name = r_name;
430 result->h_aliases = (char**) r_aliases;
431 result->h_addrtype = af;
432 result->h_length = alen;
433 result->h_addr_list = (char**) r_addr_list;
434
435 if (ttlp)
436 *ttlp = 0;
437
438 if (canonp)
439 *canonp = r_name;
440
06202b9e
YW
441 /* Explicitly reset both *h_errnop and h_errno to work around
442 * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
443 *h_errnop = NETDB_SUCCESS;
444 h_errno = 0;
445
4d1cf1e2
LP
446 return NSS_STATUS_SUCCESS;
447
448fail:
cdccd29f 449 UNPROTECT_ERRNO;
0192cbdb 450 *errnop = -r;
a464cf80 451 *h_errnop = NO_RECOVERY;
954cba66 452 return NSS_STATUS_UNAVAIL;
06202b9e
YW
453
454not_found:
455 *h_errnop = HOST_NOT_FOUND;
456 return NSS_STATUS_NOTFOUND;
4d1cf1e2
LP
457}
458
459enum nss_status _nss_resolve_gethostbyaddr2_r(
460 const void* addr, socklen_t len,
461 int af,
462 struct hostent *result,
463 char *buffer, size_t buflen,
464 int *errnop, int *h_errnop,
465 int32_t *ttlp) {
466
4afd3348
LP
467 _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
468 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e2 469 char *r_name, *r_aliases, *r_addr, *r_addr_list;
4afd3348 470 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
4d1cf1e2
LP
471 unsigned c = 0, i = 0;
472 size_t ms = 0, idx;
473 const char *n;
51323288 474 int r, ifindex;
4d1cf1e2 475
06202b9e 476 PROTECT_ERRNO;
0c5eb056
LP
477 BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
478
4d1cf1e2
LP
479 assert(addr);
480 assert(result);
481 assert(buffer);
482 assert(errnop);
483 assert(h_errnop);
484
485 if (!IN_SET(af, AF_INET, AF_INET6)) {
cdccd29f 486 UNPROTECT_ERRNO;
0192cbdb 487 *errnop = EAFNOSUPPORT;
4d1cf1e2
LP
488 *h_errnop = NO_DATA;
489 return NSS_STATUS_UNAVAIL;
490 }
491
9d485985 492 if (len != FAMILY_ADDRESS_SIZE(af)) {
a62fc245
LP
493 r = -EINVAL;
494 goto fail;
4d1cf1e2
LP
495 }
496
2f28018c
LP
497 if (avoid_deadlock()) {
498 r = -EDEADLK;
499 goto fail;
500 }
501
4d1cf1e2
LP
502 r = sd_bus_open_system(&bus);
503 if (r < 0)
5486a31d 504 goto fail;
4d1cf1e2 505
a63d7e7b 506 r = bus_message_new_method_call(bus, &req, bus_resolve_mgr, "ResolveAddress");
4d1cf1e2
LP
507 if (r < 0)
508 goto fail;
509
510 r = sd_bus_message_set_auto_start(req, false);
511 if (r < 0)
512 goto fail;
513
51323288 514 r = sd_bus_message_append(req, "ii", 0, af);
4d1cf1e2
LP
515 if (r < 0)
516 goto fail;
517
518 r = sd_bus_message_append_array(req, 'y', addr, len);
519 if (r < 0)
520 goto fail;
521
51323288 522 r = sd_bus_message_append(req, "t", (uint64_t) 0);
4d1cf1e2
LP
523 if (r < 0)
524 goto fail;
525
4cbfd62b 526 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
4d1cf1e2 527 if (r < 0) {
547fde47 528 if (!bus_error_shall_fallback(&error))
06202b9e 529 goto not_found;
7c2a5e26 530
46c7a7ac 531 goto fail;
4d1cf1e2
LP
532 }
533
78c6a153 534 r = sd_bus_message_enter_container(reply, 'a', "(is)");
51323288
LP
535 if (r < 0)
536 goto fail;
537
78c6a153 538 while ((r = sd_bus_message_read(reply, "(is)", &ifindex, &n)) > 0) {
51323288 539
78c6a153
LP
540 if (ifindex < 0) {
541 r = -EINVAL;
542 goto fail;
543 }
4d1cf1e2 544
4d1cf1e2
LP
545 c++;
546 ms += ALIGN(strlen(n) + 1);
547 }
548 if (r < 0)
549 goto fail;
550
551 r = sd_bus_message_rewind(reply, false);
552 if (r < 0)
c7c468c9 553 goto fail;
4d1cf1e2 554
06202b9e
YW
555 if (c <= 0)
556 goto not_found;
4d1cf1e2
LP
557
558 ms += ALIGN(len) + /* the address */
559 2 * sizeof(char*) + /* pointers to the address, plus trailing NULL */
560 c * sizeof(char*); /* pointers to aliases, plus trailing NULL */
561
562 if (buflen < ms) {
cdccd29f 563 UNPROTECT_ERRNO;
0192cbdb 564 *errnop = ERANGE;
e36c6e48 565 *h_errnop = NETDB_INTERNAL;
4d1cf1e2
LP
566 return NSS_STATUS_TRYAGAIN;
567 }
568
569 /* First, place address */
570 r_addr = buffer;
571 memcpy(r_addr, addr, len);
572 idx = ALIGN(len);
573
574 /* Second, place address list */
575 r_addr_list = buffer + idx;
576 ((char**) r_addr_list)[0] = r_addr;
577 ((char**) r_addr_list)[1] = NULL;
578 idx += sizeof(char*) * 2;
579
580 /* Third, reserve space for the aliases array */
581 r_aliases = buffer + idx;
582 idx += sizeof(char*) * c;
583
584 /* Fourth, place aliases */
585 i = 0;
586 r_name = buffer + idx;
78c6a153 587 while ((r = sd_bus_message_read(reply, "(is)", &ifindex, &n)) > 0) {
4d1cf1e2
LP
588 char *p;
589 size_t l;
590
591 l = strlen(n);
592 p = buffer + idx;
593 memcpy(p, n, l+1);
594
963783d7 595 if (i > 0)
4d1cf1e2
LP
596 ((char**) r_aliases)[i-1] = p;
597 i++;
598
599 idx += ALIGN(l+1);
600 }
309e9d86
LP
601 if (r < 0)
602 goto fail;
4d1cf1e2
LP
603
604 ((char**) r_aliases)[c-1] = NULL;
605 assert(idx == ms);
606
607 result->h_name = r_name;
608 result->h_aliases = (char**) r_aliases;
609 result->h_addrtype = af;
610 result->h_length = len;
611 result->h_addr_list = (char**) r_addr_list;
612
613 if (ttlp)
614 *ttlp = 0;
615
06202b9e
YW
616 /* Explicitly reset both *h_errnop and h_errno to work around
617 * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
e70df46b
LP
618 *h_errnop = NETDB_SUCCESS;
619 h_errno = 0;
620
4d1cf1e2
LP
621 return NSS_STATUS_SUCCESS;
622
623fail:
cdccd29f 624 UNPROTECT_ERRNO;
0192cbdb 625 *errnop = -r;
a464cf80 626 *h_errnop = NO_RECOVERY;
954cba66 627 return NSS_STATUS_UNAVAIL;
06202b9e
YW
628
629not_found:
630 *h_errnop = HOST_NOT_FOUND;
631 return NSS_STATUS_NOTFOUND;
4d1cf1e2
LP
632}
633
634NSS_GETHOSTBYNAME_FALLBACKS(resolve);
635NSS_GETHOSTBYADDR_FALLBACKS(resolve);