diff options
-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; |