nss-mymachines.c revision 3a6fb33c54bc64398e0af1c9d7c74a6b614a849d
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering/***
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering This file is part of systemd.
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering Copyright 2014 Lennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering systemd is free software; you can redistribute it and/or modify it
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering under the terms of the GNU Lesser General Public License as published by
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering (at your option) any later version.
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering systemd is distributed in the hope that it will be useful, but
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering Lesser General Public License for more details.
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering You should have received a copy of the GNU Lesser General Public License
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering***/
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include <nss.h>
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include <netdb.h>
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "sd-bus.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "sd-login.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "macro.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "util.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "nss-util.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "bus-util.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering#include "in-addr-util.h"
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart PoetteringNSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poetteringstatic int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering unsigned c = 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(m);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(ret);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
3a6fb33c54bc64398e0af1c9d7c74a6b614a849dLennart Poettering while ((r = sd_bus_message_enter_container(m, 'r', "iay")) > 0) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int family;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_read(m, "i", &family);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_skip(m, "ay");
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_exit_container(m);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (af != AF_UNSPEC && family != af)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering continue;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering c ++;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_rewind(m, false);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *ret = c;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering}
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poetteringenum nss_status _nss_mymachines_gethostbyname4_r(
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering const char *name,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering struct gaih_addrtuple **pat,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering char *buffer, size_t buflen,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int *errnop, int *h_errnop,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int32_t *ttlp) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering _cleanup_bus_message_unref_ sd_bus_message* reply = NULL;
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering _cleanup_bus_close_unref_ sd_bus *bus = NULL;
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering _cleanup_free_ int *ifindices = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering _cleanup_free_ char *class = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering size_t l, ms, idx;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering unsigned i = 0, c = 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering char *r_name;
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering int n_ifindices, r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(pat);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(buffer);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(errnop);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(h_errnop);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_machine_get_class(name, &class);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (!streq(class, "container")) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = -ENOTTY;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering n_ifindices = sd_machine_get_ifindices(name, &ifindices);
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering if (n_ifindices < 0) {
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering r = n_ifindices;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_open_system(&bus);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_call_method(bus,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "org.freedesktop.machine1",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "/org/freedesktop/machine1",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "org.freedesktop.machine1.Manager",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "GetMachineAddresses",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering NULL,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering &reply,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "s", name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = count_addresses(reply, AF_UNSPEC, &c);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (c <= 0) {
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering *errnop = ESRCH;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *h_errnop = HOST_NOT_FOUND;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_NOTFOUND;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering l = strlen(name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (buflen < ms) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *errnop = ENOMEM;
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering *h_errnop = TRY_AGAIN;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_TRYAGAIN;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* First, append name */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_name = buffer;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering memcpy(r_name, name, l+1);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx = ALIGN(l+1);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* Second, append addresses */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int family;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering const void *a;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering size_t sz;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_read(reply, "i", &family);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_exit_container(reply);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering if (!IN_SET(family, AF_INET, AF_INET6)) {
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering r = -EAFNOSUPPORT;
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering goto fail;
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering }
555bd6e95bf2b469306d9cd86e126c0122d0895bLennart Poettering
9d485985338a46b8cb1acdf1af6c1eb2e88acfeeLennart Poettering if (sz != FAMILY_ADDRESS_SIZE(family)) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = -EINVAL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_tuple = (struct gaih_addrtuple*) (buffer + idx);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_tuple->name = r_name;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_tuple->family = family;
634af5665fda8776d22624d947c8de830e30a874Lennart Poettering r_tuple->scopeid = n_ifindices == 1 ? ifindices[0] : 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering memcpy(r_tuple->addr, a, sz);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx += ALIGN(sizeof(struct gaih_addrtuple));
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering i++;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(i == c);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_exit_container(reply);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(idx == ms);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (*pat)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering **pat = *r_tuple_first;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering else
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *pat = r_tuple_first;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (ttlp)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *ttlp = 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart 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
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_SUCCESS;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poetteringfail:
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *errnop = -r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *h_errnop = NO_DATA;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_UNAVAIL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering}
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poetteringenum nss_status _nss_mymachines_gethostbyname3_r(
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering const char *name,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int af,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering struct hostent *result,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering char *buffer, size_t buflen,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int *errnop, int *h_errnop,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int32_t *ttlp,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering char **canonp) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering _cleanup_bus_message_unref_ sd_bus_message* reply = NULL;
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering _cleanup_bus_close_unref_ sd_bus *bus = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering _cleanup_free_ char *class = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering unsigned c = 0, i = 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering char *r_name, *r_aliases, *r_addr, *r_addr_list;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering size_t l, idx, ms, alen;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering int r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(result);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(buffer);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(errnop);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(h_errnop);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (af == AF_UNSPEC)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering af = AF_INET;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (af != AF_INET && af != AF_INET6) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = -EAFNOSUPPORT;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_machine_get_class(name, &class);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (!streq(class, "container")) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = -ENOTTY;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_open_system(&bus);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_call_method(bus,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "org.freedesktop.machine1",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "/org/freedesktop/machine1",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "org.freedesktop.machine1.Manager",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "GetMachineAddresses",
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering NULL,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering &reply,
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering "s", name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = count_addresses(reply, af, &c);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (c <= 0) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *errnop = ENOENT;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *h_errnop = HOST_NOT_FOUND;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_NOTFOUND;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
9d485985338a46b8cb1acdf1af6c1eb2e88acfeeLennart Poettering alen = FAMILY_ADDRESS_SIZE(af);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering l = strlen(name);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering ms = ALIGN(l+1) +
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering sizeof(char*) +
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering (c > 0 ? c : 1) * ALIGN(alen) +
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering (c > 0 ? c+1 : 2) * sizeof(char*);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (buflen < ms) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *errnop = ENOMEM;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *h_errnop = NO_RECOVERY;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_TRYAGAIN;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* First, append name */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_name = buffer;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering memcpy(r_name, name, l+1);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx = ALIGN(l+1);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* Second, create aliases array */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_aliases = buffer + idx;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering ((char**) r_aliases)[0] = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx += sizeof(char*);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* Third, append addresses */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_addr = buffer + idx;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int family;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering const void *a;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering size_t sz;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_read(reply, "i", &family);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_exit_container(reply);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (family != af)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering continue;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (sz != alen) {
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = -EINVAL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering memcpy(r_addr + i*ALIGN(alen), a, alen);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering i++;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering }
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(i == c);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx += c * ALIGN(alen);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r = sd_bus_message_exit_container(reply);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (r < 0)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering goto fail;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering /* Third, append address pointer array */
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering r_addr_list = buffer + idx;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering for (i = 0; i < c; i++)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering ((char**) r_addr_list)[i] = NULL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering idx += (c+1) * sizeof(char*);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering assert(idx == ms);
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering result->h_name = r_name;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering result->h_aliases = (char**) r_aliases;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering result->h_addrtype = af;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering result->h_length = alen;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering result->h_addr_list = (char**) r_addr_list;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (ttlp)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *ttlp = 0;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering if (canonp)
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *canonp = r_name;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart 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
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_SUCCESS;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poetteringfail:
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *errnop = -r;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering *h_errnop = NO_DATA;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering return NSS_STATUS_UNAVAIL;
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering}
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart Poettering
cabb0bc6b1a4ec57e108dc99364687d7c4f9670fLennart PoetteringNSS_GETHOSTBYNAME_FALLBACKS(mymachines)