summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/torture/nsstest.c195
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;