nss-resolve.c revision 9d485985338a46b8cb1acdf1af6c1eb2e88acfee
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <limits.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <nss.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <sys/types.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <netdb.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <errno.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <string.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <unistd.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <net/if.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <stdlib.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include <arpa/inet.h>
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "sd-bus.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "bus-util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "bus-errors.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "macro.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "nss-util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "util.h"
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering#include "in-addr-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
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poetteringstatic int count_addresses(sd_bus_message *m, unsigned af, const char **canonical) {
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering int c = 0, r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering assert(m);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering assert(canonical);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_enter_container(m, 'a', "(yayi)");
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering while ((r = sd_bus_message_enter_container(m, 'r', "yayi")) > 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering unsigned char family;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_read(m, "y", &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_skip(m, "ayi");
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering const char *canonical = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t l, ms, idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering int c, r, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart 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)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_append(req, "sy", name, AF_UNSPEC);
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
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
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(yayi)");
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto fail;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "yayi")) > 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering unsigned char family;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const void *a;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int ifindex;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t sz;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_read(reply, "y", &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart 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_read(reply, "i", &ifindex);
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 if (ifindex < 0) {
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_SUCCESS;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_DATA;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name, *r_aliases, *r_addr, *r_addr_list;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t l, idx, ms, alen;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering const char *canonical;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering int c, r, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart 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)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_append(req, "sy", name, af);
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering ms = ALIGN(l+1) +
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering sizeof(char*) +
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering (c > 0 ? c : 1) * ALIGN(alen) +
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering (c > 0 ? c+1 : 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
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(yayi)");
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto fail;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "yayi")) > 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering unsigned char family;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const void *a;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int ifindex;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t sz;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_read(reply, "y", &family);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart 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_read(reply, "i", &ifindex);
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 if (ifindex < 0) {
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
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_DATA;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering char *r_name, *r_aliases, *r_addr, *r_addr_list;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering unsigned c = 0, i = 0;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering size_t ms = 0, idx;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering const char *n;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering int r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart 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)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_append(req, "y", 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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_append(req, "i", 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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_RECOVERY;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering }
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "s");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (r < 0)
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering goto fail;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering while ((r = sd_bus_message_read(reply, "s", &n)) > 0) {
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;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering while ((r = sd_bus_message_read(reply, "s", &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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering if (i > 1)
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
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_SUCCESS;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poetteringfail:
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *errnop = -r;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering *h_errnop = NO_DATA;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering return NSS_STATUS_UNAVAIL;
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering}
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYNAME_FALLBACKS(resolve);
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart PoetteringNSS_GETHOSTBYADDR_FALLBACKS(resolve);