drs: Send DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP by default
[samba.git] / source3 / winbindd / wb_next_grent.c
index 54c4c1c440e06f1c497be52d685e48653abcdab1..fd925b609e5773fcca2b6b2d380944219eaad43a 100644 (file)
 
 #include "includes.h"
 #include "winbindd.h"
-#include "librpc/gen_ndr/ndr_wbint_c.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
+#include "passdb/machine_sid.h"
 
 struct wb_next_grent_state {
        struct tevent_context *ev;
        int max_nesting;
        struct getgrent_state *gstate;
-       struct wbint_Principals next_groups;
        struct winbindd_gr *gr;
        struct talloc_dict *members;
 };
@@ -33,50 +33,27 @@ struct wb_next_grent_state {
 static void wb_next_grent_fetch_done(struct tevent_req *subreq);
 static void wb_next_grent_getgrsid_done(struct tevent_req *subreq);
 
-struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
-                                     struct tevent_context *ev,
-                                     int max_nesting,
-                                     struct getgrent_state *gstate,
-                                     struct winbindd_gr *gr)
+static void wb_next_grent_send_do(struct tevent_req *req,
+                                 struct wb_next_grent_state *state)
 {
-       struct tevent_req *req, *subreq;
-       struct wb_next_grent_state *state;
-
-       req = tevent_req_create(mem_ctx, &state, struct wb_next_grent_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->ev = ev;
-       state->gstate = gstate;
-       state->gr = gr;
-       state->max_nesting = max_nesting;
+       struct tevent_req *subreq;
 
        if (state->gstate->next_group >= state->gstate->num_groups) {
                TALLOC_FREE(state->gstate->groups);
 
-               if (state->gstate->domain == NULL) {
-                       state->gstate->domain = domain_list();
-               } else {
-                       state->gstate->domain = state->gstate->domain->next;
-               }
-
-               if ((state->gstate->domain != NULL)
-                   && sid_check_is_domain(&state->gstate->domain->sid)) {
-                       state->gstate->domain = state->gstate->domain->next;
-               }
-
+               state->gstate->domain = wb_next_domain(state->gstate->domain);
                if (state->gstate->domain == NULL) {
                        tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-                       return tevent_req_post(req, ev);
+                       return;
                }
-               subreq = dcerpc_wbint_QueryGroupList_send(
-                       state, state->ev, dom_child_handle(state->gstate->domain),
-                       &state->next_groups);
+
+               subreq = wb_query_group_list_send(state, state->ev,
+                                                 state->gstate->domain);
                if (tevent_req_nomem(subreq, req)) {
-                       return tevent_req_post(req, ev);
+                       return;
                }
                tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
-               return req;
+               return;
        }
 
        subreq = wb_getgrsid_send(
@@ -84,9 +61,34 @@ struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
                &state->gstate->groups[state->gstate->next_group].sid,
                state->max_nesting);
        if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
+               return;
        }
        tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
+}
+
+struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
+                                     struct tevent_context *ev,
+                                     int max_nesting,
+                                     struct getgrent_state *gstate,
+                                     struct winbindd_gr *gr)
+{
+       struct tevent_req *req;
+       struct wb_next_grent_state *state;
+
+       req = tevent_req_create(mem_ctx, &state, struct wb_next_grent_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->gstate = gstate;
+       state->gr = gr;
+       state->max_nesting = max_nesting;
+
+       wb_next_grent_send_do(req, state);
+       if (!tevent_req_is_in_progress(req)) {
+               return tevent_req_post(req, ev);
+       }
+
        return req;
 }
 
@@ -96,64 +98,22 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct wb_next_grent_state *state = tevent_req_data(
                req, struct wb_next_grent_state);
-       NTSTATUS status, result;
+       NTSTATUS status;
 
-       status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result);
+       status = wb_query_group_list_recv(subreq, state->gstate,
+                                         &state->gstate->num_groups,
+                                         &state->gstate->groups);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                /* Ignore errors here, just log it */
-               DEBUG(10, ("query_user_list for domain %s returned %s\n",
-                          state->gstate->domain->name,
-                          nt_errstr(status)));
-               tevent_req_nterror(req, status);
-               return;
-       }
-       if (!NT_STATUS_IS_OK(result)) {
-               /* Ignore errors here, just log it */
-               DEBUG(10, ("query_user_list for domain %s returned %s/%s\n",
-                          state->gstate->domain->name,
-                          nt_errstr(status), nt_errstr(result)));
-               tevent_req_nterror(req, result);
-               return;
-       }
-
-       state->gstate->num_groups = state->next_groups.num_principals;
-       state->gstate->groups = talloc_move(
-               state->gstate, &state->next_groups.principals);
-
-       if (state->gstate->num_groups == 0) {
-               state->gstate->domain = state->gstate->domain->next;
-
-               if ((state->gstate->domain != NULL)
-                   && sid_check_is_domain(&state->gstate->domain->sid)) {
-                       state->gstate->domain = state->gstate->domain->next;
-               }
-
-               if (state->gstate->domain == NULL) {
-                       tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-                       return;
-               }
-               subreq = dcerpc_wbint_QueryGroupList_send(
-                       state, state->ev, dom_child_handle(state->gstate->domain),
-                       &state->next_groups);
-               if (tevent_req_nomem(subreq, req)) {
-                       return;
-               }
-               tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
-               return;
+               DEBUG(10, ("query_group_list for domain %s returned %s\n",
+                          state->gstate->domain->name, nt_errstr(status)));
+               state->gstate->num_groups = 0;
        }
 
        state->gstate->next_group = 0;
 
-       subreq = wb_getgrsid_send(
-               state, state->ev,
-               &state->gstate->groups[state->gstate->next_group].sid,
-               state->max_nesting);
-       if (tevent_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
-       return;
+       wb_next_grent_send_do(req, state);
 }
 
 static void wb_next_grent_getgrsid_done(struct tevent_req *subreq)
@@ -168,10 +128,17 @@ static void wb_next_grent_getgrsid_done(struct tevent_req *subreq)
        status = wb_getgrsid_recv(subreq, talloc_tos(), &domname, &name,
                                  &state->gr->gr_gid, &state->members);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+               state->gstate->next_group += 1;
+
+               wb_next_grent_send_do(req, state);
+
+               return;
+       } else if (tevent_req_nterror(req, status)) {
                return;
        }
+
        if (!fill_grent(talloc_tos(), state->gr, domname, name,
                        state->gr->gr_gid)) {
                DEBUG(5, ("fill_grent failed\n"));