diff options
-rw-r--r-- | source3/winbindd/winbindd_getgroups.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index 3d52ce8329..445de3dcd9 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -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, |