s3:winbind: change getgroups to only do one sids2xids call instead of many
authorMichael Adam <obnox@samba.org>
Fri, 26 Jul 2013 10:25:27 +0000 (12:25 +0200)
committerMichael Adam <obnox@samba.org>
Mon, 29 Jul 2013 10:53:55 +0000 (12:53 +0200)
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Michael Adam <obnox@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/winbindd/winbindd_getgroups.c

index 3d52ce83292fa062b694fb3c7eb5a3c340b4ce3b..445de3dcd9792b9c9836082177d0541bc099d7f8 100644 (file)
@@ -29,7 +29,6 @@ struct winbindd_getgroups_state {
        enum lsa_SidType type;
        int num_sids;
        struct dom_sid *sids;
-       int next_sid;
        int num_gids;
        gid_t *gids;
 };
@@ -129,15 +128,8 @@ static void winbindd_getgroups_gettoken_done(struct tevent_req *subreq)
         * complete token.
         */
 
-       state->gids = talloc_array(state, gid_t, state->num_sids);
-       if (tevent_req_nomem(state->gids, req)) {
-               return;
-       }
-       state->num_gids = 0;
-       state->next_sid = 0;
-
        subreq = wb_sids2xids_send(state, state->ev,
-                                  &state->sids[state->next_sid], 1);
+                                  state->sids, state->num_sids);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -151,12 +143,19 @@ static void winbindd_getgroups_sid2gid_done(struct tevent_req *subreq)
        struct winbindd_getgroups_state *state = tevent_req_data(
                req, struct winbindd_getgroups_state);
        NTSTATUS status;
-       struct unixid xid;
+       struct unixid *xids;
+       int i;
 
-       xid.type = ID_TYPE_NOT_SPECIFIED;
-       xid.id = UINT32_MAX;
+       xids = talloc_array(state, struct unixid, state->num_sids);
+       if (tevent_req_nomem(xids, req)) {
+               return;
+       }
+       for (i=0; i < state->num_sids; i++) {
+               xids[i].type = ID_TYPE_NOT_SPECIFIED;
+               xids[i].id = UINT32_MAX;
+       }
 
-       status = wb_sids2xids_recv(subreq, &xid);
+       status = wb_sids2xids_recv(subreq, xids);
        TALLOC_FREE(subreq);
        if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) ||
            NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
@@ -167,26 +166,43 @@ static void winbindd_getgroups_sid2gid_done(struct tevent_req *subreq)
                return;
        }
 
-       if (xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH) {
-               state->gids[state->num_gids] = (gid_t)xid.id;
-               state->num_gids += 1;
-       } else {
-               state->gids[state->num_gids] = (uid_t)-1;
+       state->gids = talloc_array(state, gid_t, state->num_sids);
+       if (tevent_req_nomem(state->gids, req)) {
+               return;
        }
+       state->num_gids = 0;
 
-       state->next_sid += 1;
+       for (i=0; i < state->num_sids; i++) {
+               bool include_gid = false;
 
-       if (state->next_sid >= state->num_sids) {
-               tevent_req_done(req);
-               return;
+               switch (xids[i].type) {
+               case ID_TYPE_NOT_SPECIFIED:
+               case ID_TYPE_UID:
+                       break;
+               case ID_TYPE_GID:
+               case ID_TYPE_BOTH:
+                       include_gid = true;
+                       break;
+               }
+
+               if (!include_gid) {
+                       continue;
+               }
+
+               state->gids[state->num_gids] = (gid_t)xids[i].id;
+               state->num_gids += 1;
        }
 
-       subreq = wb_sids2xids_send(state, state->ev,
-                                  &state->sids[state->next_sid], 1);
-       if (tevent_req_nomem(subreq, req)) {
+       /*
+        * This should not fail, as it does not do any reallocation,
+        * just updating the talloc size.
+        */
+       state->gids = talloc_realloc(state, state->gids, gid_t, state->num_gids);
+       if (tevent_req_nomem(state->gids, req)) {
                return;
        }
-       tevent_req_set_callback(subreq, winbindd_getgroups_sid2gid_done, req);
+
+       tevent_req_done(req);
 }
 
 NTSTATUS winbindd_getgroups_recv(struct tevent_req *req,