[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1292-g2774a02

Volker Lendecke vlendec at samba.org
Sat Aug 29 11:54:28 MDT 2009


The branch, master has been updated
       via  2774a02f64a57d981924e0fc65b23060803cc469 (commit)
       via  6b474c56a5a1cfaf11dec1c35c7510ba06f175b1 (commit)
      from  a95955f285ea13a3feddafa75edf8d2031d39403 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2774a02f64a57d981924e0fc65b23060803cc469
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 29 17:17:47 2009 +0200

    s3:winbind: Convert WINBINDD_LIST_GROUPS to the new API

commit 6b474c56a5a1cfaf11dec1c35c7510ba06f175b1
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Aug 29 16:05:02 2009 +0200

    s3:winbind: Convert WINBINDD_LIST_USERS to the new API

-----------------------------------------------------------------------

Summary of changes:
 source3/Makefile.in                     |    2 +
 source3/winbindd/winbindd.c             |    6 +-
 source3/winbindd/winbindd_async.c       |  180 ---------------------------
 source3/winbindd/winbindd_domain.c      |    8 --
 source3/winbindd/winbindd_group.c       |    6 -
 source3/winbindd/winbindd_list_groups.c |  204 +++++++++++++++++++++++++++++++
 source3/winbindd/winbindd_list_users.c  |  204 +++++++++++++++++++++++++++++++
 source3/winbindd/winbindd_misc.c        |  122 ------------------
 source3/winbindd/winbindd_proto.h       |   15 +++
 source3/winbindd/winbindd_user.c        |    6 -
 10 files changed, 429 insertions(+), 324 deletions(-)
 create mode 100644 source3/winbindd/winbindd_list_groups.c
 create mode 100644 source3/winbindd/winbindd_list_users.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 55baff2..ebf6024 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1209,6 +1209,8 @@ WINBINDD_OBJ1 = \
 		winbindd/winbindd_endgrent.o \
 		winbindd/winbindd_dsgetdcname.o \
 		winbindd/winbindd_getdcname.o \
+		winbindd/winbindd_list_users.o \
+		winbindd/winbindd_list_groups.o \
 		auth/token_util.o \
 		../nsswitch/libwbclient/wb_reqtrans.o \
 		smbd/connection.o
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 5dac932..e583dae 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -435,8 +435,6 @@ static struct winbindd_dispatch_table {
 
 	/* Enumeration functions */
 
-	{ WINBINDD_LIST_USERS, winbindd_list_users, "LIST_USERS" },
-	{ WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
 	{ WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
 	  "LIST_TRUSTDOM" },
 
@@ -537,6 +535,10 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_getgrent_send, winbindd_getgrent_recv },
 	{ WINBINDD_ENDGRENT, "ENDGRENT",
 	  winbindd_endgrent_send, winbindd_endgrent_recv },
+	{ WINBINDD_LIST_USERS, "LIST_USERS",
+	  winbindd_list_users_send, winbindd_list_users_recv },
+	{ WINBINDD_LIST_GROUPS, "LIST_GROUPS",
+	  winbindd_list_groups_send, winbindd_list_groups_recv },
 
 	{ 0, NULL, NULL, NULL }
 };
diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c
index 1e63ed1..6c5d92e 100644
--- a/source3/winbindd/winbindd_async.c
+++ b/source3/winbindd/winbindd_async.c
@@ -454,163 +454,6 @@ enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
 	return WINBINDD_OK;
 }
 
-/* This is the first callback after enumerating users/groups from a domain */
-static void listent_recv(TALLOC_CTX *mem_ctx, bool success,
-	                    struct winbindd_response *response,
-			    void *c, void *private_data)
-{
-	void (*cont)(void *priv, bool succ, fstring dom_name, char *data) =
-		(void (*)(void *, bool, fstring, char*))c;
-
-	if (!success || response->result != WINBINDD_OK) {
-		DEBUG(5, ("list_ent() failed!\n"));
-		cont(private_data, False, response->data.name.dom_name, NULL);
-		return;
-	}
-
-	cont(private_data, True, response->data.name.dom_name,
-	     (char *)response->extra_data.data);
-}
-
-/* Request the name of all users/groups in a single domain */
-void winbindd_listent_async(TALLOC_CTX *mem_ctx,
-	                       struct winbindd_domain *domain,
-	                       void (*cont)(void *private_data, bool success,
-				     fstring dom_name, char* extra_data),
-			       void *private_data, enum ent_type type)
-{
-	struct winbindd_request request;
-
-	ZERO_STRUCT(request);
-	if (type == LIST_USERS)
-		request.cmd = WINBINDD_LIST_USERS;
-	else if (type == LIST_GROUPS)
-		request.cmd = WINBINDD_LIST_GROUPS;
-
-	do_async_domain(mem_ctx, domain, &request, listent_recv,
-		        (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_list_users(struct winbindd_domain *domain,
-                                              struct winbindd_cli_state *state)
-{
-	struct wbint_userinfo *info;
-	NTSTATUS status;
-	struct winbindd_methods *methods;
-	uint32 num_entries = 0;
-	char *extra_data;
-	uint32_t extra_data_len = 0, i;
-
-	/* Must copy domain into response first for debugging in parent */
-	fstrcpy(state->response->data.name.dom_name, domain->name);
-
-	/* Query user info */
-	methods = domain->methods;
-	status = methods->query_user_list(domain, state->mem_ctx, 
-					  &num_entries, &info);
-
-	if (!NT_STATUS_IS_OK(status))
-		return WINBINDD_ERROR;
-
-	if (num_entries == 0)
-		return WINBINDD_OK;
-
-	/* Allocate some memory for extra data.  Note that we limit
-	   account names to sizeof(fstring) = 256 characters.		
-	   +1 for the ',' between group names */
-	extra_data = talloc_array(state->mem_ctx, char,
-				  (sizeof(fstring) + 1) * num_entries);
-
-	if (!extra_data) {
-		DEBUG(0,("failed to enlarge buffer!\n"));
-		return WINBINDD_ERROR;
-	}
-
-	/* Pack user list into extra data fields */
-	for (i = 0; i < num_entries; i++) {
-		fstring acct_name, name;
-
-		if (info[i].acct_name == NULL)
-			fstrcpy(acct_name, "");
-		else
-			fstrcpy(acct_name, info[i].acct_name);
-
-		fill_domain_username(name, domain->name, acct_name, True);
-		/* Append to extra data */
-		memcpy(&extra_data[extra_data_len], name, strlen(name));
-		extra_data_len += strlen(name);
-		extra_data[extra_data_len++] = ',';
-	}   
-
-	/* Assign extra_data fields in response structure */
-	if (extra_data) {
-		/* remove trailing ',' */
-		extra_data[extra_data_len - 1] = '\0';
-		state->response->extra_data.data = extra_data;
-		state->response->length += extra_data_len;
-	}
-
-	return WINBINDD_OK;
-}
-
-enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain,
-                                               struct winbindd_cli_state *state)
-{
-	struct getent_state groups;
-	char *extra_data;
-	uint32_t extra_data_len = 0, i;
-
-	ZERO_STRUCT(groups);
-
-	/* Must copy domain into response first for debugging in parent */
-	fstrcpy(state->response->data.name.dom_name, domain->name);
-	fstrcpy(groups.domain_name, domain->name);
-
-	/* Get list of sam groups */
-	if (!get_sam_group_entries(&groups)) {
-		/* this domain is empty or in an error state */
-		return WINBINDD_ERROR;
-	}
-
-	/* Allocate some memory for extra data.  Note that we limit
-	   account names to sizeof(fstring) = 256 characters.
-	   +1 for the ',' between group names */
-	extra_data = talloc_array(
-		state->mem_ctx, char,
-		(sizeof(fstring) + 1) * groups.num_sam_entries);
-
-	if (!extra_data) {
-		DEBUG(0,("failed to enlarge buffer!\n"));
-		SAFE_FREE(groups.sam_entries);
-		return WINBINDD_ERROR;
-	}
-
-	/* Pack group list into extra data fields */
-	for (i = 0; i < groups.num_sam_entries; i++) {
-		char *group_name = ((struct acct_info *)
-				    groups.sam_entries)[i].acct_name;
-		fstring name;
-
-		fill_domain_username(name, domain->name, group_name, True);
-		/* Append to extra data */
-		memcpy(&extra_data[extra_data_len], name, strlen(name));
-		extra_data_len += strlen(name);
-		extra_data[extra_data_len++] = ',';
-	}
-
-	SAFE_FREE(groups.sam_entries);
-
-	/* Assign extra_data fields in response structure */
-	if (extra_data) {
-		/* remove trailing ',' */
-		extra_data[extra_data_len - 1] = '\0';
-		state->response->extra_data.data = extra_data;
-		state->response->length += extra_data_len;
-	}
-
-	return WINBINDD_OK;
-}
-
 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
 		   size_t num_sids, char **result, ssize_t *len)
 {
@@ -671,29 +514,6 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
 	return True;
 }
 
-static bool parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr,
-			  uint32 **rids, size_t *num_rids)
-{
-	char *p;
-
-	p = ridstr;
-	if (p == NULL)
-		return False;
-
-	while (p[0] != '\0') {
-		uint32 rid;
-		char *q;
-		rid = strtoul(p, &q, 10);
-		if (*q != '\n') {
-			DEBUG(0, ("Got invalid ridstr: %s\n", p));
-			return False;
-		}
-		p = q+1;
-		ADD_TO_ARRAY(mem_ctx, uint32, rid, rids, num_rids);
-	}
-	return True;
-}
-
 static void getsidaliases_recv(TALLOC_CTX *mem_ctx, bool success,
 			       struct winbindd_response *response,
 			       void *c, void *private_data)
diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c
index 14376c6..107c83a 100644
--- a/source3/winbindd/winbindd_domain.c
+++ b/source3/winbindd/winbindd_domain.c
@@ -50,14 +50,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
 		.struct_cmd	= WINBINDD_LOOKUPNAME,
 		.struct_fn	= winbindd_dual_lookupname,
 	},{
-		.name		= "LIST_USERS",
-		.struct_cmd	= WINBINDD_LIST_USERS,
-		.struct_fn	= winbindd_dual_list_users,
-	},{
-		.name		= "LIST_GROUPS",
-		.struct_cmd	= WINBINDD_LIST_GROUPS,
-		.struct_fn	= winbindd_dual_list_groups,
-	},{
 		.name		= "LIST_TRUSTDOM",
 		.struct_cmd	= WINBINDD_LIST_TRUSTDOM,
 		.struct_fn	= winbindd_dual_list_trusted_domains,
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index 8a76071..eab5c26 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -201,12 +201,6 @@ bool get_sam_group_entries(struct getent_state *ent)
 	return result;
 }
 
-/* List domain groups without mapping to unix ids */
-void winbindd_list_groups(struct winbindd_cli_state *state)
-{
-	winbindd_list_ent(state, LIST_GROUPS);
-}
-
 /* Get user supplementary groups.  This is much quicker than trying to
    invert the groups database.  We merge the groups from the gids and
    other_sids info3 fields as trusted domain, universal group
diff --git a/source3/winbindd/winbindd_list_groups.c b/source3/winbindd/winbindd_list_groups.c
new file mode 100644
index 0000000..3795045
--- /dev/null
+++ b/source3/winbindd/winbindd_list_groups.c
@@ -0,0 +1,204 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_LIST_GROUPS
+   Copyright (C) Volker Lendecke 2009
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "librpc/gen_ndr/cli_wbint.h"
+
+struct winbindd_list_groups_domstate {
+	struct tevent_req *subreq;
+	struct winbindd_domain *domain;
+	struct wbint_Principals groups;
+};
+
+struct winbindd_list_groups_state {
+	int num_received;
+	/* All domains */
+	int num_domains;
+	struct winbindd_list_groups_domstate *domains;
+};
+
+static void winbindd_list_groups_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_list_groups_send(TALLOC_CTX *mem_ctx,
+					     struct tevent_context *ev,
+					     struct winbindd_cli_state *cli,
+					     struct winbindd_request *request)
+{
+	struct tevent_req *req;
+	struct winbindd_list_groups_state *state;
+	struct winbindd_domain *domain;
+	int i;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct winbindd_list_groups_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	/* Ensure null termination */
+	request->domain_name[sizeof(request->domain_name)-1]='\0';
+
+	DEBUG(3, ("list_groups %s\n", request->domain_name));
+
+	if (request->domain_name[0] != '\0') {
+		state->num_domains = 1;
+	} else {
+		state->num_domains = 0;
+		for (domain = domain_list(); domain; domain = domain->next) {
+			state->num_domains += 1;
+		}
+	}
+
+	state->domains = talloc_array(state,
+				      struct winbindd_list_groups_domstate,
+				      state->num_domains);
+	if (tevent_req_nomem(state->domains, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	if (request->domain_name[0] != '\0') {
+		state->domains[0].domain = find_domain_from_name_noinit(
+			request->domain_name);
+		if (state->domains[0].domain == NULL) {
+			tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
+			return tevent_req_post(req, ev);
+		}
+	} else {
+		i = 0;
+		for (domain = domain_list(); domain; domain = domain->next) {
+			state->domains[i++].domain = domain;
+		}
+	}
+
+	for (i=0; i<state->num_domains; i++) {
+		struct winbindd_list_groups_domstate *d = &state->domains[i];
+
+		d->subreq = rpccli_wbint_QueryGroupList_send(
+			state->domains, ev, d->domain->child.rpccli,
+			&d->groups);
+		if (tevent_req_nomem(d->subreq, req)) {
+			TALLOC_FREE(state->domains);
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(d->subreq, winbindd_list_groups_done,
+					req);
+	}
+	state->num_received = 0;
+	return req;
+}
+
+static void winbindd_list_groups_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct winbindd_list_groups_state *state = tevent_req_data(
+		req, struct winbindd_list_groups_state);
+	NTSTATUS status, result;
+	int i;
+
+	status = rpccli_wbint_QueryGroupList_recv(subreq, state->domains,
+						  &result);
+
+	for (i=0; i<state->num_domains; i++) {
+		if (subreq == state->domains[i].subreq) {
+			break;
+		}
+	}
+	if (i < state->num_domains) {
+		struct winbindd_list_groups_domstate *d = &state->domains[i];
+
+		DEBUG(10, ("Domain %s returned %d users\n", d->domain->name,
+			   d->groups.num_principals));
+
+		d->subreq = NULL;
+
+		if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(result)) {
+			DEBUG(10, ("list_groups for domain %s failed\n",
+				   d->domain->name));
+			d->groups.num_principals = 0;
+		}
+	}
+
+	TALLOC_FREE(subreq);
+
+	state->num_received += 1;
+
+	if (state->num_received >= state->num_domains) {
+		tevent_req_done(req);
+	}
+}
+
+NTSTATUS winbindd_list_groups_recv(struct tevent_req *req,
+				   struct winbindd_response *response)
+{
+	struct winbindd_list_groups_state *state = tevent_req_data(
+		req, struct winbindd_list_groups_state);
+	NTSTATUS status;
+	char *result;
+	int i;
+	uint32_t j;
+	size_t len;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+
+	len = 0;
+	for (i=0; i<state->num_domains; i++) {
+		struct winbindd_list_groups_domstate *d = &state->domains[i];
+
+		for (j=0; j<d->groups.num_principals; j++) {
+			fstring name;
+			fill_domain_username(name, d->domain->name,
+					     d->groups.principals[j].name,
+					     True);
+			len += strlen(name)+1;
+		}
+	}
+
+	result = talloc_array(response, char, len+1);
+	if (result == 0) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	len = 0;
+	for (i=0; i<state->num_domains; i++) {
+		struct winbindd_list_groups_domstate *d = &state->domains[i];
+
+		for (j=0; j<d->groups.num_principals; j++) {
+			fstring name;
+			size_t this_len;
+			fill_domain_username(name, d->domain->name,
+					     d->groups.principals[j].name,
+					     True);
+			this_len = strlen(name);
+			memcpy(result+len, name, this_len);
+			len += this_len;
+			result[len] = ',';
+			len += 1;
+		}
+	}
+	result[len-1] = '\0';
+
+	response->extra_data.data = result;
+	response->length += len;
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/winbindd/winbindd_list_users.c b/source3/winbindd/winbindd_list_users.c
new file mode 100644
index 0000000..19232b7
--- /dev/null
+++ b/source3/winbindd/winbindd_list_users.c
@@ -0,0 +1,204 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_LIST_USERS
+   Copyright (C) Volker Lendecke 2009
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the


-- 
Samba Shared Repository


More information about the samba-cvs mailing list