diff options
Diffstat (limited to 'source4/winbind/wb_sid2domain.c')
-rw-r--r-- | source4/winbind/wb_sid2domain.c | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/source4/winbind/wb_sid2domain.c b/source4/winbind/wb_sid2domain.c index 13cc318f76..8940c8e9b7 100644 --- a/source4/winbind/wb_sid2domain.c +++ b/source4/winbind/wb_sid2domain.c @@ -79,19 +79,24 @@ struct sid2domain_state { struct wbsrv_domain *my_domain; struct wbsrv_domain *result; + + struct netr_DsRGetDCName dsr_getdcname; + struct netr_GetAnyDCName getdcname; }; static void sid2domain_recv_name(struct composite_context *ctx); +static void sid2domain_recv_dsr_dcname(struct rpc_request *req); static void sid2domain_recv_dcname(struct composite_context *ctx); static void sid2domain_recv_init(struct composite_context *ctx); -struct composite_context *wb_sid2domain_send(struct wbsrv_service *service, +struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const struct dom_sid *sid) { struct composite_context *result, *ctx; struct sid2domain_state *state; - result = talloc_zero(NULL, struct composite_context); + result = talloc_zero(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -143,6 +148,7 @@ static void sid2domain_recv_name(struct composite_context *ctx) struct sid2domain_state *state = talloc_get_type(ctx->async.private_data, struct sid2domain_state); + struct rpc_request *req; struct wb_sid_object *name; state->ctx->status = wb_cmd_lookupsid_recv(ctx, state, &name); @@ -155,12 +161,61 @@ static void sid2domain_recv_name(struct composite_context *ctx) state->domain_name = name->domain; state->domain_sid = dom_sid_dup(state, state->sid); + if (composite_nomem(state->domain_sid, state->ctx)) return; + if (name->type != SID_NAME_DOMAIN) { state->domain_sid->num_auths -= 1; } - - ctx = wb_cmd_getdcname_send(state->service, state->my_domain, - state->domain_name); + + state->dsr_getdcname.in.server_unc = + talloc_asprintf(state, "\\\\%s", state->my_domain->dcname); + if (composite_nomem(state->dsr_getdcname.in.server_unc, + state->ctx)) return; + + state->dsr_getdcname.in.domain_name = state->domain_name; + state->dsr_getdcname.in.domain_guid = NULL; + state->dsr_getdcname.in.site_guid = NULL; + state->dsr_getdcname.in.flags = 0x40000000; + + req = dcerpc_netr_DsRGetDCName_send(state->my_domain->netlogon_pipe, + state, &state->dsr_getdcname); + composite_continue_rpc(state->ctx, req, sid2domain_recv_dsr_dcname, + state); +} + +static void sid2domain_recv_dsr_dcname(struct rpc_request *req) +{ + struct sid2domain_state *state = + talloc_get_type(req->async.private, + struct sid2domain_state); + struct composite_context *ctx; + + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + DEBUG(9, ("dcerpc_ndr_request_recv returned %s\n", + nt_errstr(state->ctx->status))); + goto fallback; + } + + state->ctx->status = + werror_to_ntstatus(state->dsr_getdcname.out.result); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + DEBUG(9, ("dsrgetdcname returned %s\n", + nt_errstr(state->ctx->status))); + goto fallback; + } + + DEBUG(0, ("unc: %s, addr: %s, addr_type: %d, domain_name: %s, " + "forest_name: %s\n", + state->dsr_getdcname.out.info->dc_unc, + state->dsr_getdcname.out.info->dc_address, + state->dsr_getdcname.out.info->dc_address_type, + state->dsr_getdcname.out.info->domain_name, + state->dsr_getdcname.out.info->forest_name)); + + fallback: + + ctx = wb_cmd_getdcname_send(state, state->service, state->domain_name); composite_continue(state->ctx, ctx, sid2domain_recv_dcname, state); } @@ -200,7 +255,10 @@ static void sid2domain_recv_init(struct composite_context *ctx) struct sid2domain_state); state->ctx->status = wb_init_domain_recv(ctx); - if (!composite_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) { + DEBUG(10, ("Could not init domain\n")); + return; + } composite_done(state->ctx); } @@ -219,10 +277,11 @@ NTSTATUS wb_sid2domain_recv(struct composite_context *ctx, return status; } -NTSTATUS wb_sid2domain(struct wbsrv_service *service, +NTSTATUS wb_sid2domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const struct dom_sid *sid, struct wbsrv_domain **result) { - struct composite_context *c = wb_sid2domain_send(service, sid); + struct composite_context *c = wb_sid2domain_send(mem_ctx, service, + sid); return wb_sid2domain_recv(c, result); } |