s3:winbind: Convert winbindd_show_sequence to the new API
authorVolker Lendecke <vl@samba.org>
Sat, 15 Aug 2009 11:23:57 +0000 (13:23 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 16 Aug 2009 08:38:24 +0000 (10:38 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_misc.c
source3/winbindd/winbindd_proto.h
source3/winbindd/winbindd_show_sequence.c [new file with mode: 0644]

index 61fde565c282bc6bdcc306262c3ac99478c4836d..f1c645a576f65aee9bd02af1bc6c7cc6ae41191e 100644 (file)
@@ -1178,6 +1178,7 @@ WINBINDD_OBJ1 = \
                winbindd/winbindd_getsidaliases.o \
                winbindd/winbindd_getuserdomgroups.o \
                winbindd/winbindd_getgroups.o \
+               winbindd/winbindd_show_sequence.o \
                auth/token_util.o \
                ../nsswitch/libwbclient/wb_reqtrans.o \
                smbd/connection.o
index 348816b39cf2b9663f2a764a650176f2ad7f071c..3dfdb03374cabb94f1df4594e8f09ba45ff42dda 100644 (file)
@@ -456,7 +456,6 @@ static struct winbindd_dispatch_table {
        { WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
        { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
          "LIST_TRUSTDOM" },
-       { WINBINDD_SHOW_SEQUENCE, winbindd_show_sequence, "SHOW_SEQUENCE" },
 
        /* SID related functions */
 
@@ -534,6 +533,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
        { WINBINDD_GETGROUPS, "GETGROUPS",
          winbindd_getgroups_send, winbindd_getgroups_recv },
+       { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
+         winbindd_show_sequence_send, winbindd_show_sequence_recv },
 
        { 0, NULL, NULL, NULL }
 };
index c6608316d1c5a8770b13e40d36d90d4f0018bf08..7b1091143450fe3fb22cad508b1ad7cb4f2e7ce1 100644 (file)
@@ -506,117 +506,6 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
        return WINBINDD_OK;
 }
 
-struct sequence_state {
-       TALLOC_CTX *mem_ctx;
-       struct winbindd_cli_state *cli_state;
-       struct winbindd_domain *domain;
-       struct winbindd_request *request;
-       struct winbindd_response *response;
-       char *extra_data;
-};
-
-static void sequence_recv(void *private_data, bool success);
-
-void winbindd_show_sequence(struct winbindd_cli_state *state)
-{
-       struct sequence_state *seq;
-
-       /* Ensure null termination */
-       state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';
-
-       if (strlen(state->request->domain_name) > 0) {
-               struct winbindd_domain *domain;
-               domain = find_domain_from_name_noinit(
-                       state->request->domain_name);
-               if (domain == NULL) {
-                       request_error(state);
-                       return;
-               }
-               sendto_domain(state, domain);
-               return;
-       }
-
-       /* Ask all domains in sequence, collect the results in sequence_recv */
-
-       seq = TALLOC_P(state->mem_ctx, struct sequence_state);
-       if (seq == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               request_error(state);
-               return;
-       }
-
-       seq->mem_ctx = state->mem_ctx;
-       seq->cli_state = state;
-       seq->domain = domain_list();
-       if (seq->domain == NULL) {
-               DEBUG(0, ("domain list empty\n"));
-               request_error(state);
-               return;
-       }
-       seq->request = TALLOC_ZERO_P(state->mem_ctx,
-                                    struct winbindd_request);
-       seq->response = TALLOC_ZERO_P(state->mem_ctx,
-                                     struct winbindd_response);
-       seq->extra_data = talloc_strdup(state->mem_ctx, "");
-
-       if ((seq->request == NULL) || (seq->response == NULL) ||
-           (seq->extra_data == NULL)) {
-               DEBUG(0, ("talloc failed\n"));
-               request_error(state);
-               return;
-       }
-
-       seq->request->length = sizeof(*seq->request);
-       seq->request->cmd = WINBINDD_SHOW_SEQUENCE;
-       fstrcpy(seq->request->domain_name, seq->domain->name);
-
-       async_domain_request(state->mem_ctx, seq->domain,
-                            seq->request, seq->response,
-                            sequence_recv, seq);
-}
-
-static void sequence_recv(void *private_data, bool success)
-{
-       struct sequence_state *state =
-               (struct sequence_state *)private_data;
-       uint32 seq = DOM_SEQUENCE_NONE;
-
-       if ((success) && (state->response->result == WINBINDD_OK))
-               seq = state->response->data.sequence_number;
-
-       if (seq == DOM_SEQUENCE_NONE) {
-               state->extra_data = talloc_asprintf(state->mem_ctx,
-                                                   "%s%s : DISCONNECTED\n",
-                                                   state->extra_data,
-                                                   state->domain->name);
-       } else {
-               state->extra_data = talloc_asprintf(state->mem_ctx,
-                                                   "%s%s : %d\n",
-                                                   state->extra_data,
-                                                   state->domain->name, seq);
-       }
-
-       state->domain->sequence_number = seq;
-
-       state->domain = state->domain->next;
-
-       if (state->domain == NULL) {
-               struct winbindd_cli_state *cli_state = state->cli_state;
-               cli_state->response->length =
-                       sizeof(struct winbindd_response) +
-                       strlen(state->extra_data) + 1;
-               cli_state->response->extra_data.data = state->extra_data;
-               request_ok(cli_state);
-               return;
-       }
-
-       /* Ask the next domain */
-       fstrcpy(state->request->domain_name, state->domain->name);
-       async_domain_request(state->mem_ctx, state->domain,
-                            state->request, state->response,
-                            sequence_recv, state);
-}
-
 /* This is the child-only version of --sequence. It only allows for a single
  * domain (ie "our" one) to be displayed. */
 
index a144c99c80f9f74a01c0bb1d9c7f2ed187924c67..e0ac48e070be6ab3d9bbec6a9af3b3e5b063d878 100644 (file)
@@ -778,4 +778,11 @@ NTSTATUS wb_seqnums_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                         int *num_domains, struct winbindd_domain ***domains,
                         NTSTATUS **stati, uint32_t **seqnums);
 
+struct tevent_req *winbindd_show_sequence_send(TALLOC_CTX *mem_ctx,
+                                              struct tevent_context *ev,
+                                              struct winbindd_request *request);
+NTSTATUS winbindd_show_sequence_recv(struct tevent_req *req,
+                                    struct winbindd_response *response);
+
+
 #endif /*  _WINBINDD_PROTO_H_  */
diff --git a/source3/winbindd/winbindd_show_sequence.c b/source3/winbindd/winbindd_show_sequence.c
new file mode 100644 (file)
index 0000000..b40996c
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_SHOW_SEQUENCE
+   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"
+
+struct winbindd_show_sequence_state {
+       bool one_domain;
+       /* One domain */
+       uint32_t seqnum;
+
+       /* All domains */
+       int num_domains;
+       NTSTATUS *stati;
+       struct winbindd_domain **domains;
+       uint32_t *seqnums;
+};
+
+static void winbindd_show_sequence_done_one(struct tevent_req *subreq);
+static void winbindd_show_sequence_done_all(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_show_sequence_send(TALLOC_CTX *mem_ctx,
+                                              struct tevent_context *ev,
+                                              struct winbindd_request *request)
+{
+       struct tevent_req *req, *subreq;
+       struct winbindd_show_sequence_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_show_sequence_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->one_domain = false;
+       state->domains = NULL;
+       state->stati = NULL;
+       state->seqnums = NULL;
+
+       /* Ensure null termination */
+       request->domain_name[sizeof(request->domain_name)-1]='\0';
+
+       DEBUG(3, ("show_sequence %s\n", request->domain_name));
+
+       if (request->domain_name[0] != '\0') {
+               struct winbindd_domain *domain;
+
+               state->one_domain = true;
+
+               domain = find_domain_from_name_noinit(
+                       request->domain_name);
+               if (domain == NULL) {
+                       tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
+                       return tevent_req_post(req, ev);
+               }
+
+               subreq = wb_seqnum_send(state, ev, domain);
+               if (tevent_req_nomem(subreq, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               tevent_req_set_callback(
+                       subreq, winbindd_show_sequence_done_one, req);
+               return req;
+       }
+
+       subreq = wb_seqnums_send(state, ev);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_show_sequence_done_all, req);
+       return req;
+}
+
+static void winbindd_show_sequence_done_one(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_show_sequence_state *state = tevent_req_data(
+               req, struct winbindd_show_sequence_state);
+       NTSTATUS status;
+
+       status = wb_seqnum_recv(subreq, &state->seqnum);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static void winbindd_show_sequence_done_all(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_show_sequence_state *state = tevent_req_data(
+               req, struct winbindd_show_sequence_state);
+       NTSTATUS status;
+
+       status = wb_seqnums_recv(subreq, state, &state->num_domains,
+                                &state->domains, &state->stati,
+                                &state->seqnums);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_show_sequence_recv(struct tevent_req *req,
+                                    struct winbindd_response *response)
+{
+       struct winbindd_show_sequence_state *state = tevent_req_data(
+               req, struct winbindd_show_sequence_state);
+       NTSTATUS status;
+       char *extra_data;
+       int i;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+
+       if (state->one_domain) {
+               response->data.sequence_number = state->seqnum;
+               return NT_STATUS_OK;
+       }
+
+       extra_data = talloc_strdup(response, "");
+       if (extra_data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i<state->num_domains; i++) {
+               if (!NT_STATUS_IS_OK(state->stati[i])
+                   || (state->seqnums[i] == DOM_SEQUENCE_NONE)) {
+                       extra_data = talloc_asprintf_append_buffer(
+                               extra_data, "%s : DISCONNECTED\n",
+                               state->domains[i]->name);
+               } else {
+                       extra_data = talloc_asprintf_append_buffer(
+                               extra_data, "%s : %d\n",
+                               state->domains[i]->name,
+                               (int)state->seqnums[i]);
+               }
+               if (extra_data == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       response->extra_data.data = extra_data;
+       response->length += talloc_get_size(extra_data);
+       return NT_STATUS_OK;
+}