winbindd: Make DOMAIN_INFO a proper async request
authorVolker Lendecke <vl@samba.org>
Wed, 2 May 2018 18:47:49 +0000 (20:47 +0200)
committerVolker Lendecke <vl@samba.org>
Thu, 17 May 2018 06:44:19 +0000 (08:44 +0200)
This has an async code path hidden inside. Expose that properly.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/winbindd/winbindd.c
source3/winbindd/winbindd_domain_info.c [new file with mode: 0644]
source3/winbindd/winbindd_misc.c
source3/winbindd/winbindd_proto.h
source3/winbindd/wscript_build

index 28f048c2f265a1895a163778a1c68e192e6d7be5..1542edb6cb0bf5ed8bee73f3d847245e25ad23d3 100644 (file)
@@ -532,9 +532,6 @@ static struct winbindd_dispatch_table {
 
        /* Miscellaneous */
 
-       { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
-       /* Credential cache access */
-
        /* End of list */
 
        { WINBINDD_NUM_CMDS, NULL, "NONE" }
@@ -658,6 +655,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_wins_byip_send, winbindd_wins_byip_recv },
        { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
          winbindd_wins_byname_send, winbindd_wins_byname_recv },
+       { WINBINDD_DOMAIN_INFO, "DOMAIN_INFO",
+         winbindd_domain_info_send, winbindd_domain_info_recv },
 
        { 0, NULL, NULL, NULL }
 };
diff --git a/source3/winbindd/winbindd_domain_info.c b/source3/winbindd/winbindd_domain_info.c
new file mode 100644 (file)
index 0000000..126691a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * async implementation of WINBINDD_DOMAIN_INFO
+ * Copyright (C) Volker Lendecke 2018
+ *
+ * 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_domain_info_state {
+       struct winbindd_domain *domain;
+       struct winbindd_request ping_request;
+};
+
+static void winbindd_domain_info_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_domain_info_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct winbindd_cli_state *cli,
+       struct winbindd_request *request)
+{
+       struct tevent_req *req, *subreq;
+       struct winbindd_domain_info_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_domain_info_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid,
+                 cli->request->domain_name));
+
+       state->domain = find_domain_from_name_noinit(
+               cli->request->domain_name);
+
+       if (state->domain == NULL) {
+               DEBUG(3, ("Did not find domain [%s]\n",
+                         cli->request->domain_name));
+               tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
+               return tevent_req_post(req, ev);
+       }
+
+       if (state->domain->initialized) {
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
+       }
+
+       state->ping_request.cmd = WINBINDD_PING;
+
+       /*
+        * Send a ping down. This implicitly initializes the domain.
+        */
+
+       subreq = wb_domain_request_send(state, server_event_context(),
+                                       state->domain, &state->ping_request);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_domain_info_done, req);
+
+       return req;
+}
+
+static void winbindd_domain_info_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_domain_info_state *state = tevent_req_data(
+               req, struct winbindd_domain_info_state);
+       struct winbindd_response *response;
+       int ret, err;
+
+       ret = wb_domain_request_recv(subreq, state, &response, &err);
+       TALLOC_FREE(subreq);
+       if (ret == -1) {
+               DBG_DEBUG("wb_domain_request failed: %s\n", strerror(err));
+               tevent_req_nterror(req, map_nt_error_from_unix(err));
+               return;
+       }
+
+       if (!state->domain->initialized) {
+               DBG_INFO("wb_domain_request did not initialize domain %s\n",
+                        state->domain->name);
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_domain_info_recv(struct tevent_req *req,
+                                  struct winbindd_response *response)
+{
+       struct winbindd_domain_info_state *state = tevent_req_data(
+               req, struct winbindd_domain_info_state);
+       struct winbindd_domain *domain = state->domain;
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               DBG_DEBUG("winbindd_domain_info failed: %s\n",
+                         nt_errstr(status));
+               return status;
+       }
+
+       fstrcpy(response->data.domain_info.name, domain->name);
+       fstrcpy(response->data.domain_info.alt_name, domain->alt_name);
+       sid_to_fstring(response->data.domain_info.sid, &domain->sid);
+
+       response->data.domain_info.native_mode = domain->native_mode;
+       response->data.domain_info.active_directory = domain->active_directory;
+       response->data.domain_info.primary = domain->primary;
+
+       return NT_STATUS_OK;
+}
index c8b778db72728dcc9e3f1e3d144291ba4333f9fc..46273a99a1a5ad285e4564721c0df999c0d5af8c 100644 (file)
@@ -346,112 +346,6 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *
        return WINBINDD_OK;
 }
 
-struct domain_info_state {
-       struct winbindd_domain *domain;
-       struct winbindd_cli_state *cli;
-       struct winbindd_request ping_request;
-};
-
-static void domain_info_done(struct tevent_req *req);
-
-void winbindd_domain_info(struct winbindd_cli_state *cli)
-{
-       struct domain_info_state *state;
-       struct winbindd_domain *domain;
-       struct tevent_req *req;
-
-       DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid,
-                 cli->request->domain_name));
-
-       domain = find_domain_from_name_noinit(cli->request->domain_name);
-
-       if (domain == NULL) {
-               DEBUG(3, ("Did not find domain [%s]\n",
-                         cli->request->domain_name));
-               request_error(cli);
-               return;
-       }
-
-       if (domain->initialized) {
-               fstrcpy(cli->response->data.domain_info.name,
-                       domain->name);
-               fstrcpy(cli->response->data.domain_info.alt_name,
-                       domain->alt_name);
-               sid_to_fstring(cli->response->data.domain_info.sid,
-                              &domain->sid);
-               cli->response->data.domain_info.native_mode =
-                       domain->native_mode;
-               cli->response->data.domain_info.active_directory =
-                       domain->active_directory;
-               cli->response->data.domain_info.primary =
-                       domain->primary;
-               request_ok(cli);
-               return;
-       }
-
-       state = talloc_zero(cli->mem_ctx, struct domain_info_state);
-       if (state == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               request_error(cli);
-               return;
-       }
-
-       state->cli = cli;
-       state->domain = domain;
-       state->ping_request.cmd = WINBINDD_PING;
-
-       /*
-        * Send a ping down. This implicitly initializes the domain.
-        */
-
-       req = wb_domain_request_send(state, server_event_context(),
-                                    domain, &state->ping_request);
-       if (req == NULL) {
-               DEBUG(3, ("wb_domain_request_send failed\n"));
-               request_error(cli);
-               return;
-       }
-       tevent_req_set_callback(req, domain_info_done, state);
-}
-
-static void domain_info_done(struct tevent_req *req)
-{
-       struct domain_info_state *state = tevent_req_callback_data(
-               req, struct domain_info_state);
-       struct winbindd_response *response;
-       int ret, err;
-
-       ret = wb_domain_request_recv(req, req, &response, &err);
-       TALLOC_FREE(req);
-       if (ret == -1) {
-               DEBUG(10, ("wb_domain_request failed: %s\n", strerror(errno)));
-               request_error(state->cli);
-               return;
-       }
-       if (!state->domain->initialized) {
-               DEBUG(5, ("wb_domain_request did not initialize domain %s\n",
-                         state->domain->name));
-               request_error(state->cli);
-               return;
-       }
-
-       fstrcpy(state->cli->response->data.domain_info.name,
-               state->domain->name);
-       fstrcpy(state->cli->response->data.domain_info.alt_name,
-               state->domain->alt_name);
-       sid_to_fstring(state->cli->response->data.domain_info.sid,
-                      &state->domain->sid);
-
-       state->cli->response->data.domain_info.native_mode =
-               state->domain->native_mode;
-       state->cli->response->data.domain_info.active_directory =
-               state->domain->active_directory;
-       state->cli->response->data.domain_info.primary =
-               state->domain->primary;
-
-       request_ok(state->cli);
-}
-
 bool winbindd_dc_info(struct winbindd_cli_state *cli)
 {
        struct winbindd_domain *domain;
index 7eb92fb6c9cc606398382f3ebc7c47c2ea662032..3b5423e48e2564891dac7c729b646d0a92d15918 100644 (file)
@@ -385,7 +385,6 @@ bool winbindd_list_trusted_domains(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
                                                        struct winbindd_cli_state *state);
 void winbindd_show_sequence(struct winbindd_cli_state *state);
-void winbindd_domain_info(struct winbindd_cli_state *state);
 bool winbindd_dc_info(struct winbindd_cli_state *state);
 bool winbindd_ping(struct winbindd_cli_state *state);
 bool winbindd_info(struct winbindd_cli_state *state);
@@ -941,7 +940,13 @@ struct tevent_req *winbindd_wins_byname_send(TALLOC_CTX *mem_ctx,
                                             struct winbindd_request *request);
 NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req,
                                   struct winbindd_response *presp);
-
+struct tevent_req *winbindd_domain_info_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct winbindd_cli_state *cli,
+       struct winbindd_request *request);
+NTSTATUS winbindd_domain_info_recv(struct tevent_req *req,
+                                  struct winbindd_response *response);
 
 /* The following definitions come from winbindd/winbindd_samr.c  */
 
index 0adbe9cbba1bc1a6b802d7b998b243138ea0269e..a23c44566ed45596b57b858e033eb74d580faacb 100644 (file)
@@ -249,6 +249,7 @@ bld.SAMBA3_BINARY('winbindd',
                  winbindd_change_machine_acct.c
                  winbindd_irpc.c
                  winbindd_ping_dc.c
+                 winbindd_domain_info.c
                  winbindd_pam_auth.c
                  winbindd_pam_logoff.c
                  winbindd_pam_chauthtok.c