#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NSS_WRAPPER_HOSTNAME_ENV "NSS_WRAPPER_HOSTNAME" static void test_nwrap_gethostname(void **state) { const char *hostname = "milliways"; char sys_host[256] = {0}; char host[16] = {0}; int rc; (void) state; /* unused */ rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, hostname, 1); assert_int_equal(rc, 0); rc = gethostname(host, sizeof(host)); assert_int_equal(rc, 0); assert_string_equal(host, hostname); rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, "this_hostname_is_too_long", 1); assert_int_equal(rc, 0); rc = gethostname(host, sizeof(host)); assert_int_equal(rc, -1); assert_int_equal(errno, ENAMETOOLONG); unsetenv(NSS_WRAPPER_HOSTNAME_ENV); rc = gethostname(sys_host, sizeof(sys_host)); assert_int_equal(rc, 0); } static void *thread_test_gethostbyname(void *u) { struct hostent *he; (void) u; /* unused */ he = gethostbyname("magrathea"); assert_non_null(he); assert_non_null(he->h_name); assert_string_equal(he->h_name, "magrathea.galaxy.site"); pthread_exit(NULL); } static void test_nwrap_gethostbyname_thread(void **state) { struct hostent *he; pthread_t th; (void) state; /* unused */ he = gethostbyname("maximegalon.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_string_equal(he->h_name, "maximegalon.galaxy.site"); pthread_create(&th, NULL, &thread_test_gethostbyname, NULL); pthread_join(th, NULL); assert_non_null(he); assert_non_null(he->h_name); #ifdef BSD /* * On *BSD (and Mac OS X) systems, * data is stored in thread local storage. */ assert_string_equal(he->h_name, "maximegalon.galaxy.site"); #else /* * Glibc doesn't store data in thread local storage, so calling * gethostbyname from a thread overwrites the parent thread's data. */ assert_string_equal(he->h_name, "magrathea.galaxy.site"); #endif } static void test_nwrap_gethostbyname(void **state) { char ip[INET_ADDRSTRLEN]; struct hostent *he; const char *a; (void) state; /* unused */ he = gethostbyname("magrathea.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.11"); } static void test_nwrap_gethostbyname_multiple(void **state) { struct hostent *he; char **list; /* For inet_ntop call */ char buf[4096]; const char *result; char *p = buf; /* List of ips in hosts file - order matters */ const char *const result_ips[] = { "127.0.0.11", "127.0.0.12", NULL }; const char *actual_ip = result_ips[0]; unsigned int ac; (void) state; /* unused */ he = gethostbyname("magrathea.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); list = he->h_addr_list; for (ac = 0; *list != NULL; ++ac, ++list) { actual_ip = result_ips[ac]; /* When test fails here more records are returned */ assert_non_null(actual_ip); result = inet_ntop(AF_INET, *list, p, 4096); assert_non_null(p); assert_string_equal(actual_ip, result); } } #ifdef HAVE_GETHOSTBYNAME2 static void test_nwrap_gethostbyname2(void **state) { char ip[INET6_ADDRSTRLEN]; struct hostent *he; const char *a; (void) state; /* unused */ he = gethostbyname2("magrathea.galaxy.site", AF_INET6); assert_non_null(he); he = gethostbyname2("magrathea.galaxy.site", AF_INET); assert_non_null(he); /* Check ipv6 he */ he = gethostbyname2("krikkit.galaxy.site", AF_INET6); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "krikkit.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET6); a = inet_ntop(AF_INET6, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "::14"); /* Check ipv4 he */ he = gethostbyname2("krikkit.galaxy.site", AF_INET); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "krikkit.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.14"); } #endif /* HAVE_GETHOSTBYNAME2 */ static void test_nwrap_gethostbyaddr(void **state) { struct hostent *he; struct in_addr in; int rc; (void) state; /* unused */ rc = inet_aton("127.0.0.11", &in); assert_int_equal(rc, 1); he = gethostbyaddr(&in, sizeof(struct in_addr), AF_INET); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); assert_memory_equal(&in, he->h_addr_list[0], he->h_length); } #ifdef HAVE_GETHOSTBYNAME_R static void test_nwrap_gethostbyname_r(void **state) { char buf[1024] = {0}; char ip[INET_ADDRSTRLEN]; struct hostent hb, *he; const char *a; int herr = 0; int rc; (void) state; /* unused */ rc = gethostbyname_r("magrathea.galaxy.site", &hb, buf, sizeof(buf), &he, &herr); assert_int_equal(rc, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.11"); } #endif #ifdef HAVE_GETHOSTBYADDR_R static void test_nwrap_gethostbyaddr_r(void **state) { char buf[1024] = {0}; struct hostent hb, *he; struct in_addr in; int herr = 0; int rc; (void) state; /* unused */ rc = inet_aton("127.0.0.11", &in); assert_int_equal(rc, 1); rc = gethostbyaddr_r(&in, sizeof(struct in_addr), AF_INET, &hb, buf, sizeof(buf), &he, &herr); assert_int_equal(rc, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); assert_memory_equal(&in, he->h_addr_list[0], he->h_length); } #endif int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_gethostname), cmocka_unit_test(test_nwrap_gethostbyname), cmocka_unit_test(test_nwrap_gethostbyname_thread), #ifdef HAVE_GETHOSTBYNAME2 cmocka_unit_test(test_nwrap_gethostbyname2), #endif cmocka_unit_test(test_nwrap_gethostbyaddr), #ifdef HAVE_GETHOSTBYNAME_R cmocka_unit_test(test_nwrap_gethostbyname_r), #endif #ifdef HAVE_GETHOSTBYADDR_R cmocka_unit_test(test_nwrap_gethostbyaddr_r), #endif cmocka_unit_test(test_nwrap_gethostbyname_multiple), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; }