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 <[email protected]>
Date:   Sat Aug 29 17:17:47 2009 +0200

    s3:winbind: Convert WINBINDD_LIST_GROUPS to the new API

commit 6b474c56a5a1cfaf11dec1c35c7510ba06f175b1
Author: Volker Lendecke <[email protected]>
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

Reply via email to