summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/winbind/struct_based.c220
1 files changed, 208 insertions, 12 deletions
diff --git a/source4/torture/winbind/struct_based.c b/source4/torture/winbind/struct_based.c
index 0477b7b111..78f9273903 100644
--- a/source4/torture/winbind/struct_based.c
+++ b/source4/torture/winbind/struct_based.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
SMB torture tester - winbind struct based protocol
Copyright (C) Stefan Metzmacher 2007
+ Copyright (C) Michael Adam 2007
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
@@ -99,6 +100,18 @@ static bool torture_winbind_struct_ping(struct torture_context *torture)
return true;
}
+
+static char winbind_separator(struct torture_context *torture)
+{
+ struct winbindd_response rep;
+
+ ZERO_STRUCT(rep);
+
+ DO_STRUCT_REQ_REP(WINBINDD_INFO, NULL, &rep);
+
+ return rep.data.info.winbind_separator;
+}
+
static bool torture_winbind_struct_info(struct torture_context *torture)
{
struct winbindd_response rep;
@@ -176,23 +189,34 @@ static bool torture_winbind_struct_netbios_name(struct torture_context *torture)
return true;
}
-static bool torture_winbind_struct_domain_name(struct torture_context *torture)
+static bool get_winbind_domain(struct torture_context *torture, char **domain)
{
struct winbindd_response rep;
- const char *expected;
ZERO_STRUCT(rep);
- torture_comment(torture, "Running WINBINDD_DOMAIN_NAME (struct based)\n");
-
DO_STRUCT_REQ_REP(WINBINDD_DOMAIN_NAME, NULL, &rep);
+ *domain = talloc_strdup(torture, rep.data.domain_name);
+ torture_assert(torture, domain, "talloc error");
+
+ return true;
+}
+
+static bool torture_winbind_struct_domain_name(struct torture_context *torture)
+{
+ const char *expected;
+ char *domain;
+
+ torture_comment(torture, "Running WINBINDD_DOMAIN_NAME (struct based)\n");
+
expected = torture_setting_string(torture,
"winbindd netbios domain",
lp_workgroup(global_loadparm));
- torture_assert_str_equal(torture,
- rep.data.domain_name, expected,
+ get_winbind_domain(torture, &domain);
+
+ torture_assert_str_equal(torture, domain, expected,
"winbindd's netbios domain doesn't match");
return true;
@@ -556,33 +580,103 @@ static bool torture_winbind_struct_dsgetdcname(struct torture_context *torture)
return true;
}
-static bool torture_winbind_struct_list_users(struct torture_context *torture)
+static bool get_user_list(struct torture_context *torture, char ***users)
{
struct winbindd_request req;
struct winbindd_response rep;
-
- torture_comment(torture, "Running WINBINDD_LIST_USERS (struct based)\n");
+ char **u = NULL;
+ uint32_t count;
+ fstring name;
+ const char *extra_data;
ZERO_STRUCT(req);
ZERO_STRUCT(rep);
DO_STRUCT_REQ_REP(WINBINDD_LIST_USERS, &req, &rep);
+ extra_data = (char *)rep.extra_data.data;
+ torture_assert(torture, extra_data, "NULL extra data");
+
+ for(count = 0;
+ next_token(&extra_data, name, ",", sizeof(fstring));
+ count++)
+ {
+ u = talloc_realloc(torture, u, char *, count + 2);
+ u[count+1] = NULL;
+ u[count] = talloc_strdup(u, name);
+ }
+
+ SAFE_FREE(rep.extra_data.data);
+
+ *users = u;
return true;
}
-static bool torture_winbind_struct_list_groups(struct torture_context *torture)
+static bool torture_winbind_struct_list_users(struct torture_context *torture)
+{
+ char **users;
+ uint32_t count;
+ bool ok;
+
+ torture_comment(torture, "Running WINBINDD_LIST_USERS (struct based)\n");
+
+ ok = get_user_list(torture, &users);
+ torture_assert(torture, ok, "failed to get group list");
+
+ for (count = 0; users[count]; count++) { }
+
+ torture_comment(torture, "got %d users\n", count);
+
+ return true;
+}
+
+static bool get_group_list(struct torture_context *torture, char ***groups)
{
struct winbindd_request req;
struct winbindd_response rep;
-
- torture_comment(torture, "Running WINBINDD_LIST_GROUPS (struct based)\n");
+ char **g = NULL;
+ uint32_t count;
+ fstring name;
+ const char *extra_data;
ZERO_STRUCT(req);
ZERO_STRUCT(rep);
DO_STRUCT_REQ_REP(WINBINDD_LIST_GROUPS, &req, &rep);
+ extra_data = (char *)rep.extra_data.data;
+ torture_assert(torture, extra_data, "NULL extra data");
+
+ for(count = 0;
+ next_token(&extra_data, name, ",", sizeof(fstring));
+ count++)
+ {
+ g = talloc_realloc(torture, g, char *, count + 2);
+ g[count+1] = NULL;
+ g[count] = talloc_strdup(g, name);
+ }
+
+ SAFE_FREE(rep.extra_data.data);
+
+ *groups = g;
+ return true;
+}
+
+static bool torture_winbind_struct_list_groups(struct torture_context *torture)
+{
+ char **groups;
+ uint32_t count;
+ bool ok;
+
+ torture_comment(torture, "Running WINBINDD_LIST_GROUPS (struct based)\n");
+
+ ok = get_group_list(torture, &groups);
+ torture_assert(torture, ok, "failed to get group list");
+
+ for (count = 0; groups[count]; count++) { }
+
+ torture_comment(torture, "got %d groups\n", count);
+
return true;
}
@@ -764,6 +858,107 @@ static bool torture_winbind_struct_endpwent(struct torture_context *torture)
return true;
}
+/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
+ form DOMAIN/user into a domain and a user */
+
+static bool parse_domain_user(struct torture_context *torture,
+ const char *domuser, fstring domain,
+ fstring user)
+{
+ char *p = strchr(domuser, winbind_separator(torture));
+ char *dom;
+
+ if (!p) {
+ /* Maybe it was a UPN? */
+ if ((p = strchr(domuser, '@')) != NULL) {
+ fstrcpy(domain, "");
+ fstrcpy(user, domuser);
+ return true;
+ }
+
+ fstrcpy(user, domuser);
+ get_winbind_domain(torture, &dom);
+ fstrcpy(domain, dom);
+ return true;
+ }
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper_m(domain);
+
+ return true;
+}
+
+static bool lookup_name_sid_list(struct torture_context *torture, char **list)
+{
+ uint32_t count;
+
+ for (count = 0; list[count]; count++) {
+ struct winbindd_request req;
+ struct winbindd_response rep;
+ char *sid;
+ char *name;
+
+ ZERO_STRUCT(req);
+ ZERO_STRUCT(rep);
+
+ parse_domain_user(torture, list[count], req.data.name.dom_name,
+ req.data.name.name);
+
+ DO_STRUCT_REQ_REP(WINBINDD_LOOKUPNAME, &req, &rep);
+
+ sid = talloc_strdup(torture, rep.data.sid.sid);
+
+ ZERO_STRUCT(req);
+ ZERO_STRUCT(rep);
+
+ fstrcpy(req.data.sid, sid);
+
+ DO_STRUCT_REQ_REP(WINBINDD_LOOKUPSID, &req, &rep);
+
+ name = talloc_asprintf(torture, "%s%c%s",
+ rep.data.name.dom_name,
+ winbind_separator(torture),
+ rep.data.name.name);
+
+ torture_assert_casestr_equal(torture, list[count], name,
+ "LOOKUP_SID after LOOKUP_NAME != id");
+
+#if 0
+ torture_comment(torture, " %s -> %s -> %s\n", list[count],
+ sid, name);
+#endif
+
+ talloc_free(sid);
+ talloc_free(name);
+ }
+
+ return true;
+}
+
+static bool torture_winbind_struct_lookup_name_sid(struct torture_context *torture)
+{
+ char **users;
+ char **groups;
+ uint32_t count;
+ bool ok;
+
+ torture_comment(torture, "Running WINBINDD_LOOKUP_NAME_SID (struct based)\n");
+
+ ok = get_user_list(torture, &users);
+ torture_assert(torture, ok, "failed to retrieve list of users");
+ lookup_name_sid_list(torture, users);
+ talloc_free(users);
+
+ ok = get_group_list(torture, &groups);
+ torture_assert(torture, ok, "failed to retrieve list of groups");
+ lookup_name_sid_list(torture, groups);
+ talloc_free(groups);
+
+ return true;
+}
+
struct torture_suite *torture_winbind_struct_init(void)
{
struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "STRUCT");
@@ -785,6 +980,7 @@ struct torture_suite *torture_winbind_struct_init(void)
torture_suite_add_simple_test(suite, "SETPWENT", torture_winbind_struct_setpwent);
torture_suite_add_simple_test(suite, "GETPWENT", torture_winbind_struct_getpwent);
torture_suite_add_simple_test(suite, "ENDPWENT", torture_winbind_struct_endpwent);
+ torture_suite_add_simple_test(suite, "LOOKUP_NAME_SID", torture_winbind_struct_lookup_name_sid);
suite->description = talloc_strdup(suite, "WINBIND - struct based protocol tests");