diff options
-rw-r--r-- | source4/winbind/config.mk | 1 | ||||
-rw-r--r-- | source4/winbind/wb_async_helpers.c | 98 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_getdcname.c | 123 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_list_trustdom.c | 9 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_lookupname.c | 66 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_lookupsid.c | 65 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_userdomgroups.c | 83 | ||||
-rw-r--r-- | source4/winbind/wb_cmd_usersids.c | 271 | ||||
-rw-r--r-- | source4/winbind/wb_connect_lsa.c | 26 | ||||
-rw-r--r-- | source4/winbind/wb_connect_sam.c | 12 | ||||
-rw-r--r-- | source4/winbind/wb_domain_request.c | 155 | ||||
-rw-r--r-- | source4/winbind/wb_init_domain.c | 32 | ||||
-rw-r--r-- | source4/winbind/wb_pam_auth.c | 154 | ||||
-rw-r--r-- | source4/winbind/wb_samba3_cmd.c | 20 | ||||
-rw-r--r-- | source4/winbind/wb_server.h | 2 | ||||
-rw-r--r-- | source4/winbind/wb_sid2domain.c | 75 |
16 files changed, 489 insertions, 703 deletions
diff --git a/source4/winbind/config.mk b/source4/winbind/config.mk index 597c96549d..6ed4f51cfc 100644 --- a/source4/winbind/config.mk +++ b/source4/winbind/config.mk @@ -11,7 +11,6 @@ INIT_OBJ_FILES = \ wb_samba3_cmd.o \ wb_init_domain.o \ wb_sid2domain.o \ - wb_domain_request.o \ wb_connect_lsa.o \ wb_connect_sam.o \ wb_cmd_lookupname.o \ diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c index 29fd167a93..f00c0725b4 100644 --- a/source4/winbind/wb_async_helpers.c +++ b/source4/winbind/wb_async_helpers.c @@ -54,7 +54,8 @@ struct finddcs_state { static void finddcs_resolve(struct composite_context *ctx); static void finddcs_getdc(struct irpc_request *ireq); -struct composite_context *wb_finddcs_send(const char *domain_name, +struct composite_context *wb_finddcs_send(TALLOC_CTX *mem_ctx, + const char *domain_name, const struct dom_sid *domain_sid, struct event_context *event_ctx, struct messaging_context *msg_ctx) @@ -63,7 +64,7 @@ struct composite_context *wb_finddcs_send(const char *domain_name, struct finddcs_state *state; struct nbt_name name; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -150,7 +151,7 @@ static void finddcs_getdc(struct irpc_request *ireq) NTSTATUS wb_finddcs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, int *num_dcs, struct nbt_dc_name **dcs) { - NTSTATUS status =composite_wait(c); + NTSTATUS status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct finddcs_state *state = talloc_get_type(c->private_data, struct finddcs_state); @@ -161,13 +162,14 @@ NTSTATUS wb_finddcs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, return status; } -NTSTATUS wb_finddcs(const char *domain_name, const struct dom_sid *domain_sid, +NTSTATUS wb_finddcs(TALLOC_CTX *mem_ctx, + const char *domain_name, const struct dom_sid *domain_sid, struct event_context *event_ctx, struct messaging_context *msg_ctx, - TALLOC_CTX *mem_ctx, int *num_dcs, struct nbt_dc_name **dcs) { - struct composite_context *c = wb_finddcs_send(domain_name, domain_sid, + struct composite_context *c = wb_finddcs_send(mem_ctx, + domain_name, domain_sid, event_ctx, msg_ctx); return wb_finddcs_recv(c, mem_ctx, num_dcs, dcs); } @@ -188,14 +190,15 @@ static void get_schannel_creds_recv_auth(struct rpc_request *req); static void get_schannel_creds_recv_chal(struct rpc_request *req); static void get_schannel_creds_recv_pipe(struct composite_context *ctx); -struct composite_context *wb_get_schannel_creds_send(struct cli_credentials *wks_creds, +struct composite_context *wb_get_schannel_creds_send(TALLOC_CTX *mem_ctx, + struct cli_credentials *wks_creds, struct smbcli_tree *tree, struct event_context *ev) { struct composite_context *result, *ctx; struct get_schannel_creds_state *state; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -349,14 +352,15 @@ NTSTATUS wb_get_schannel_creds_recv(struct composite_context *c, return status; } -NTSTATUS wb_get_schannel_creds(struct cli_credentials *wks_creds, +NTSTATUS wb_get_schannel_creds(TALLOC_CTX *mem_ctx, + struct cli_credentials *wks_creds, struct smbcli_tree *tree, struct event_context *event_ctx, - TALLOC_CTX *mem_ctx, struct dcerpc_pipe **netlogon_pipe) { struct composite_context *c = - wb_get_schannel_creds_send(wks_creds, tree, event_ctx); + wb_get_schannel_creds_send(mem_ctx, wks_creds, tree, + event_ctx); return wb_get_schannel_creds_recv(c, mem_ctx, netlogon_pipe); } @@ -372,7 +376,8 @@ struct lsa_lookupsids_state { static void lsa_lookupsids_recv_names(struct rpc_request *req); -struct composite_context *wb_lsa_lookupsids_send(struct dcerpc_pipe *lsa_pipe, +struct composite_context *wb_lsa_lookupsids_send(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *lsa_pipe, struct policy_handle *handle, int num_sids, const struct dom_sid **sids) @@ -382,7 +387,7 @@ struct composite_context *wb_lsa_lookupsids_send(struct dcerpc_pipe *lsa_pipe, struct lsa_lookupsids_state *state; int i; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -504,14 +509,15 @@ NTSTATUS wb_lsa_lookupsids_recv(struct composite_context *c, return status; } -NTSTATUS wb_lsa_lookupsids(struct dcerpc_pipe *lsa_pipe, +NTSTATUS wb_lsa_lookupsids(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *lsa_pipe, struct policy_handle *handle, int num_sids, const struct dom_sid **sids, - TALLOC_CTX *mem_ctx, struct wb_sid_object ***names) { struct composite_context *c = - wb_lsa_lookupsids_send(lsa_pipe, handle, num_sids, sids); + wb_lsa_lookupsids_send(mem_ctx, lsa_pipe, handle, + num_sids, sids); return wb_lsa_lookupnames_recv(c, mem_ctx, names); } @@ -528,7 +534,8 @@ struct lsa_lookupnames_state { static void lsa_lookupnames_recv_sids(struct rpc_request *req); -struct composite_context *wb_lsa_lookupnames_send(struct dcerpc_pipe *lsa_pipe, +struct composite_context *wb_lsa_lookupnames_send(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *lsa_pipe, struct policy_handle *handle, int num_names, const char **names) @@ -540,7 +547,7 @@ struct composite_context *wb_lsa_lookupnames_send(struct dcerpc_pipe *lsa_pipe, struct lsa_String *lsa_names; int i; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -647,14 +654,15 @@ NTSTATUS wb_lsa_lookupnames_recv(struct composite_context *c, return status; } -NTSTATUS wb_lsa_lookupnames(struct dcerpc_pipe *lsa_pipe, +NTSTATUS wb_lsa_lookupnames(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *lsa_pipe, struct policy_handle *handle, int num_names, const char **names, - TALLOC_CTX *mem_ctx, struct wb_sid_object ***sids) { struct composite_context *c = - wb_lsa_lookupnames_send(lsa_pipe, handle, num_names, names); + wb_lsa_lookupnames_send(mem_ctx, lsa_pipe, handle, + num_names, names); return wb_lsa_lookupnames_recv(c, mem_ctx, sids); } @@ -723,49 +731,6 @@ NTSTATUS wb_cmd_checkmachacc(struct wbsrv_call *call) return wb_cmd_checkmachacc_recv(c); } -static void composite_netr_LogonSamLogon_recv_rpc(struct rpc_request *req); - -struct composite_context *composite_netr_LogonSamLogon_send(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct netr_LogonSamLogon *r) -{ - struct composite_context *result; - struct rpc_request *req; - - result = talloc(mem_ctx, struct composite_context); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->async.fn = NULL; - result->event_ctx = p->conn->event_ctx; - - req = dcerpc_netr_LogonSamLogon_send(p, mem_ctx, r); - if (req == NULL) goto failed; - req->async.callback = composite_netr_LogonSamLogon_recv_rpc; - req->async.private = result; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void composite_netr_LogonSamLogon_recv_rpc(struct rpc_request *req) -{ - struct composite_context *ctx = - talloc_get_type(req->async.private, struct composite_context); - - ctx->status = dcerpc_ndr_request_recv(req); - if (!composite_is_ok(ctx)) return; - composite_done(ctx); -} - -NTSTATUS composite_netr_LogonSamLogon_recv(struct composite_context *ctx) -{ - NTSTATUS status = composite_wait(ctx); - talloc_free(ctx); - return status; -} - struct samr_getuserdomgroups_state { struct composite_context *ctx; struct dcerpc_pipe *samr_pipe; @@ -783,7 +748,8 @@ static void samr_usergroups_recv_open(struct rpc_request *req); static void samr_usergroups_recv_groups(struct rpc_request *req); static void samr_usergroups_recv_close(struct rpc_request *req); -struct composite_context *wb_samr_userdomgroups_send(struct dcerpc_pipe *samr_pipe, +struct composite_context *wb_samr_userdomgroups_send(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *samr_pipe, struct policy_handle *domain_handle, uint32_t rid) { @@ -791,7 +757,7 @@ struct composite_context *wb_samr_userdomgroups_send(struct dcerpc_pipe *samr_pi struct rpc_request *req; struct samr_getuserdomgroups_state *state; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; diff --git a/source4/winbind/wb_cmd_getdcname.c b/source4/winbind/wb_cmd_getdcname.c index 72e0ba0efd..8cca3197a1 100644 --- a/source4/winbind/wb_cmd_getdcname.c +++ b/source4/winbind/wb_cmd_getdcname.c @@ -28,49 +28,6 @@ #include "librpc/gen_ndr/ndr_netlogon.h" -static void composite_netr_GetAnyDCName_recv_rpc(struct rpc_request *req); - -static struct composite_context *composite_netr_GetAnyDCName_send(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct netr_GetAnyDCName *r) -{ - struct composite_context *result; - struct rpc_request *req; - - result = talloc(mem_ctx, struct composite_context); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->async.fn = NULL; - result->event_ctx = p->conn->event_ctx; - - req = dcerpc_netr_GetAnyDCName_send(p, mem_ctx, r); - if (req == NULL) goto failed; - req->async.callback = composite_netr_GetAnyDCName_recv_rpc; - req->async.private = result; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void composite_netr_GetAnyDCName_recv_rpc(struct rpc_request *req) -{ - struct composite_context *ctx = - talloc_get_type(req->async.private, struct composite_context); - - ctx->status = dcerpc_ndr_request_recv(req); - if (!composite_is_ok(ctx)) return; - composite_done(ctx); -} - -static NTSTATUS composite_netr_GetAnyDCName_recv(struct composite_context *ctx) -{ - NTSTATUS status = composite_wait(ctx); - talloc_free(ctx); - return status; -} - struct cmd_getdcname_state { struct composite_context *ctx; const char *domain_name; @@ -78,59 +35,77 @@ struct cmd_getdcname_state { struct netr_GetAnyDCName g; }; -static struct composite_context *getdcname_send_req(struct wbsrv_domain *domain, - void *p); -static NTSTATUS getdcname_recv_req(struct composite_context *ctx, void *p); +static void getdcname_recv_domain(struct composite_context *ctx); +static void getdcname_recv_dcname(struct rpc_request *req); -struct composite_context *wb_cmd_getdcname_send(struct wbsrv_service *service, - struct wbsrv_domain *domain, +struct composite_context *wb_cmd_getdcname_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const char *domain_name) { + struct composite_context *result, *ctx; struct cmd_getdcname_state *state; - state = talloc(NULL, struct cmd_getdcname_state); + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = service->task->event_ctx; + + state = talloc(result, struct cmd_getdcname_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; + state->domain_name = talloc_strdup(state, domain_name); - state->ctx = wb_domain_request_send(state, service, - service->primary_sid, - getdcname_send_req, - getdcname_recv_req, - state); - if (state->ctx == NULL) { - talloc_free(state); - return NULL; - } - state->ctx->private_data = state; - return state->ctx; + if (state->domain_name == NULL) goto failed; + + ctx = wb_sid2domain_send(state, service, service->primary_sid); + if (ctx == NULL) goto failed; + + ctx->async.fn = getdcname_recv_domain; + ctx->async.private_data = state; + return result; + + failed: + talloc_free(result); + return NULL; } -static struct composite_context *getdcname_send_req(struct wbsrv_domain *domain, void *p) +static void getdcname_recv_domain(struct composite_context *ctx) { struct cmd_getdcname_state *state = - talloc_get_type(p, struct cmd_getdcname_state); + talloc_get_type(ctx->async.private_data, + struct cmd_getdcname_state); + struct wbsrv_domain *domain; + struct rpc_request *req; + + state->ctx->status = wb_sid2domain_recv(ctx, &domain); + if (!composite_is_ok(state->ctx)) return; state->g.in.logon_server = talloc_asprintf( state, "\\\\%s", dcerpc_server_name(domain->netlogon_pipe)); state->g.in.domainname = state->domain_name; - return composite_netr_GetAnyDCName_send(domain->netlogon_pipe, - state, &state->g); + req = dcerpc_netr_GetAnyDCName_send(domain->netlogon_pipe, state, + &state->g); + if (composite_nomem(req, state->ctx)) return; + + composite_continue_rpc(state->ctx, req, getdcname_recv_dcname, state); } -static NTSTATUS getdcname_recv_req(struct composite_context *ctx, void *p) +static void getdcname_recv_dcname(struct rpc_request *req) { struct cmd_getdcname_state *state = - talloc_get_type(p, struct cmd_getdcname_state); - NTSTATUS status; + talloc_get_type(req->async.private, + struct cmd_getdcname_state); - status = composite_netr_GetAnyDCName_recv(ctx); - NT_STATUS_NOT_OK_RETURN(status); - - if (!W_ERROR_IS_OK(state->g.out.result)) { - return werror_to_ntstatus(state->g.out.result); - } + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = werror_to_ntstatus(state->g.out.result); + if (!composite_is_ok(state->ctx)) return; - return NT_STATUS_OK; + composite_done(state->ctx); } NTSTATUS wb_cmd_getdcname_recv(struct composite_context *c, diff --git a/source4/winbind/wb_cmd_list_trustdom.c b/source4/winbind/wb_cmd_list_trustdom.c index af93ea0643..c96da48712 100644 --- a/source4/winbind/wb_cmd_list_trustdom.c +++ b/source4/winbind/wb_cmd_list_trustdom.c @@ -48,12 +48,13 @@ static void cmd_list_trustdoms_recv_domain(struct composite_context *ctx); static void cmd_list_trustdoms_recv_lsa(struct composite_context *ctx); static void cmd_list_trustdoms_recv_doms(struct rpc_request *req); -struct composite_context *wb_cmd_list_trustdoms_send(struct wbsrv_service *service) +struct composite_context *wb_cmd_list_trustdoms_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service) { struct composite_context *result, *ctx; struct cmd_list_trustdom_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; @@ -64,7 +65,7 @@ struct composite_context *wb_cmd_list_trustdoms_send(struct wbsrv_service *servi state->ctx = result; result->private_data = state; - ctx = wb_sid2domain_send(service, service->primary_sid); + ctx = wb_sid2domain_send(state, service, service->primary_sid); if (ctx == NULL) goto failed; ctx->async.fn = cmd_list_trustdoms_recv_domain; ctx->async.private_data = state; @@ -89,7 +90,7 @@ static void cmd_list_trustdoms_recv_domain(struct composite_context *ctx) tree = dcerpc_smb_tree(domain->lsa_pipe->conn); if (composite_nomem(tree, state->ctx)) return; - ctx = wb_init_lsa_send(tree, domain->lsa_auth_type, + ctx = wb_init_lsa_send(state, tree, domain->lsa_auth_type, domain->schannel_creds); composite_continue(state->ctx, ctx, cmd_list_trustdoms_recv_lsa, state); diff --git a/source4/winbind/wb_cmd_lookupname.c b/source4/winbind/wb_cmd_lookupname.c index bf77b445b5..6a7c565f91 100644 --- a/source4/winbind/wb_cmd_lookupname.c +++ b/source4/winbind/wb_cmd_lookupname.c @@ -32,56 +32,70 @@ struct cmd_lookupname_state { struct wb_sid_object *result; }; -static struct composite_context *lookupname_send_req(struct wbsrv_domain *domain, void *p); -static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p); +static void lookupname_recv_domain(struct composite_context *ctx); +static void lookupname_recv_sids(struct composite_context *ctx); struct composite_context *wb_cmd_lookupname_send(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const char *dom_name, const char *name) { + struct composite_context *result, *ctx; struct cmd_lookupname_state *state; - state = talloc(mem_ctx, struct cmd_lookupname_state); + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = service->task->event_ctx; + + state = talloc(result, struct cmd_lookupname_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; + state->name = talloc_asprintf(state, "%s\\%s", dom_name, name); if (state->name == NULL) goto failed; - state->ctx = wb_domain_request_send(state, service, - service->primary_sid, - lookupname_send_req, - lookupname_recv_req, - state); - if (state->ctx == NULL) goto failed; - state->ctx->private_data = state; - return state->ctx; + + ctx = wb_sid2domain_send(state, service, service->primary_sid); + if (ctx == NULL) goto failed; + + ctx->async.fn = lookupname_recv_domain; + ctx->async.private_data = state; + return result; failed: - talloc_free(state); + talloc_free(result); return NULL; } -static struct composite_context *lookupname_send_req(struct wbsrv_domain *domain, - void *p) +static void lookupname_recv_domain(struct composite_context *ctx) { struct cmd_lookupname_state *state = - talloc_get_type(p, struct cmd_lookupname_state); + talloc_get_type(ctx->async.private_data, + struct cmd_lookupname_state); + struct wbsrv_domain *domain; - return wb_lsa_lookupnames_send(domain->lsa_pipe, - domain->lsa_policy, - 1, &state->name); + state->ctx->status = wb_sid2domain_recv(ctx, &domain); + if (!composite_is_ok(state->ctx)) return; + + ctx = wb_lsa_lookupnames_send(state, domain->lsa_pipe, + domain->lsa_policy, 1, &state->name); + composite_continue(state->ctx, ctx, lookupname_recv_sids, state); } -static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p) +static void lookupname_recv_sids(struct composite_context *ctx) { struct cmd_lookupname_state *state = - talloc_get_type(p, struct cmd_lookupname_state); + talloc_get_type(ctx->async.private_data, + struct cmd_lookupname_state); struct wb_sid_object **sids; - NTSTATUS status; - status = wb_lsa_lookupnames_recv(ctx, state, &sids); - if (NT_STATUS_IS_OK(status)) { - state->result = sids[0]; - } - return status; + state->ctx->status = wb_lsa_lookupnames_recv(ctx, state, &sids); + if (!composite_is_ok(state->ctx)) return; + + state->result = sids[0]; + composite_done(state->ctx); } NTSTATUS wb_cmd_lookupname_recv(struct composite_context *c, diff --git a/source4/winbind/wb_cmd_lookupsid.c b/source4/winbind/wb_cmd_lookupsid.c index a92b2ea183..450fc86aae 100644 --- a/source4/winbind/wb_cmd_lookupsid.c +++ b/source4/winbind/wb_cmd_lookupsid.c @@ -32,54 +32,69 @@ struct cmd_lookupsid_state { struct wb_sid_object *result; }; -static struct composite_context *lookupsid_send_req(struct wbsrv_domain *domain, void *p); -static NTSTATUS lookupsid_recv_req(struct composite_context *ctx, void *p); +static void lookupsid_recv_domain(struct composite_context *ctx); +static void lookupsid_recv_names(struct composite_context *ctx); struct composite_context *wb_cmd_lookupsid_send(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const struct dom_sid *sid) { + struct composite_context *result, *ctx; struct cmd_lookupsid_state *state; - state = talloc(mem_ctx, struct cmd_lookupsid_state); + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = service->task->event_ctx; + + state = talloc(result, struct cmd_lookupsid_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; + state->sid = dom_sid_dup(state, sid); if (state->sid == NULL) goto failed; - state->ctx = wb_domain_request_send(state, service, - service->primary_sid, - lookupsid_send_req, - lookupsid_recv_req, - state); - if (state->ctx == NULL) goto failed; - state->ctx->private_data = state; - return state->ctx; + + ctx = wb_sid2domain_send(state, service, service->primary_sid); + if (ctx == NULL) goto failed; + + ctx->async.fn = lookupsid_recv_domain; + ctx->async.private_data = state; + return result; failed: - talloc_free(state); + talloc_free(result); return NULL; } -static struct composite_context *lookupsid_send_req(struct wbsrv_domain *domain, void *p) +static void lookupsid_recv_domain(struct composite_context *ctx) { struct cmd_lookupsid_state *state = - talloc_get_type(p, struct cmd_lookupsid_state); + talloc_get_type(ctx->async.private_data, + struct cmd_lookupsid_state); + struct wbsrv_domain *domain; - return wb_lsa_lookupsids_send(domain->lsa_pipe, - domain->lsa_policy, - 1, &state->sid); + state->ctx->status = wb_sid2domain_recv(ctx, &domain); + if (!composite_is_ok(state->ctx)) return; + + ctx = wb_lsa_lookupsids_send(state, domain->lsa_pipe, + domain->lsa_policy, 1, &state->sid); + composite_continue(state->ctx, ctx, lookupsid_recv_names, state); } -static NTSTATUS lookupsid_recv_req(struct composite_context *ctx, void *p) +static void lookupsid_recv_names(struct composite_context *ctx) { struct cmd_lookupsid_state *state = - talloc_get_type(p, struct cmd_lookupsid_state); + talloc_get_type(ctx->async.private_data, + struct cmd_lookupsid_state); struct wb_sid_object **names; - NTSTATUS status; - status = wb_lsa_lookupsids_recv(ctx, state, &names); - if (NT_STATUS_IS_OK(status)) { - state->result = names[0]; - } - return status; + state->ctx->status = wb_lsa_lookupsids_recv(ctx, state, &names); + if (!composite_is_ok(state->ctx)) return; + + state->result = names[0]; + composite_done(state->ctx); } NTSTATUS wb_cmd_lookupsid_recv(struct composite_context *c, diff --git a/source4/winbind/wb_cmd_userdomgroups.c b/source4/winbind/wb_cmd_userdomgroups.c index b69547b3e4..6021412e21 100644 --- a/source4/winbind/wb_cmd_userdomgroups.c +++ b/source4/winbind/wb_cmd_userdomgroups.c @@ -24,6 +24,7 @@ #include "libcli/composite/composite.h" #include "winbind/wb_server.h" #include "smbd/service_stream.h" +#include "smbd/service_task.h" #include "lib/events/events.h" #include "librpc/gen_ndr/ndr_security.h" @@ -35,50 +36,74 @@ struct cmd_userdomgroups_state { uint32_t *rids; }; -static struct composite_context *userdomgroups_send_req(struct wbsrv_domain *domain, void *p); -static NTSTATUS userdomgroups_recv_req(struct composite_context *ctx, void *p); +static void userdomgroups_recv_domain(struct composite_context *ctx); +static void userdomgroups_recv_rids(struct composite_context *ctx); -struct composite_context *wb_cmd_userdomgroups_send(struct wbsrv_service *service, +struct composite_context *wb_cmd_userdomgroups_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const struct dom_sid *sid) { + struct composite_context *result, *ctx; struct cmd_userdomgroups_state *state; - state = talloc(NULL, struct cmd_userdomgroups_state); + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = service->task->event_ctx; + + state = talloc(result, struct cmd_userdomgroups_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; + + state->dom_sid = dom_sid_dup(state, sid); + if (state->dom_sid == NULL) goto failed; + state->dom_sid->num_auths -= 1; state->user_rid = sid->sub_auths[sid->num_auths-1]; - state->ctx = wb_domain_request_send(state, service, sid, - userdomgroups_send_req, - userdomgroups_recv_req, - state); - if (state->ctx == NULL) goto failed; - state->ctx->private_data = state; - return state->ctx; + + ctx = wb_sid2domain_send(state, service, sid); + if (ctx == NULL) goto failed; + + ctx->async.fn = userdomgroups_recv_domain; + ctx->async.private_data = state; + return result; failed: - talloc_free(state); + talloc_free(result); return NULL; } -static struct composite_context *userdomgroups_send_req(struct wbsrv_domain *domain, - void *p) +static void userdomgroups_recv_domain(struct composite_context *ctx) { struct cmd_userdomgroups_state *state = - talloc_get_type(p, struct cmd_userdomgroups_state); + talloc_get_type(ctx->async.private_data, + struct cmd_userdomgroups_state); + struct wbsrv_domain *domain; + + state->ctx->status = wb_sid2domain_recv(ctx, &domain); + if (!composite_is_ok(state->ctx)) return; - state->dom_sid = talloc_reference(state, domain->sid); - if (state->dom_sid == NULL) return NULL; - return wb_samr_userdomgroups_send(domain->samr_pipe, - domain->domain_handle, - state->user_rid); + ctx = wb_samr_userdomgroups_send(state, domain->samr_pipe, + domain->domain_handle, + state->user_rid); + composite_continue(state->ctx, ctx, userdomgroups_recv_rids, state); + } -static NTSTATUS userdomgroups_recv_req(struct composite_context *ctx, void *p) +static void userdomgroups_recv_rids(struct composite_context *ctx) { struct cmd_userdomgroups_state *state = - talloc_get_type(p, struct cmd_userdomgroups_state); + talloc_get_type(ctx->async.private_data, + struct cmd_userdomgroups_state); - return wb_samr_userdomgroups_recv(ctx, state, &state->num_rids, - &state->rids); + state->ctx->status = wb_samr_userdomgroups_recv(ctx, state, + &state->num_rids, + &state->rids); + if (!composite_is_ok(state->ctx)) return; + + composite_done(state->ctx); } NTSTATUS wb_cmd_userdomgroups_recv(struct composite_context *c, @@ -111,16 +136,16 @@ NTSTATUS wb_cmd_userdomgroups_recv(struct composite_context *c, } done: - talloc_free(state); + talloc_free(c); return status; } -NTSTATUS wb_cmd_userdomgroups(struct wbsrv_service *service, +NTSTATUS wb_cmd_userdomgroups(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const struct dom_sid *sid, - TALLOC_CTX *mem_ctx, int *num_sids, - struct dom_sid ***sids) + int *num_sids, struct dom_sid ***sids) { struct composite_context *c = - wb_cmd_userdomgroups_send(service, sid); + wb_cmd_userdomgroups_send(mem_ctx, service, sid); return wb_cmd_userdomgroups_recv(c, mem_ctx, num_sids, sids); } diff --git a/source4/winbind/wb_cmd_usersids.c b/source4/winbind/wb_cmd_usersids.c index 47c69fffc8..8b38ba56f4 100644 --- a/source4/winbind/wb_cmd_usersids.c +++ b/source4/winbind/wb_cmd_usersids.c @@ -29,177 +29,9 @@ #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_samr.h" -/* Calculate the token in two steps: Go the user's originating domain, asking - * for the user's domain groups. Then with the resulting list of sids go to - * our own domain, expanding the aliases aka domain local groups. Two helpers - * are needed: composite_samr_GetAliasMembership and wb_sidaliases. The core - * function this file supplies is wb_cmd_usersids somewhere down. */ - - -/* composite_context wrapper around dcerpc_samr_GetAliasMembership */ - -static void composite_samr_GetAliasMembership_recv_rpc(struct rpc_request *req); - -static struct composite_context *composite_samr_GetAliasMembership_send(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct samr_GetAliasMembership *r) -{ - struct composite_context *result; - struct rpc_request *req; - - result = talloc(mem_ctx, struct composite_context); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->async.fn = NULL; - result->event_ctx = p->conn->event_ctx; - - req = dcerpc_samr_GetAliasMembership_send(p, mem_ctx, r); - if (req == NULL) goto failed; - req->async.callback = composite_samr_GetAliasMembership_recv_rpc; - req->async.private = result; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void composite_samr_GetAliasMembership_recv_rpc(struct rpc_request *req) -{ - struct composite_context *ctx = - talloc_get_type(req->async.private, struct composite_context); - - ctx->status = dcerpc_ndr_request_recv(req); - if (!composite_is_ok(ctx)) return; - composite_done(ctx); -} - -static NTSTATUS composite_samr_GetAliasMembership_recv(struct composite_context *ctx) -{ - NTSTATUS status = composite_wait(ctx); - talloc_free(ctx); - return status; -} - -/* Composite wrapper including domain selection and domain queueing around - * GetAliasMemberships */ - -struct sidaliases_state { - struct composite_context *ctx; - int num_sids; - const struct dom_sid *domain_sid; - const struct dom_sid *sids; - - struct lsa_SidArray lsa_sids; - struct samr_Ids rids; - struct samr_GetAliasMembership r; -}; - -static struct composite_context *sidaliases_send_req(struct wbsrv_domain *domain, - void *p); -static NTSTATUS sidaliases_recv_req(struct composite_context *ctx, void *p); - -static struct composite_context *wb_sidaliases_send(struct wbsrv_service *service, - int num_sids, - struct dom_sid **sids) -{ - struct sidaliases_state *state; - int i; - - state = talloc(NULL, struct sidaliases_state); - - state->domain_sid = talloc_reference(state, service->primary_sid); - if (state->domain_sid == NULL) goto failed; - - state->lsa_sids.num_sids = num_sids; - state->lsa_sids.sids = talloc_array(state, struct lsa_SidPtr, - num_sids); - if (state->lsa_sids.sids == NULL) goto failed; - - for (i=0; i<state->lsa_sids.num_sids; i++) { - state->lsa_sids.sids[i].sid = - talloc_reference(state->lsa_sids.sids, sids[i]); - if (state->lsa_sids.sids[i].sid == NULL) goto failed; - } - - state->rids.count = 0; - state->rids.ids = NULL; - - state->ctx = wb_domain_request_send(state, service, - service->primary_sid, - sidaliases_send_req, - sidaliases_recv_req, - state); - if (state->ctx == NULL) goto failed; - state->ctx->private_data = state; - return state->ctx; - - failed: - talloc_free(state); - return NULL; -} - -static struct composite_context *sidaliases_send_req(struct wbsrv_domain *domain, - void *p) -{ - struct sidaliases_state *state = - talloc_get_type(p, struct sidaliases_state); - - state->r.in.domain_handle = domain->domain_handle; - state->r.in.sids = &state->lsa_sids; - state->r.out.rids = &state->rids; - - return composite_samr_GetAliasMembership_send(domain->samr_pipe, - state, &state->r); -} - -static NTSTATUS sidaliases_recv_req(struct composite_context *ctx, void *p) -{ - struct sidaliases_state *state = - talloc_get_type(p, struct sidaliases_state); - NTSTATUS status; - - status = composite_samr_GetAliasMembership_recv(ctx); - NT_STATUS_NOT_OK_RETURN(status); - return state->r.out.result; -} - -static NTSTATUS wb_sidaliases_recv(struct composite_context *ctx, - TALLOC_CTX *mem_ctx, - int *num_sids, - struct dom_sid ***sids) -{ - struct sidaliases_state *state = - talloc_get_type(ctx->private_data, - struct sidaliases_state); - NTSTATUS status; - int i; - - status = composite_wait(ctx); - if (!NT_STATUS_IS_OK(status)) goto done; - - *num_sids = state->r.out.rids->count; - *sids = talloc_array(mem_ctx, struct dom_sid *, *num_sids); - if (*sids == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - for (i=0; i<*num_sids; i++) { - (*sids)[i] = dom_sid_add_rid((*sids), state->domain_sid, - state->r.out.rids->ids[i]); - if ((*sids)[i] == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - } - - done: - talloc_free(state); - return status; -} - -/* Supplied a SID, go to the user's DC, ask it for the user's domain - * groups. Then go to our DC, ask it for the domain local groups. */ +/* Calculate the token in two steps: Go the user's originating domain, ask for + * the user's domain groups. Then with the resulting list of sids go to our + * own domain to expand the aliases aka domain local groups. */ struct cmd_usersids_state { struct composite_context *ctx; @@ -207,20 +39,27 @@ struct cmd_usersids_state { struct dom_sid *user_sid; int num_domgroups; struct dom_sid **domgroups; + + struct lsa_SidArray lsa_sids; + struct samr_Ids rids; + struct samr_GetAliasMembership r; + int num_sids; struct dom_sid **sids; }; -static void cmd_usersids_recv_domgroups(struct composite_context *ctx); -static void cmd_usersids_recv_aliases(struct composite_context *ctx); +static void usersids_recv_domgroups(struct composite_context *ctx); +static void usersids_recv_domain(struct composite_context *ctx); +static void usersids_recv_aliases(struct rpc_request *req); -struct composite_context *wb_cmd_usersids_send(struct wbsrv_service *service, +struct composite_context *wb_cmd_usersids_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const struct dom_sid *sid) { struct composite_context *result, *ctx; struct cmd_usersids_state *state; - result = talloc_zero(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -235,10 +74,10 @@ struct composite_context *wb_cmd_usersids_send(struct wbsrv_service *service, state->user_sid = dom_sid_dup(state, sid); if (state->user_sid == NULL) goto failed; - ctx = wb_cmd_userdomgroups_send(service, sid); + ctx = wb_cmd_userdomgroups_send(state, service, sid); if (ctx == NULL) goto failed; - ctx->async.fn = cmd_usersids_recv_domgroups; + ctx->async.fn = usersids_recv_domgroups; ctx->async.private_data = state; return result; @@ -247,46 +86,69 @@ struct composite_context *wb_cmd_usersids_send(struct wbsrv_service *service, return NULL; } -static void cmd_usersids_recv_domgroups(struct composite_context *ctx) +static void usersids_recv_domgroups(struct composite_context *ctx) { struct cmd_usersids_state *state = talloc_get_type(ctx->async.private_data, struct cmd_usersids_state); - int i; - struct dom_sid **sids; - state->ctx->status = wb_cmd_userdomgroups_recv(ctx, state, &state->num_domgroups, &state->domgroups); if (!composite_is_ok(state->ctx)) return; - sids = talloc_array(state, struct dom_sid *, state->num_domgroups+1); - if (composite_nomem(sids, state->ctx)) return; + ctx = wb_sid2domain_send(state, state->service, + state->service->primary_sid); + composite_continue(state->ctx, ctx, usersids_recv_domain, state); +} + +static void usersids_recv_domain(struct composite_context *ctx) +{ + struct cmd_usersids_state *state = + talloc_get_type(ctx->async.private_data, + struct cmd_usersids_state); + struct rpc_request *req; + struct wbsrv_domain *domain; + int i; + + state->ctx->status = wb_sid2domain_recv(ctx, &domain); + if (!composite_is_ok(state->ctx)) return; + + state->lsa_sids.num_sids = state->num_domgroups+1; + state->lsa_sids.sids = talloc_array(state, struct lsa_SidPtr, + state->lsa_sids.num_sids); + if (composite_nomem(state->lsa_sids.sids, state->ctx)) return; - sids[0] = state->user_sid; + state->lsa_sids.sids[0].sid = state->user_sid; for (i=0; i<state->num_domgroups; i++) { - sids[i+1] = state->domgroups[i]; + state->lsa_sids.sids[i+1].sid = state->domgroups[i]; } - ctx = wb_sidaliases_send(state->service, state->num_domgroups+1, - sids); - composite_continue(state->ctx, ctx, cmd_usersids_recv_aliases, state); + state->rids.count = 0; + state->rids.ids = NULL; + + state->r.in.domain_handle = domain->domain_handle; + state->r.in.sids = &state->lsa_sids; + state->r.out.rids = &state->rids; + + req = dcerpc_samr_GetAliasMembership_send(domain->samr_pipe, state, + &state->r); + composite_continue_rpc(state->ctx, req, usersids_recv_aliases, state); } -static void cmd_usersids_recv_aliases(struct composite_context *ctx) +static void usersids_recv_aliases(struct rpc_request *req) { struct cmd_usersids_state *state = - talloc_get_type(ctx->async.private_data, + talloc_get_type(req->async.private, struct cmd_usersids_state); - int i, num_aliases; - struct dom_sid **aliases; + int i; - state->ctx->status = wb_sidaliases_recv(ctx, state, &num_aliases, - &aliases); + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = state->r.out.result; if (!composite_is_ok(state->ctx)) return; - state->num_sids = 1 + state->num_domgroups + num_aliases; + state->num_sids = 1 + state->num_domgroups + state->r.out.rids->count; state->sids = talloc_array(state, struct dom_sid *, state->num_sids); if (composite_nomem(state->sids, state->ctx)) return; @@ -297,9 +159,13 @@ static void cmd_usersids_recv_aliases(struct composite_context *ctx) talloc_steal(state->sids, state->domgroups[i]); } - for (i=0; i<num_aliases; i++) { - state->sids[1+i+state->num_domgroups] = - talloc_steal(state->sids, aliases[i]); + for (i=0; i<state->r.out.rids->count; i++) { + state->sids[1+state->num_domgroups+i] = dom_sid_add_rid( + state->sids, state->service->primary_sid, + state->r.out.rids->ids[i]); + + if (composite_nomem(state->sids[1+state->num_domgroups+i], + state->ctx)) return; } composite_done(state->ctx); @@ -321,13 +187,12 @@ NTSTATUS wb_cmd_usersids_recv(struct composite_context *ctx, return status; } -NTSTATUS wb_cmd_usersids(struct wbsrv_service *service, - const struct dom_sid *sid, - TALLOC_CTX *mem_ctx, int *num_sids, - struct dom_sid ***sids) +NTSTATUS wb_cmd_usersids(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, + const struct dom_sid *sid, + int *num_sids, struct dom_sid ***sids) { struct composite_context *c = - wb_cmd_usersids_send(service, sid); + wb_cmd_usersids_send(mem_ctx, service, sid); return wb_cmd_usersids_recv(c, mem_ctx, num_sids, sids); } diff --git a/source4/winbind/wb_connect_lsa.c b/source4/winbind/wb_connect_lsa.c index ada510a22c..779bcb60a2 100644 --- a/source4/winbind/wb_connect_lsa.c +++ b/source4/winbind/wb_connect_lsa.c @@ -45,14 +45,15 @@ struct init_lsa_state { static void init_lsa_recv_pipe(struct composite_context *ctx); static void init_lsa_recv_openpol(struct rpc_request *req); -struct composite_context *wb_init_lsa_send(struct smbcli_tree *tree, +struct composite_context *wb_init_lsa_send(TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, uint8_t auth_type, struct cli_credentials *creds) { struct composite_context *result, *ctx; struct init_lsa_state *state; - result = talloc(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -185,13 +186,14 @@ static void connect_lsa_recv_ntlmssp(struct composite_context *ctx); static void connect_lsa_recv_schannel(struct composite_context *ctx); static void connect_lsa_recv_anon(struct composite_context *ctx); -struct composite_context *wb_connect_lsa_send(struct smbcli_tree *tree, +struct composite_context *wb_connect_lsa_send(TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, struct cli_credentials *credentials) { struct composite_context *result, *ctx; struct connect_lsa_state *state; - result = talloc(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -206,14 +208,16 @@ struct composite_context *wb_connect_lsa_send(struct smbcli_tree *tree, state->credentials = credentials; if (credentials == NULL) { - ctx = wb_init_lsa_send(tree, DCERPC_AUTH_TYPE_NONE, NULL); + ctx = wb_init_lsa_send(state, tree, DCERPC_AUTH_TYPE_NONE, + NULL); if (ctx == NULL) goto failed; ctx->async.fn = connect_lsa_recv_anon; ctx->async.private_data = state; return result; } - ctx = wb_init_lsa_send(tree, DCERPC_AUTH_TYPE_NTLMSSP, credentials); + ctx = wb_init_lsa_send(state, tree, DCERPC_AUTH_TYPE_NTLMSSP, + credentials); if (ctx == NULL) goto failed; ctx->async.fn = connect_lsa_recv_ntlmssp; ctx->async.private_data = state; @@ -239,7 +243,7 @@ static void connect_lsa_recv_ntlmssp(struct composite_context *ctx) return; } - ctx = wb_init_lsa_send(state->tree, DCERPC_AUTH_TYPE_SCHANNEL, + ctx = wb_init_lsa_send(state, state->tree, DCERPC_AUTH_TYPE_SCHANNEL, state->credentials); composite_continue(state->ctx, ctx, connect_lsa_recv_schannel, state); @@ -260,7 +264,7 @@ static void connect_lsa_recv_schannel(struct composite_context *ctx) return; } - ctx = wb_init_lsa_send(state->tree, DCERPC_AUTH_TYPE_NONE, + ctx = wb_init_lsa_send(state, state->tree, DCERPC_AUTH_TYPE_NONE, state->credentials); composite_continue(state->ctx, ctx, connect_lsa_recv_anon, state); @@ -299,15 +303,15 @@ NTSTATUS wb_connect_lsa_recv(struct composite_context *c, return status; } -NTSTATUS wb_connect_lsa(struct smbcli_tree *tree, +NTSTATUS wb_connect_lsa(TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, struct cli_credentials *credentials, - TALLOC_CTX *mem_ctx, uint8_t *auth_type, struct dcerpc_pipe **lsa_pipe, struct policy_handle **lsa_policy) { struct composite_context *c; - c = wb_connect_lsa_send(tree, credentials); + c = wb_connect_lsa_send(mem_ctx, tree, credentials); return wb_connect_lsa_recv(c, mem_ctx, auth_type, lsa_pipe, lsa_policy); } diff --git a/source4/winbind/wb_connect_sam.c b/source4/winbind/wb_connect_sam.c index 8693356c7a..2ce189a5c7 100644 --- a/source4/winbind/wb_connect_sam.c +++ b/source4/winbind/wb_connect_sam.c @@ -49,7 +49,8 @@ static void connect_samr_recv_pipe(struct composite_context *ctx); static void connect_samr_recv_conn(struct rpc_request *req); static void connect_samr_recv_open(struct rpc_request *req); -struct composite_context *wb_connect_sam_send(struct smbcli_tree *tree, +struct composite_context *wb_connect_sam_send(TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, uint8_t auth_type, struct cli_credentials *creds, const struct dom_sid *domain_sid) @@ -57,7 +58,7 @@ struct composite_context *wb_connect_sam_send(struct smbcli_tree *tree, struct composite_context *result, *ctx; struct connect_samr_state *state; - result = talloc(NULL, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -194,17 +195,18 @@ NTSTATUS wb_connect_sam_recv(struct composite_context *c, return status; } -NTSTATUS wb_connect_sam(struct smbcli_tree *tree, +NTSTATUS wb_connect_sam(TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, uint8_t auth_type, struct cli_credentials *creds, const struct dom_sid *domain_sid, - TALLOC_CTX *mem_ctx, struct dcerpc_pipe **samr_pipe, struct policy_handle **connect_handle, struct policy_handle **domain_handle) { struct composite_context *c = - wb_connect_sam_send(tree, auth_type, creds, domain_sid); + wb_connect_sam_send(mem_ctx, tree, auth_type, creds, + domain_sid); return wb_connect_sam_recv(c, mem_ctx, samr_pipe, connect_handle, domain_handle); } diff --git a/source4/winbind/wb_domain_request.c b/source4/winbind/wb_domain_request.c deleted file mode 100644 index 8c95c20a56..0000000000 --- a/source4/winbind/wb_domain_request.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - A composite API for initializing a domain - - Copyright (C) Volker Lendecke 2005 - - 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 2 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "libcli/composite/composite.h" -#include "winbind/wb_server.h" -#include "smbd/service_stream.h" -#include "smbd/service_task.h" -#include "dlinklist.h" - -struct domain_request_state { - struct domain_request_state *prev, *next; - struct composite_context *ctx; - struct wbsrv_service *service; - struct wbsrv_domain *domain; - struct composite_context *(*send_fn)(struct wbsrv_domain *domain, - void *p); - NTSTATUS (*recv_fn)(struct composite_context *c, - void *p); - void *private_data; -}; - -static void domain_request_recv_domain(struct composite_context *ctx); -static void domain_request_recv_init(struct composite_context *ctx); -static void domain_request_recv_sub(struct composite_context *ctx); - -struct composite_context *wb_domain_request_send(TALLOC_CTX *mem_ctx, - struct wbsrv_service *service, - const struct dom_sid *sid, - struct composite_context *(*send_fn)(struct wbsrv_domain *domain, void *p), - NTSTATUS (*recv_fn)(struct composite_context *c, - void *p), - void *private_data) - -{ - struct composite_context *result, *ctx; - struct domain_request_state *state; - - result = talloc(mem_ctx, struct composite_context); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->async.fn = NULL; - result->event_ctx = service->task->event_ctx; - - state = talloc_zero(result, struct domain_request_state); - if (state == NULL) goto failed; - state->ctx = result; - result->private_data = state; - - state->service = service; - state->send_fn = send_fn; - state->recv_fn = recv_fn; - state->private_data = private_data; - - ctx = wb_sid2domain_send(service, sid); - if (ctx == NULL) goto failed; - - ctx->async.fn = domain_request_recv_domain; - ctx->async.private_data = state; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void domain_request_recv_domain(struct composite_context *ctx) -{ - struct domain_request_state *state = - talloc_get_type(ctx->async.private_data, - struct domain_request_state); - - state->ctx->status = wb_sid2domain_recv(ctx, &state->domain); - if (!composite_is_ok(state->ctx)) return; - - if (state->domain->busy) { - DEBUG(3, ("Domain %s busy\n", state->domain->name)); - DLIST_ADD_END(state->domain->request_queue, state, - struct domain_request_state *); - return; - } - - state->domain->busy = True; - - if (!state->domain->initialized) { - ctx = wb_init_domain_send(state->service, state->domain); - composite_continue(state->ctx, ctx, domain_request_recv_init, - state); - return; - } - - ctx = state->send_fn(state->domain, state->private_data); - composite_continue(state->ctx, ctx, domain_request_recv_sub, state); -} - -static void domain_request_recv_init(struct composite_context *ctx) -{ - struct domain_request_state *state = - talloc_get_type(ctx->async.private_data, - struct domain_request_state); - - state->ctx->status = wb_init_domain_recv(ctx); - if (!composite_is_ok(state->ctx)) return; - - ctx = state->send_fn(state->domain, state->private_data); - composite_continue(state->ctx, ctx, domain_request_recv_sub, state); -} - -static void domain_request_recv_sub(struct composite_context *ctx) -{ - struct domain_request_state *state = - talloc_get_type(ctx->async.private_data, - struct domain_request_state); - - state->ctx->status = state->recv_fn(ctx, state->private_data); - state->domain->busy = False; - - if (state->domain->request_queue != NULL) { - struct domain_request_state *s2; - s2 = state->domain->request_queue; - DLIST_REMOVE(state->domain->request_queue, s2); - ctx = s2->send_fn(state->domain, s2->private_data); - composite_continue(s2->ctx, ctx, domain_request_recv_sub, s2); - state->domain->busy = True; - } - - if (!composite_is_ok(state->ctx)) return; - composite_done(state->ctx); -} - -NTSTATUS wb_domain_request_recv(struct composite_context *ctx) -{ - NTSTATUS status = composite_wait(ctx); - talloc_free(ctx); - return status; -} diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index eaafdfafbe..c5082a9a3e 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -141,8 +141,8 @@ struct composite_context *wb_init_domain_send(struct wbsrv_service *service, schannel_creds); if (!NT_STATUS_IS_OK(state->ctx->status)) goto failed; - ctx = wb_finddcs_send(domain->name, domain->sid, result->event_ctx, - service->task->msg_ctx); + ctx = wb_finddcs_send(state, domain->name, domain->sid, + result->event_ctx, service->task->msg_ctx); if (ctx == NULL) goto failed; ctx->async.fn = init_domain_recv_dcs; @@ -171,6 +171,10 @@ static void init_domain_recv_dcs(struct composite_context *ctx) state->dcaddr = state->dcs[0].address; + state->domain->dcname = talloc_reference(state->domain, + state->dcs[0].name); + if (composite_nomem(state->domain->dcname, state->ctx)) return; + state->conn.in.dest_host = state->dcs[0].address; state->conn.in.port = 0; state->conn.in.called_name = state->dcs[0].name; @@ -191,7 +195,7 @@ static void init_domain_recv_dcs(struct composite_context *ctx) state->conn.in.fallback_to_anonymous = True; - ctx = smb_composite_connect_send(&state->conn, state, + ctx = smb_composite_connect_send(&state->conn, state->domain, state->ctx->event_ctx); composite_continue(state->ctx, ctx, init_domain_recv_tree, state); } @@ -215,7 +219,7 @@ static void init_domain_recv_dcip(struct composite_context *ctx) state->conn.in.fallback_to_anonymous = True; - ctx = smb_composite_connect_send(&state->conn, state, + ctx = smb_composite_connect_send(&state->conn, state->domain, state->ctx->event_ctx); composite_continue(state->ctx, ctx, init_domain_recv_tree, state); } @@ -233,7 +237,8 @@ static void init_domain_recv_tree(struct composite_context *ctx) ((lp_server_role() == ROLE_DOMAIN_MEMBER) && (dom_sid_equal(state->domain->sid, state->service->primary_sid)))) { - ctx = wb_get_schannel_creds_send(state->domain->schannel_creds, + ctx = wb_get_schannel_creds_send(state, + state->domain->schannel_creds, state->conn.out.tree, state->ctx->event_ctx); composite_continue(state->ctx, ctx, @@ -241,7 +246,7 @@ static void init_domain_recv_tree(struct composite_context *ctx) return; } - ctx = wb_connect_lsa_send(state->conn.out.tree, NULL); + ctx = wb_connect_lsa_send(state, state->conn.out.tree, NULL); composite_continue(state->ctx, ctx, init_domain_recv_lsa, state); } @@ -256,12 +261,10 @@ static void init_domain_recv_netlogoncreds(struct composite_context *ctx) &state->auth2_pipe); if (!composite_is_ok(state->ctx)) return; - talloc_unlink(state, state->conn.out.tree); /* The pipe owns it now */ - if (!lp_winbind_sealed_pipes()) { state->netlogon_pipe = talloc_reference(state, state->auth2_pipe); - ctx = wb_connect_lsa_send(state->conn.out.tree, NULL); + ctx = wb_connect_lsa_send(state, state->conn.out.tree, NULL); composite_continue(state->ctx, ctx, init_domain_recv_lsa, state); return; @@ -304,7 +307,7 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) NULL); if (!composite_is_ok(state->ctx)) return; - ctx = wb_connect_lsa_send(state->conn.out.tree, + ctx = wb_connect_lsa_send(state, state->conn.out.tree, state->domain->schannel_creds); composite_continue(state->ctx, ctx, init_domain_recv_lsa, state); } @@ -323,11 +326,8 @@ static void init_domain_recv_lsa(struct composite_context *ctx) &state->lsa_policy); if (!composite_is_ok(state->ctx)) return; - if (state->auth2_pipe == NULL) { - /* Give the tree to the LSA pipe. If auth2_pipe exists we have - * given it to that already */ - talloc_unlink(state, state->conn.out.tree); - } + /* Give the tree to the pipes. */ +// talloc_unlink(state, state->conn.out.tree); state->queryinfo.in.handle = state->lsa_policy; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; @@ -394,7 +394,7 @@ static void init_domain_recv_ldapconn(struct composite_context *ctx) state->samr_pipe = dcerpc_pipe_init(state, state->ctx->event_ctx); if (composite_nomem(state->samr_pipe, state->ctx)) return; - ctx = wb_connect_sam_send(state->conn.out.tree, + ctx = wb_connect_sam_send(state, state->conn.out.tree, state->domain->lsa_auth_type, state->domain->schannel_creds, state->domain->sid); diff --git a/source4/winbind/wb_pam_auth.c b/source4/winbind/wb_pam_auth.c index 0724875151..dfe3374b0b 100644 --- a/source4/winbind/wb_pam_auth.c +++ b/source4/winbind/wb_pam_auth.c @@ -26,6 +26,7 @@ #include "winbind/wb_async_helpers.h" #include "winbind/wb_server.h" #include "smbd/service_stream.h" +#include "smbd/service_task.h" #include "libcli/auth/credentials.h" /* Oh, there is so much to keep an eye on when authenticating a user. Oh my! */ @@ -48,19 +49,15 @@ struct pam_auth_crap_state { DATA_BLOB info3; }; -static struct composite_context *crap_samlogon_send_req(struct wbsrv_domain *domain, - void *p); -static NTSTATUS crap_samlogon_recv_req(struct composite_context *ctx, void *p); - -/* NTLM authentication. - - Fill parameters into a control block to pass to the next function. - No application logic, this is done by the helper function paramters - to wb_domain_request_send() - +/* + * NTLM authentication. */ -struct composite_context *wb_cmd_pam_auth_crap_send(struct wbsrv_call *call, +static void pam_auth_crap_recv_domain(struct composite_context *ctx); +static void pam_auth_crap_recv_samlogon(struct rpc_request *req); + +struct composite_context *wb_cmd_pam_auth_crap_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, uint32_t logon_parameters, const char *domain, const char *user, @@ -69,13 +66,19 @@ struct composite_context *wb_cmd_pam_auth_crap_send(struct wbsrv_call *call, DATA_BLOB nt_resp, DATA_BLOB lm_resp) { + struct composite_context *result, *ctx; struct pam_auth_crap_state *state; - struct wbsrv_service *service = call->wbconn->listen_socket->service; - state = talloc(NULL, struct pam_auth_crap_state); - if (state == NULL) goto failed; + result = talloc(mem_ctx, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = service->task->event_ctx; - state->event_ctx = call->event_ctx; + state = talloc(result, struct pam_auth_crap_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; state->logon_parameters = logon_parameters; @@ -99,17 +102,15 @@ struct composite_context *wb_cmd_pam_auth_crap_send(struct wbsrv_call *call, if ((lm_resp.data != NULL) && (state->lm_resp.data == NULL)) goto failed; - state->ctx = wb_domain_request_send(state, service, - service->primary_sid, - crap_samlogon_send_req, - crap_samlogon_recv_req, - state); - if (state->ctx == NULL) goto failed; - state->ctx->private_data = state; - return state->ctx; + ctx = wb_sid2domain_send(state, service, service->primary_sid); + if (ctx == NULL) goto failed; + + ctx->async.fn = pam_auth_crap_recv_domain; + ctx->async.private_data = state; + return result; failed: - talloc_free(state); + talloc_free(result); return NULL; } @@ -118,11 +119,15 @@ struct composite_context *wb_cmd_pam_auth_crap_send(struct wbsrv_call *call, Send of a SamLogon request to authenticate a user. */ -static struct composite_context *crap_samlogon_send_req(struct wbsrv_domain *domain, - void *p) +static void pam_auth_crap_recv_domain(struct composite_context *ctx) { struct pam_auth_crap_state *state = - talloc_get_type(p, struct pam_auth_crap_state); + talloc_get_type(ctx->async.private_data, + struct pam_auth_crap_state); + struct rpc_request *req; + struct wbsrv_domain *domain; + + state->ctx->status = wb_sid2domain_recv(ctx, &domain); state->creds_state = cli_credentials_get_netlogon_creds(domain->schannel_creds); @@ -146,7 +151,7 @@ static struct composite_context *crap_samlogon_send_req(struct wbsrv_domain *dom state->r.in.server_name = talloc_asprintf( state, "\\\\%s", dcerpc_server_name(domain->netlogon_pipe)); - if (state->r.in.server_name == NULL) return NULL; + if (composite_nomem(state->r.in.server_name, state->ctx)) return; ZERO_STRUCT(state->auth2); @@ -159,36 +164,39 @@ static struct composite_context *crap_samlogon_send_req(struct wbsrv_domain *dom state->r.in.logon.network = &state->ninfo; state->r.out.return_authenticator = NULL; - return composite_netr_LogonSamLogon_send(domain->netlogon_pipe, - state, &state->r); + req = dcerpc_netr_LogonSamLogon_send(domain->netlogon_pipe, state, + &state->r); + composite_continue_rpc(state->ctx, req, pam_auth_crap_recv_samlogon, + state); } /* NTLM Authentication - Check the SamLogon reply, decrypt and parse out the session keys and the info3 structure + Check the SamLogon reply, decrypt and parse out the session keys and the + info3 structure. */ -static NTSTATUS crap_samlogon_recv_req(struct composite_context *ctx, - void *p) +static void pam_auth_crap_recv_samlogon(struct rpc_request *req) { struct pam_auth_crap_state *state = - talloc_get_type(p, struct pam_auth_crap_state); + talloc_get_type(req->async.private, + struct pam_auth_crap_state); struct netr_SamBaseInfo *base; DATA_BLOB tmp_blob; - NTSTATUS status; - status = composite_netr_LogonSamLogon_recv(ctx); - if (!NT_STATUS_IS_OK(status)) return status; + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; if ((state->r.out.return_authenticator == NULL) || (!creds_client_check(state->creds_state, &state->r.out.return_authenticator->cred))) { DEBUG(0, ("Credentials check failed!\n")); - return NT_STATUS_ACCESS_DENIED; + composite_error(state->ctx, NT_STATUS_ACCESS_DENIED); + return; } - status = state->r.out.result; - if (!NT_STATUS_IS_OK(status)) return status; + state->ctx->status = state->r.out.result; + if (!composite_is_ok(state->ctx)) return; /* Decrypt the session keys before we reform the info3, so the * person on the other end of winbindd pipe doesn't have to. @@ -197,22 +205,23 @@ static NTSTATUS crap_samlogon_recv_req(struct composite_context *ctx, state->r.in.validation_level, &state->r.out.validation); - status = ndr_push_struct_blob( - &tmp_blob, state, - state->r.out.validation.sam3, + state->ctx->status = ndr_push_struct_blob( + &tmp_blob, state, state->r.out.validation.sam3, (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); - NT_STATUS_NOT_OK_RETURN(status); + if (!composite_is_ok(state->ctx)) return; /* The Samba3 protocol is a bit broken (due to non-IDL * heritage, so for compatability we must add a non-zero 4 * bytes to the info3 */ state->info3 = data_blob_talloc(state, NULL, tmp_blob.length+4); - NT_STATUS_HAVE_NO_MEMORY(state->info3.data); + if (composite_nomem(state->info3.data, state->ctx)) return; SIVAL(state->info3.data, 0, 1); memcpy(state->info3.data+4, tmp_blob.data, tmp_blob.length); - /* We actually only ask for level 3, and assume it above, but anyway... */ + /* We actually only ask for level 3, and assume it above, but + * anyway... */ + base = NULL; switch(state->r.in.validation_level) { case 2: @@ -226,7 +235,8 @@ static NTSTATUS crap_samlogon_recv_req(struct composite_context *ctx, break; } if (base == NULL) { - return NT_STATUS_INTERNAL_ERROR; + composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + return; } state->user_session_key = base->key; @@ -244,7 +254,7 @@ static NTSTATUS crap_samlogon_recv_req(struct composite_context *ctx, talloc_steal(state, base->domain.string); } - return NT_STATUS_OK; + composite_done(state->ctx); } NTSTATUS wb_cmd_pam_auth_crap_recv(struct composite_context *c, @@ -263,7 +273,8 @@ NTSTATUS wb_cmd_pam_auth_crap_recv(struct composite_context *c, *user_session_key = state->user_session_key; *lm_key = state->lm_key; *unix_username = talloc_asprintf(mem_ctx, "%s%s%s", - state->domain_name, lp_winbind_separator(), + state->domain_name, + lp_winbind_separator(), state->user_name); if (!*unix_username) { status = NT_STATUS_NO_MEMORY; @@ -273,31 +284,32 @@ NTSTATUS wb_cmd_pam_auth_crap_recv(struct composite_context *c, return status; } -NTSTATUS wb_cmd_pam_auth_crap(struct wbsrv_call *call, +NTSTATUS wb_cmd_pam_auth_crap(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, uint32_t logon_parameters, const char *domain, const char *user, const char *workstation, DATA_BLOB chal, DATA_BLOB nt_resp, - DATA_BLOB lm_resp, TALLOC_CTX *mem_ctx, + DATA_BLOB lm_resp, DATA_BLOB *info3, struct netr_UserSessionKey *user_session_key, struct netr_LMSessionKey *lm_key, char **unix_username) { struct composite_context *c = - wb_cmd_pam_auth_crap_send(call, logon_parameters, + wb_cmd_pam_auth_crap_send(mem_ctx, service, logon_parameters, domain, user, workstation, chal, nt_resp, lm_resp); return wb_cmd_pam_auth_crap_recv(c, mem_ctx, info3, user_session_key, lm_key, unix_username); } -struct composite_context *wb_cmd_pam_auth_send(struct wbsrv_call *call, +struct composite_context *wb_cmd_pam_auth_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, const char *domain, const char *user, const char *password) { - struct composite_context *c; struct cli_credentials *credentials; const char *workstation; NTSTATUS status; @@ -314,7 +326,7 @@ struct composite_context *wb_cmd_pam_auth_send(struct wbsrv_call *call, DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n")); - credentials = cli_credentials_init(call); + credentials = cli_credentials_init(mem_ctx); if (!credentials) { return NULL; } @@ -324,34 +336,33 @@ struct composite_context *wb_cmd_pam_auth_send(struct wbsrv_call *call, cli_credentials_set_password(credentials, password, CRED_SPECIFIED); - chal = data_blob_talloc(call, NULL, 8); + chal = data_blob_talloc(mem_ctx, NULL, 8); if (!chal.data) { return NULL; } generate_random_buffer(chal.data, chal.length); - cli_credentials_get_ntlm_username_domain(credentials, call, + cli_credentials_get_ntlm_username_domain(credentials, mem_ctx, &user, &domain); /* for best compatability with multiple vitual netbios names * on the host, this should be generated from the * cli_credentials associated with the machine account */ workstation = cli_credentials_get_workstation(credentials); - names_blob = NTLMv2_generate_names_blob(call, cli_credentials_get_workstation(credentials), - cli_credentials_get_domain(credentials)); + names_blob = NTLMv2_generate_names_blob( + mem_ctx, + cli_credentials_get_workstation(credentials), + cli_credentials_get_domain(credentials)); - status = cli_credentials_get_ntlm_response(credentials, call, - &flags, - chal, - names_blob, - &lm_resp, &nt_resp, - NULL, NULL); + status = cli_credentials_get_ntlm_response( + credentials, mem_ctx, &flags, chal, names_blob, + &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { return NULL; } - c = wb_cmd_pam_auth_crap_send(call, 0 /* logon parameters */, - domain, user, workstation, - chal, nt_resp, lm_resp); - return c; + return wb_cmd_pam_auth_crap_send(mem_ctx, service, + 0 /* logon parameters */, + domain, user, workstation, + chal, nt_resp, lm_resp); } NTSTATUS wb_cmd_pam_auth_recv(struct composite_context *c) @@ -363,12 +374,11 @@ NTSTATUS wb_cmd_pam_auth_recv(struct composite_context *c) return status; } -NTSTATUS wb_cmd_pam_auth(struct wbsrv_call *call, +NTSTATUS wb_cmd_pam_auth(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const char *domain, const char *user, const char *password) { struct composite_context *c = - wb_cmd_pam_auth_send(call, domain, user, - password); + wb_cmd_pam_auth_send(mem_ctx, service, domain, user, password); return wb_cmd_pam_auth_recv(c); } diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c index 25c80cb099..a5e7cb722b 100644 --- a/source4/winbind/wb_samba3_cmd.c +++ b/source4/winbind/wb_samba3_cmd.c @@ -185,7 +185,7 @@ NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call) DEBUG(5, ("wbsrv_samba3_getdcname called\n")); - ctx = wb_cmd_getdcname_send(service, service->domains, + ctx = wb_cmd_getdcname_send(s3call, service, s3call->request.domain_name); NT_STATUS_HAVE_NO_MEMORY(ctx); @@ -234,7 +234,7 @@ NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call) } ctx = wb_cmd_userdomgroups_send( - s3call->call->wbconn->listen_socket->service, sid); + s3call, s3call->call->wbconn->listen_socket->service, sid); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->async.fn = userdomgroups_recv_groups; @@ -301,7 +301,7 @@ NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call) } ctx = wb_cmd_usersids_send( - s3call->call->wbconn->listen_socket->service, sid); + s3call, s3call->call->wbconn->listen_socket->service, sid); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->async.fn = usersids_recv_sids; @@ -471,6 +471,8 @@ static void pam_auth_crap_recv(struct composite_context *ctx); NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) { struct composite_context *ctx; + struct wbsrv_service *service = + s3call->call->wbconn->listen_socket->service; DATA_BLOB chal, nt_resp, lm_resp; DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n")); @@ -483,7 +485,7 @@ NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call) lm_resp.length = s3call->request.data.auth_crap.lm_resp_len; ctx = wb_cmd_pam_auth_crap_send( - s3call->call, + s3call, service, s3call->request.data.auth_crap.logon_parameters, s3call->request.data.auth_crap.domain, s3call->request.data.auth_crap.user, @@ -571,16 +573,18 @@ static void pam_auth_recv(struct composite_context *ctx); NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call) { struct composite_context *ctx; + struct wbsrv_service *service = + s3call->call->wbconn->listen_socket->service; char *user, *domain; + if (!samba3_parse_domuser(s3call, s3call->request.data.auth.user, &domain, &user)) { return NT_STATUS_NO_SUCH_USER; } - ctx = wb_cmd_pam_auth_send( - s3call->call, domain, user, - s3call->request.data.auth.pass); + ctx = wb_cmd_pam_auth_send(s3call, service, domain, user, + s3call->request.data.auth.pass); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->async.fn = pam_auth_recv; @@ -618,7 +622,7 @@ NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call) DEBUG(5, ("wbsrv_samba3_list_trustdom called\n")); - ctx = wb_cmd_list_trustdoms_send(service); + ctx = wb_cmd_list_trustdoms_send(s3call, service); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->async.fn = list_trustdom_recv_doms; diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h index 501924fc01..0407d89371 100644 --- a/source4/winbind/wb_server.h +++ b/source4/winbind/wb_server.h @@ -53,6 +53,8 @@ struct wbsrv_domain { const char *name; const struct dom_sid *sid; const char *dcname; + const char *dc_dnsname; + const char *dc_address; struct dcerpc_pipe *lsa_pipe; struct policy_handle *lsa_policy; 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); } |