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