From 4051b70450b4d6b693e67e4a772911dad3ec0668 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 May 2018 20:47:49 +0200 Subject: [PATCH] winbindd: Make DOMAIN_INFO a proper async request This has an async code path hidden inside. Expose that properly. Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher --- source3/winbindd/winbindd.c | 5 +- source3/winbindd/winbindd_domain_info.c | 129 ++++++++++++++++++++++++ source3/winbindd/winbindd_misc.c | 106 ------------------- source3/winbindd/winbindd_proto.h | 9 +- source3/winbindd/wscript_build | 1 + 5 files changed, 139 insertions(+), 111 deletions(-) create mode 100644 source3/winbindd/winbindd_domain_info.c diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 28f048c2f26..1542edb6cb0 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -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 index 00000000000..126691a893e --- /dev/null +++ b/source3/winbindd/winbindd_domain_info.c @@ -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 . + */ + +#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; +} diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index c8b778db727..46273a99a1a 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -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; diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 7eb92fb6c9c..3b5423e48e2 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -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 */ diff --git a/source3/winbindd/wscript_build b/source3/winbindd/wscript_build index 0adbe9cbba1..a23c44566ed 100644 --- a/source3/winbindd/wscript_build +++ b/source3/winbindd/wscript_build @@ -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 -- 2.47.2