Files
libvirt/tests/nsstest.c
T

195 lines
5.6 KiB
C
Raw Normal View History

2016-02-15 14:02:05 +01:00
/*
* Copyright (C) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "testutils.h"
2020-06-02 17:26:54 +02:00
#ifdef WITH_NSS
2016-02-15 14:02:05 +01:00
# include "libvirt_nss.h"
2020-01-14 17:38:59 +00:00
# include "virsocket.h"
2016-02-15 14:02:05 +01:00
# define VIR_FROM_THIS VIR_FROM_NONE
# define BUF_SIZE 1024
struct testNSSData {
const char *hostname;
const char *const *ipAddr;
int af;
};
static int
testGetHostByName(const void *opaque)
{
const struct testNSSData *data = opaque;
const bool existent = data->hostname && data->ipAddr && data->ipAddr[0];
struct hostent resolved;
char buf[BUF_SIZE] = { 0 };
char **addrList;
int rv, tmp_errno = 0, tmp_herrno = 0;
2019-07-10 14:30:11 +02:00
size_t i = 0;
2016-02-15 14:02:05 +01:00
memset(&resolved, 0, sizeof(resolved));
2016-12-04 11:56:44 +01:00
rv = NSS_NAME(gethostbyname2)(data->hostname,
data->af,
&resolved,
buf, sizeof(buf),
&tmp_errno,
&tmp_herrno);
2016-02-15 14:02:05 +01:00
if (rv == NSS_STATUS_TRYAGAIN ||
rv == NSS_STATUS_UNAVAIL ||
rv == NSS_STATUS_RETURN) {
/* Resolving failed in unexpected fashion. */
virReportError(VIR_ERR_INTERNAL_ERROR,
"Resolving of %s failed due to internal error",
data->hostname);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
} else if (rv == NSS_STATUS_NOTFOUND) {
/* Resolving failed. Should it? */
if (!existent)
2019-11-12 17:46:29 -03:00
return 0;
2016-02-15 14:02:05 +01:00
else
virReportError(VIR_ERR_INTERNAL_ERROR,
"Resolving of %s failed",
data->hostname);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
/* Resolving succeeded. Should it? */
if (!existent) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"Resolving of %s succeeded but was expected to fail",
data->hostname);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
/* Now lets see if resolved address match our expectations. */
if (!resolved.h_name) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
"resolved.h_name empty");
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
if (data->af != AF_UNSPEC &&
resolved.h_addrtype != data->af) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"Expected AF_INET (%d) got %d",
data->af, resolved.h_addrtype);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
if ((resolved.h_addrtype == AF_INET && resolved.h_length != 4) ||
(resolved.h_addrtype == AF_INET6 && resolved.h_length != 16)) {
/* IPv4 addresses are encoded into 4 bytes */
virReportError(VIR_ERR_INTERNAL_ERROR,
"Expected %d bytes long address, got %d",
resolved.h_addrtype == AF_INET ? 4 : 16,
resolved.h_length);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
if (!resolved.h_addr_list) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
"resolved.h_addr_list empty");
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
addrList = resolved.h_addr_list;
2019-07-10 14:30:11 +02:00
i = 0;
2016-02-15 14:02:05 +01:00
while (*addrList) {
virSocketAddr sa;
2021-09-04 22:37:44 +02:00
g_autofree char *ipAddr = NULL;
void *address = *addrList;
2016-02-15 14:02:05 +01:00
memset(&sa, 0, sizeof(sa));
if (resolved.h_addrtype == AF_INET) {
virSocketAddrSetIPv4AddrNetOrder(&sa, *((uint32_t *) address));
2016-02-15 14:02:05 +01:00
} else {
virSocketAddrSetIPv6AddrNetOrder(&sa, address);
2016-02-15 14:02:05 +01:00
}
if (!(ipAddr = virSocketAddrFormat(&sa))) {
/* error reported by helper */
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
2019-07-10 14:30:11 +02:00
if (STRNEQ_NULLABLE(data->ipAddr[i], ipAddr)) {
2016-02-15 14:02:05 +01:00
virReportError(VIR_ERR_INTERNAL_ERROR,
2019-07-10 14:30:11 +02:00
"Unexpected address %s, expecting %s",
ipAddr, NULLSTR(data->ipAddr[i]));
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
addrList++;
i++;
}
2019-07-10 14:30:11 +02:00
if (data->ipAddr[i]) {
2016-02-15 14:02:05 +01:00
virReportError(VIR_ERR_INTERNAL_ERROR,
2019-07-10 14:30:11 +02:00
"Expected %s address, got NULL",
data->ipAddr[i]);
2019-11-12 17:46:29 -03:00
return -1;
2016-02-15 14:02:05 +01:00
}
2019-11-12 17:46:29 -03:00
return 0;
2016-02-15 14:02:05 +01:00
}
static int
mymain(void)
{
int ret = 0;
2017-11-03 13:09:47 +01:00
# define DO_TEST(name, family, ...) \
do { \
const char *addr[] = { __VA_ARGS__, NULL}; \
struct testNSSData data = { \
.hostname = name, .ipAddr = addr, .af = family, \
}; \
if (virTestRun(name, testGetHostByName, &data) < 0) \
ret = -1; \
2016-02-15 14:02:05 +01:00
} while (0)
2016-11-29 13:48:53 +01:00
# if !defined(LIBVIRT_NSS_GUEST)
DO_TEST("fedora", AF_INET, "192.168.122.197", "192.168.122.198", "192.168.122.199", "192.168.122.3");
2016-02-15 14:02:05 +01:00
DO_TEST("gentoo", AF_INET, "192.168.122.254");
DO_TEST("gentoo", AF_INET6, "2001:1234:dead:beef::2");
DO_TEST("gentoo", AF_UNSPEC, "192.168.122.254");
DO_TEST("non-existent", AF_UNSPEC, NULL);
2016-11-29 13:48:53 +01:00
# else /* defined(LIBVIRT_NSS_GUEST) */
DO_TEST("debian", AF_INET, "192.168.122.2");
DO_TEST("suse", AF_INET, "192.168.122.3");
# endif /* defined(LIBVIRT_NSS_GUEST) */
2016-02-15 14:02:05 +01:00
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
2019-08-21 19:13:16 +03:00
VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("nss"))
2016-02-15 14:02:05 +01:00
#else
int
main(void)
{
return EXIT_AM_SKIP;
}
#endif