diff options
author | Tim Potter <tpot@samba.org> | 2003-06-16 03:30:53 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2003-06-16 03:30:53 +0000 |
commit | 7c16f64e38874b491687cdaf9120651556454bde (patch) | |
tree | 61e4913d311addc6c74914a3a8072da5ed7904ca | |
parent | 35d0f987dbbe4479797cd8c99d03b829a7133264 (diff) | |
download | samba-7c16f64e38874b491687cdaf9120651556454bde.tar.gz samba-7c16f64e38874b491687cdaf9120651556454bde.tar.bz2 samba-7c16f64e38874b491687cdaf9120651556454bde.zip |
Update nsstest to cope with wins NSS module as well as winbind NSS
module. Use "wins" as the nss name to invoke this behaviour.
Also, fixed nsstest so it doesn't segfault when a nss function can't
be dlopened(). Log an error and abort the test gracefully instead.
(This used to be commit 66bafbe371359bbdec402ae47bc15024bec33f4e)
-rw-r--r-- | source3/torture/nsstest.c | 195 |
1 files changed, 183 insertions, 12 deletions
diff --git a/source3/torture/nsstest.c b/source3/torture/nsstest.c index a82fa05203..d23ac82f32 100644 --- a/source3/torture/nsstest.c +++ b/source3/torture/nsstest.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. nss tester for winbindd Copyright (C) Andrew Tridgell 2001 + Copyright (C) Tim Potter 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,6 +45,7 @@ static void *find_fn(const char *name) res = sys_dlsym(h, s); if (!res) { printf("Can't find function %s\n", s); + total_errors++; return NULL; } return res; @@ -65,6 +67,9 @@ static struct passwd *nss_getpwent(void) static char buf[1000]; NSS_STATUS status; + if (!_nss_getpwent_r) + return NULL; + status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno); if (status == NSS_STATUS_NOTFOUND) { return NULL; @@ -83,6 +88,9 @@ static struct passwd *nss_getpwnam(const char *name) static struct passwd pwd; static char buf[1000]; NSS_STATUS status; + + if (!_nss_getpwnam_r) + return NULL; status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno); if (status == NSS_STATUS_NOTFOUND) { @@ -102,6 +110,9 @@ static struct passwd *nss_getpwuid(uid_t uid) static struct passwd pwd; static char buf[1000]; NSS_STATUS status; + + if (!_nss_getpwuid_r) + return NULL; status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno); if (status == NSS_STATUS_NOTFOUND) { @@ -118,6 +129,10 @@ static void nss_setpwent(void) { NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent"); NSS_STATUS status; + + if (!_nss_setpwent) + return; + status = _nss_setpwent(); if (status != NSS_STATUS_SUCCESS) { report_nss_error("setpwent", status); @@ -128,6 +143,10 @@ static void nss_endpwent(void) { NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent"); NSS_STATUS status; + + if (!_nss_endpwent) + return; + status = _nss_endpwent(); if (status != NSS_STATUS_SUCCESS) { report_nss_error("endpwent", status); @@ -144,7 +163,11 @@ static struct group *nss_getgrent(void) static int buflen = 1024; NSS_STATUS status; - if (!buf) buf = malloc(buflen); + if (!_nss_getgrent_r) + return NULL; + + if (!buf) + buf = malloc(buflen); again: status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno); @@ -172,7 +195,11 @@ static struct group *nss_getgrnam(const char *name) static int buflen = 1000; NSS_STATUS status; - if (!buf) buf = malloc(buflen); + if (!_nss_getgrnam_r) + return NULL; + + if (!buf) + buf = malloc(buflen); again: status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { @@ -199,7 +226,12 @@ static struct group *nss_getgrgid(gid_t gid) static int buflen = 1000; NSS_STATUS status; - if (!buf) buf = malloc(buflen); + if (!_nss_getgrgid_r) + return NULL; + + if (!buf) + buf = malloc(buflen); + again: status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno); if (status == NSS_STATUS_TRYAGAIN) { @@ -221,6 +253,10 @@ static void nss_setgrent(void) { NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent"); NSS_STATUS status; + + if (!_nss_setgrent) + return; + status = _nss_setgrent(); if (status != NSS_STATUS_SUCCESS) { report_nss_error("setgrent", status); @@ -231,6 +267,10 @@ static void nss_endgrent(void) { NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent"); NSS_STATUS status; + + if (!_nss_endgrent) + return; + status = _nss_endgrent(); if (status != NSS_STATUS_SUCCESS) { report_nss_error("endgrent", status); @@ -244,7 +284,8 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta find_fn("initgroups_dyn"); NSS_STATUS status; - if (!_nss_initgroups) return NSS_STATUS_UNAVAIL; + if (!_nss_initgroups) + return NSS_STATUS_UNAVAIL; status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno); if (status != NSS_STATUS_SUCCESS) { @@ -284,7 +325,7 @@ static void print_group(struct group *grp) printf("%s\n", grp->gr_mem[i]); } -static void nss_test_initgroups(char *name, gid_t gid) +static void nss_test_winbind_initgroups(char *name, gid_t gid) { long int size = 16; long int start = 1; @@ -308,7 +349,7 @@ static void nss_test_initgroups(char *name, gid_t gid) } -static void nss_test_users(void) +static void nss_test_winbind_users(void) { struct passwd *pwd; @@ -331,13 +372,13 @@ static void nss_test_users(void) continue; } printf("getpwnam: "); print_passwd(pwd); - printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid); + printf("initgroups: "); nss_test_winbind_initgroups(pwd->pw_name, pwd->pw_gid); printf("\n"); } nss_endpwent(); } -static void nss_test_groups(void) +static void nss_test_winbind_groups(void) { struct group *grp; @@ -365,7 +406,7 @@ static void nss_test_groups(void) nss_endgrent(); } -static void nss_test_errors(void) +static void nss_test_winbind_errors(void) { struct passwd *pwd; struct group *grp; @@ -395,15 +436,145 @@ static void nss_test_errors(void) } } +static struct hostent *nss_gethostbyname(const char *name) +{ + NSS_STATUS (*_nss_gethostbyname_r)(const char *, struct hostent *, + char *, size_t, int *, int *) = + find_fn("gethostbyname_r"); + NSS_STATUS status; + static struct hostent he; + static char *buf; + static int buflen = 1000; + int h_nss_errnop; /* "Other" error information stored here */ + + if (!_nss_gethostbyname_r) + return NULL; + + if (!buf) + buf = malloc(buflen); + +again: + status = _nss_gethostbyname_r( + name, &he, buf, buflen, &nss_errno, &h_nss_errnop) ; + + if (status == NSS_STATUS_TRYAGAIN) { + buflen *= 2; + buf = realloc(buf, buflen); + goto again; + } + + if (status == NSS_STATUS_NOTFOUND) + return NULL; + + + if (status != NSS_STATUS_SUCCESS) { + report_nss_error("gethostbyname", status); + return NULL; + } + + return &he; +} + +static struct hostent *nss_gethostbyname2(const char *name, int af) +{ + NSS_STATUS (*_nss_gethostbyname2_r)(const char *, int, + struct hostent *, char *, size_t, + int *, int *) = + find_fn("gethostbyname2_r"); + NSS_STATUS status; + static struct hostent he; + static char *buf; + static int buflen = 1000; + int h_nss_errnop; /* "Other" error information stored here */ + + if (!_nss_gethostbyname2_r) + return NULL; + + if (!buf) + buf = malloc(buflen); + +again: + status = _nss_gethostbyname2_r( + name, af, &he, buf, buflen, &nss_errno, &h_nss_errnop) ; + + if (status == NSS_STATUS_TRYAGAIN) { + buflen *= 2; + buf = realloc(buf, buflen); + goto again; + } + + if (status == NSS_STATUS_NOTFOUND) + return NULL; + + + if (status != NSS_STATUS_SUCCESS) { + report_nss_error("gethostbyname2", status); + return NULL; + } + + return &he; +} + +static void nss_test_wins(void) +{ + fstring myname; + struct hostent *he; + + /* Try testing with our hostname. This will probably work if + Samba is/was running on the local machine. */ + + memset(myname, 0, sizeof(myname)); + if (gethostname(myname, sizeof(myname) - 1) == -1) { + printf("gethostname() failed!"); + total_errors++; + return; + } + + /* Test gethostbyname */ + + if ((he = nss_gethostbyname(myname))) { + struct in_addr **ip_list = (struct in_addr **)he->h_addr_list; + + while (*ip_list) { + printf("gethostbyname: %s has ip %s\n", myname, + inet_ntoa(**ip_list)); + *ip_list++; + } + } else + printf("hostname %s not found with gethostbyname\n", myname); + + /* Test gethostbyname2 */ + + if ((he = nss_gethostbyname2(myname, AF_INET))) { + struct in_addr **ip_list = (struct in_addr **)he->h_addr_list; + + while (*ip_list) { + printf("gethostbyname2: %s has ip %s\n", myname, + inet_ntoa(**ip_list)); + *ip_list++; + } + } else + printf("hostname %s not found with gethostbyname2\n", myname); +} + int main(int argc, char *argv[]) { if (argc > 1) so_path = argv[1]; if (argc > 2) nss_name = argv[2]; - nss_test_users(); - nss_test_groups(); - nss_test_errors(); + if (strequal(nss_name, "winbind")) { + nss_test_winbind_users(); + nss_test_winbind_groups(); + nss_test_winbind_errors(); + goto done; + } + if (strequal(nss_name, "wins")) { + nss_test_wins(); + goto done; + } + +done: printf("total_errors=%d\n", total_errors); return total_errors; |