4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering/***
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering This file is part of systemd.
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering Copyright 2014 Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering (at your option) any later version.
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering systemd is distributed in the hope that it will be useful, but
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering Lesser General Public License for more details.
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering***/
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <dlfcn.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <errno.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <netdb.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <nss.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <stdlib.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "sd-bus.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include "bus-common-errors.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "in-addr-util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "macro.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "nss-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "util.h"
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering#include "signal-util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYNAME_PROTOTYPES(resolve);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYADDR_PROTOTYPES(resolve);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poetteringtypedef void (*voidfunc_t)(void);
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poetteringstatic voidfunc_t find_fallback(const char *module, const char *symbol) {
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering void *dl;
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering /* Try to find a fallback NSS module symbol */
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering dl = dlopen(module, RTLD_LAZY|RTLD_NODELETE);
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering if (!dl)
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering return NULL;
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering return dlsym(dl, symbol);
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering}
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poetteringstatic bool bus_error_shall_fallback(sd_bus_error *e) {
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) ||
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering sd_bus_error_has_name(e, SD_BUS_ERROR_NO_REPLY) ||
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED);
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering}
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poetteringstatic int count_addresses(sd_bus_message *m, int af, const char **canonical) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int c = 0, r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(m);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering assert(canonical);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_enter_container(m, 'a', "(iiay)");
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while ((r = sd_bus_message_enter_container(m, 'r', "iiay")) > 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int family, ifindex;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_read(m, "ii", &ifindex, &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_skip(m, "ay");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_exit_container(m);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (af != AF_UNSPEC && family != af)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering continue;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering c ++;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_exit_container(m);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return r;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_read(m, "s", canonical);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_rewind(m, true);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return r;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return c;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering}
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringenum nss_status _nss_resolve_gethostbyname4_r(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const char *name,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering struct gaih_addrtuple **pat,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *buffer, size_t buflen,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int *errnop, int *h_errnop,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int32_t *ttlp) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering enum nss_status (*fallback)(
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering const char *name,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct gaih_addrtuple **pat,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering const char *canonical = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t l, ms, idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int c, r, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(name);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(pat);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(buffer);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(h_errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_open_system(&bus);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_new_method_call(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering bus,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering &req,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "/org/freedesktop/resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1.Manager",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "ResolveHostname");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_set_auto_start(req, false);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(req, "isit", 0, name, AF_UNSPEC, (uint64_t) 0);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (bus_error_shall_fallback(&error))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering c = count_addresses(reply, AF_UNSPEC, &canonical);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (c < 0) {
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = c;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (c == 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (isempty(canonical))
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering canonical = name;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering l = strlen(canonical);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (buflen < ms) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ENOMEM;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = TRY_AGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_TRYAGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* First, append name */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_name = buffer;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering memcpy(r_name, canonical, l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx = ALIGN(l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* Second, append addresses */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto fail;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int family, ifindex;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const void *a;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t sz;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_read(reply, "ii", &ifindex, &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (ifindex < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = -EINVAL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_exit_container(reply);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6))
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering continue;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
9d485985338a46b8cb1acdf1af6c1eb2e88acfeeLennart Poettering if (sz != FAMILY_ADDRESS_SIZE(family)) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = -EINVAL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple = (struct gaih_addrtuple*) (buffer + idx);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple->name = r_name;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple->family = family;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_tuple->scopeid = ifindex;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering memcpy(r_tuple->addr, a, sz);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += ALIGN(sizeof(struct gaih_addrtuple));
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering i++;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering assert(i == c);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(idx == ms);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (*pat)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering **pat = *r_tuple_first;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering else
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *pat = r_tuple_first;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (ttlp)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *ttlp = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering /* Explicitly reset all error variables */
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *errnop = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *h_errnop = NETDB_SUCCESS;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering h_errno = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_SUCCESS;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poetteringfallback:
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering fallback = (enum nss_status (*)(const char *name,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct gaih_addrtuple **pat,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (fallback)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering}
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringenum nss_status _nss_resolve_gethostbyname3_r(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const char *name,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int af,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering struct hostent *result,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *buffer, size_t buflen,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int *errnop, int *h_errnop,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int32_t *ttlp,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char **canonp) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering enum nss_status (*fallback)(
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering const char *name,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int af,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct hostent *result,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char **canonp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name, *r_aliases, *r_addr, *r_addr_list;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t l, idx, ms, alen;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering const char *canonical;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int c, r, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(name);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(result);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(buffer);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(h_errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (af == AF_UNSPEC)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering af = AF_INET;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (af != AF_INET && af != AF_INET6) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = -EAFNOSUPPORT;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_open_system(&bus);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_new_method_call(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering bus,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering &req,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "/org/freedesktop/resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1.Manager",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "ResolveHostname");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_set_auto_start(req, false);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(req, "isit", 0, name, af, (uint64_t) 0);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (bus_error_shall_fallback(&error))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering c = count_addresses(reply, af, &canonical);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (c < 0) {
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = c;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (c == 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (isempty(canonical))
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering canonical = name;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
9d485985338a46b8cb1acdf1af6c1eb2e88acfeeLennart Poettering alen = FAMILY_ADDRESS_SIZE(af);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering l = strlen(canonical);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
66a16e7e9fc501d371b57cbe2ae5d130fe930c6dThomas Hindoe Paaboel Andersen ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (buflen < ms) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ENOMEM;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = TRY_AGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_TRYAGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* First, append name */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_name = buffer;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering memcpy(r_name, canonical, l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx = ALIGN(l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering /* Second, create empty aliases array */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_aliases = buffer + idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_aliases)[0] = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += sizeof(char*);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* Third, append addresses */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_addr = buffer + idx;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto fail;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int ifindex, family;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const void *a;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t sz;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_read(reply, "ii", &ifindex, &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (ifindex < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = -EINVAL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_exit_container(reply);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (family != af)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering continue;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (sz != alen) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = -EINVAL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering memcpy(r_addr + i*ALIGN(alen), a, alen);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering i++;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(i == c);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += c * ALIGN(alen);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering /* Fourth, append address pointer array */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_addr_list = buffer + idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering for (i = 0; i < c; i++)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_addr_list)[i] = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += (c+1) * sizeof(char*);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(idx == ms);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_name = r_name;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_aliases = (char**) r_aliases;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_addrtype = af;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_length = alen;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_addr_list = (char**) r_addr_list;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering /* Explicitly reset all error variables */
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *errnop = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *h_errnop = NETDB_SUCCESS;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering h_errno = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (ttlp)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *ttlp = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (canonp)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *canonp = r_name;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_SUCCESS;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poetteringfallback:
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering fallback = (enum nss_status (*)(const char *name,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int af,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct hostent *result,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char **canonp))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (fallback)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering}
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringenum nss_status _nss_resolve_gethostbyaddr2_r(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const void* addr, socklen_t len,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int af,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering struct hostent *result,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *buffer, size_t buflen,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int *errnop, int *h_errnop,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int32_t *ttlp) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering enum nss_status (*fallback)(
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering const void* addr, socklen_t len,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int af,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct hostent *result,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name, *r_aliases, *r_addr, *r_addr_list;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering unsigned c = 0, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t ms = 0, idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const char *n;
51323288fc628a5cac50914df915545d685b793eLennart Poettering int r, ifindex;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
0c5eb0562abec6f845f07c30b2ad2515900ec1e5Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(addr);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(result);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(buffer);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(h_errnop);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (!IN_SET(af, AF_INET, AF_INET6)) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = EAFNOSUPPORT;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_DATA;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
9d485985338a46b8cb1acdf1af6c1eb2e88acfeeLennart Poettering if (len != FAMILY_ADDRESS_SIZE(af)) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = EINVAL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_open_system(&bus);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_new_method_call(
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering bus,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering &req,
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "/org/freedesktop/resolve1",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "org.freedesktop.resolve1.Manager",
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering "ResolveAddress");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_set_auto_start(req, false);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(req, "ii", 0, af);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_append_array(req, 'y', addr, len);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(req, "t", (uint64_t) 0);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (bus_error_shall_fallback(&error))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering goto fallback;
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
7c2a5e264c1d94ca9ba9c49acfdcd541c8a63a88Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(is)");
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto fail;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while ((r = sd_bus_message_read(reply, "(is)", &ifindex, &n)) > 0) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (ifindex < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = -EINVAL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering c++;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ms += ALIGN(strlen(n) + 1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_rewind(reply, false);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (c <= 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ESRCH;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = HOST_NOT_FOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_NOTFOUND;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ms += ALIGN(len) + /* the address */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering 2 * sizeof(char*) + /* pointers to the address, plus trailing NULL */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering c * sizeof(char*); /* pointers to aliases, plus trailing NULL */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (buflen < ms) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = ENOMEM;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = TRY_AGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_TRYAGAIN;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* First, place address */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_addr = buffer;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering memcpy(r_addr, addr, len);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx = ALIGN(len);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* Second, place address list */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_addr_list = buffer + idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_addr_list)[0] = r_addr;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_addr_list)[1] = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += sizeof(char*) * 2;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* Third, reserve space for the aliases array */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_aliases = buffer + idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += sizeof(char*) * c;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering /* Fourth, place aliases */
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r_name = buffer + idx;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while ((r = sd_bus_message_read(reply, "(is)", &ifindex, &n)) > 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *p;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t l;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering l = strlen(n);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering p = buffer + idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering memcpy(p, n, l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
963783d7447cad48e594846a865b26535874679dSamu Kallio if (i > 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_aliases)[i-1] = p;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering i++;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering idx += ALIGN(l+1);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ((char**) r_aliases)[c-1] = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(idx == ms);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_name = r_name;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_aliases = (char**) r_aliases;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_addrtype = af;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_length = len;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering result->h_addr_list = (char**) r_addr_list;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (ttlp)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *ttlp = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering /* Explicitly reset all error variables */
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *errnop = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering *h_errnop = NETDB_SUCCESS;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering h_errno = 0;
e70df46b9721a3d025e7a0b4ffb5893cbde5e55dLennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_SUCCESS;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poetteringfallback:
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering fallback = (enum nss_status (*)(
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering const void* addr, socklen_t len,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int af,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering struct hostent *result,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering char *buffer, size_t buflen,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int *errnop, int *h_errnop,
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering int32_t *ttlp))
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering if (fallback)
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
a464cf80110f0c7424f688ffaa4ec0a8a19f9720Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering}
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYNAME_FALLBACKS(resolve);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYADDR_FALLBACKS(resolve);