1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-31 01:48:16 +03:00

winbind: Maintain a binding handle per domain and always go via wb_domain_request_send()

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13292

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Volker Lendecke <vl@samba.org>
(cherry picked from commit b518cb0597d269002105644302c58ca8f9f0f717)
This commit is contained in:
Volker Lendecke 2018-02-13 16:04:44 +01:00 committed by Stefan Metzmacher
parent 0dc0c594a0
commit 0465985286
4 changed files with 66 additions and 14 deletions

View File

@ -184,6 +184,8 @@ struct winbindd_domain {
struct winbindd_child *children;
struct dcerpc_binding_handle *binding_handle;
/* Callback we use to try put us back online. */
uint32_t check_online_timeout;

View File

@ -321,10 +321,7 @@ static struct winbindd_child *choose_domain_child(struct winbindd_domain *domain
struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain)
{
struct winbindd_child *child;
child = choose_domain_child(domain);
return child->binding_handle;
return domain->binding_handle;
}
struct wb_domain_request_state {
@ -608,8 +605,10 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
child->table = table;
child->queue = tevent_queue_create(NULL, "winbind_child");
SMB_ASSERT(child->queue != NULL);
child->binding_handle = wbint_binding_handle(NULL, domain, child);
SMB_ASSERT(child->binding_handle != NULL);
if (domain == NULL) {
child->binding_handle = wbint_binding_handle(NULL, NULL, child);
SMB_ASSERT(child->binding_handle != NULL);
}
}
void winbind_child_died(pid_t pid)

View File

@ -42,7 +42,7 @@ static bool wbint_bh_is_connected(struct dcerpc_binding_handle *h)
struct wbint_bh_state *hs = dcerpc_binding_handle_data(h,
struct wbint_bh_state);
if (!hs->child) {
if ((hs->domain == NULL) && (hs->child == NULL)) {
return false;
}
@ -65,7 +65,8 @@ struct wbint_bh_raw_call_state {
DATA_BLOB out_data;
};
static void wbint_bh_raw_call_done(struct tevent_req *subreq);
static void wbint_bh_raw_call_child_done(struct tevent_req *subreq);
static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq);
static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@ -114,17 +115,28 @@ static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx,
state->request.extra_data.data = (char *)state->in_data.data;
state->request.extra_len = state->in_data.length;
subreq = wb_child_request_send(state, ev, hs->child,
&state->request);
if (hs->child != NULL) {
subreq = wb_child_request_send(state, ev, hs->child,
&state->request);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(
subreq, wbint_bh_raw_call_child_done, req);
return req;
}
subreq = wb_domain_request_send(state, ev, hs->domain,
&state->request);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, wbint_bh_raw_call_done, req);
tevent_req_set_callback(subreq, wbint_bh_raw_call_domain_done, req);
return req;
}
static void wbint_bh_raw_call_done(struct tevent_req *subreq)
static void wbint_bh_raw_call_child_done(struct tevent_req *subreq)
{
struct tevent_req *req =
tevent_req_callback_data(subreq,
@ -158,6 +170,40 @@ static void wbint_bh_raw_call_done(struct tevent_req *subreq)
tevent_req_done(req);
}
static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq)
{
struct tevent_req *req =
tevent_req_callback_data(subreq,
struct tevent_req);
struct wbint_bh_raw_call_state *state =
tevent_req_data(req,
struct wbint_bh_raw_call_state);
int ret, err;
ret = wb_domain_request_recv(subreq, state, &state->response, &err);
TALLOC_FREE(subreq);
if (ret == -1) {
NTSTATUS status = map_nt_error_from_unix(err);
tevent_req_nterror(req, status);
return;
}
state->out_data = data_blob_talloc(state,
state->response->extra_data.data,
state->response->length - sizeof(struct winbindd_response));
if (state->response->extra_data.data && !state->out_data.data) {
tevent_req_oom(req);
return;
}
if (state->domain != NULL) {
wcache_store_ndr(state->domain, state->opnum,
&state->in_data, &state->out_data);
}
tevent_req_done(req);
}
static NTSTATUS wbint_bh_raw_call_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
uint8_t **out_data,
@ -209,9 +255,8 @@ static struct tevent_req *wbint_bh_disconnect_send(TALLOC_CTX *mem_ctx,
/*
* TODO: do a real async disconnect ...
*
* For now the caller needs to free rpc_cli
*/
hs->domain = NULL;
hs->child = NULL;
tevent_req_done(req);

View File

@ -228,6 +228,12 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
return NT_STATUS_NO_MEMORY;
}
domain->binding_handle = wbint_binding_handle(domain, domain, NULL);
if (domain->binding_handle == NULL) {
TALLOC_FREE(domain);
return NT_STATUS_NO_MEMORY;
}
domain->name = talloc_strdup(domain, domain_name);
if (domain->name == NULL) {
TALLOC_FREE(domain);