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