X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source%2Fwinbind%2Fwb_async_helpers.c;h=915638abb726a45dc706ab6ac2c9a914259956fc;hb=d14948fdf687c8f70ef9ec35445b7eb04da84253;hp=0480304abe16619f9a864757ca24ea5d3ba330e9;hpb=576a724bf1350ba7f38f95118224bdee98e0be5a;p=ira%2Fwip.git diff --git a/source/winbind/wb_async_helpers.c b/source/winbind/wb_async_helpers.c index 0480304abe1..915638abb72 100644 --- a/source/winbind/wb_async_helpers.c +++ b/source/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,9 +64,10 @@ 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; result->event_ctx = event_ctx; state = talloc(result, struct finddcs_state); @@ -149,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); @@ -160,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); } @@ -187,16 +190,18 @@ 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; result->event_ctx = ev; state = talloc(result, struct get_schannel_creds_state); @@ -347,17 +352,177 @@ 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); } +struct lsa_lookupsids_state { + struct composite_context *ctx; + int num_sids; + struct lsa_LookupSids r; + struct lsa_SidArray sids; + struct lsa_TransNameArray names; + uint32_t count; + struct wb_sid_object **result; +}; + +static void lsa_lookupsids_recv_names(struct rpc_request *req); + +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) +{ + struct composite_context *result; + struct rpc_request *req; + struct lsa_lookupsids_state *state; + int i; + + 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 = lsa_pipe->conn->event_ctx; + + state = talloc(result, struct lsa_lookupsids_state); + if (state == NULL) goto failed; + result->private_data = state; + state->ctx = result; + + state->sids.num_sids = num_sids; + state->sids.sids = talloc_array(state, struct lsa_SidPtr, num_sids); + if (state->sids.sids == NULL) goto failed; + + for (i=0; isids.sids[i].sid = dom_sid_dup(state->sids.sids, + sids[i]); + if (state->sids.sids[i].sid == NULL) goto failed; + } + + state->count = 0; + state->num_sids = num_sids; + state->names.count = 0; + state->names.names = NULL; + + state->r.in.handle = handle; + state->r.in.sids = &state->sids; + state->r.in.names = &state->names; + state->r.in.level = 1; + state->r.in.count = &state->count; + state->r.out.names = &state->names; + state->r.out.count = &state->count; + + req = dcerpc_lsa_LookupSids_send(lsa_pipe, state, &state->r); + if (req == NULL) goto failed; + + req->async.callback = lsa_lookupsids_recv_names; + req->async.private = state; + return result; + + failed: + talloc_free(result); + return NULL; +} + +static void lsa_lookupsids_recv_names(struct rpc_request *req) +{ + struct lsa_lookupsids_state *state = + talloc_get_type(req->async.private, + struct lsa_lookupsids_state); + int i; + + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = state->r.out.result; + if (!NT_STATUS_IS_OK(state->ctx->status) && + !NT_STATUS_EQUAL(state->ctx->status, STATUS_SOME_UNMAPPED)) { + composite_error(state->ctx, state->ctx->status); + return; + } + + state->result = talloc_array(state, struct wb_sid_object *, + state->num_sids); + if (composite_nomem(state->result, state->ctx)) return; + + for (i=0; inum_sids; i++) { + struct lsa_TranslatedName *name = + &state->r.out.names->names[i]; + struct lsa_TrustInformation *dom; + + state->result[i] = talloc_zero(state->result, + struct wb_sid_object); + if (composite_nomem(state->result[i], state->ctx)) return; + + state->result[i]->type = name->sid_type; + if (state->result[i]->type == SID_NAME_UNKNOWN) { + continue; + } + + if (name->sid_index >= state->r.out.domains->count) { + composite_error(state->ctx, + NT_STATUS_INVALID_PARAMETER); + return; + } + + dom = &state->r.out.domains->domains[name->sid_index]; + state->result[i]->domain = talloc_reference(state->result[i], + dom->name.string); + if ((name->sid_type == SID_NAME_DOMAIN) || + (name->name.string == NULL)) { + state->result[i]->name = + talloc_strdup(state->result[i], ""); + } else { + state->result[i]->name = + talloc_steal(state->result[i], + name->name.string); + } + + if (composite_nomem(state->result[i]->name, state->ctx)) { + return; + } + } + + composite_done(state->ctx); +} + +NTSTATUS wb_lsa_lookupsids_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + struct wb_sid_object ***names) +{ + NTSTATUS status = composite_wait(c); + if (NT_STATUS_IS_OK(status)) { + struct lsa_lookupsids_state *state = + talloc_get_type(c->private_data, + struct lsa_lookupsids_state); + *names = talloc_steal(mem_ctx, state->result); + } + talloc_free(c); + return status; +} + +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, + struct wb_sid_object ***names) +{ + struct composite_context *c = + wb_lsa_lookupsids_send(mem_ctx, lsa_pipe, handle, + num_sids, sids); + return wb_lsa_lookupnames_recv(c, mem_ctx, names); +} + + + struct lsa_lookupnames_state { struct composite_context *ctx; uint32_t num_names; @@ -369,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) @@ -381,9 +547,10 @@ 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; result->event_ctx = lsa_pipe->conn->event_ctx; state = talloc(result, struct lsa_lookupnames_state); @@ -487,66 +654,53 @@ 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); } -struct cmd_lookupname_state { +#if 0 + +struct cmd_checkmachacc_state { struct composite_context *ctx; struct wbsrv_call *call; struct wbsrv_domain *domain; - const char *name; - struct wb_sid_object *result; }; -static void cmd_lookupname_recv_init(struct composite_context *ctx); -static void cmd_lookupname_recv_sid(struct composite_context *ctx); +static void cmd_checkmachacc_recv_init(struct composite_context *ctx); -struct composite_context *wb_cmd_lookupname_send(struct wbsrv_call *call, - const char *name) +struct composite_context *wb_cmd_checkmachacc_send(struct wbsrv_call *call) { struct composite_context *result, *ctx; - struct cmd_lookupname_state *state; + struct cmd_checkmachacc_state *state; struct wbsrv_service *service = call->wbconn->listen_socket->service; - result = talloc_zero(call, struct composite_context); + result = talloc(call, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; result->event_ctx = call->event_ctx; - state = talloc(result, struct cmd_lookupname_state); + state = talloc(result, struct cmd_checkmachacc_state); if (state == NULL) goto failed; state->ctx = result; result->private_data = state; - state->call = call; - state->name = talloc_strdup(state, name); state->domain = service->domains; - if (state->domain->initialized) { - ctx = wb_lsa_lookupnames_send(state->domain->lsa_pipe, - state->domain->lsa_policy, - 1, &state->name); - if (ctx == NULL) goto failed; - ctx->async.fn = cmd_lookupname_recv_sid; - ctx->async.private_data = state; - return result; - } - - ctx = wb_init_domain_send(state->domain, - result->event_ctx, - call->wbconn->conn->msg_ctx); + ctx = wb_init_domain_send(service, state->domain); if (ctx == NULL) goto failed; - ctx->async.fn = cmd_lookupname_recv_init; + ctx->async.fn = cmd_checkmachacc_recv_init; ctx->async.private_data = state; + return result; failed: @@ -554,118 +708,167 @@ struct composite_context *wb_cmd_lookupname_send(struct wbsrv_call *call, return NULL; } -static void cmd_lookupname_recv_init(struct composite_context *ctx) +static void cmd_checkmachacc_recv_init(struct composite_context *ctx) { - struct cmd_lookupname_state *state = + struct cmd_checkmachacc_state *state = talloc_get_type(ctx->async.private_data, - struct cmd_lookupname_state); + struct cmd_checkmachacc_state); state->ctx->status = wb_init_domain_recv(ctx); if (!composite_is_ok(state->ctx)) return; - ctx = wb_lsa_lookupnames_send(state->domain->lsa_pipe, - state->domain->lsa_policy, - 1, &state->name); - composite_continue(state->ctx, ctx, cmd_lookupname_recv_sid, state); -} - -static void cmd_lookupname_recv_sid(struct composite_context *ctx) -{ - struct cmd_lookupname_state *state = - talloc_get_type(ctx->async.private_data, - struct cmd_lookupname_state); - struct wb_sid_object **sids; - - 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, - TALLOC_CTX *mem_ctx, - struct wb_sid_object **sid) +NTSTATUS wb_cmd_checkmachacc_recv(struct composite_context *c) { NTSTATUS status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct cmd_lookupname_state *state = - talloc_get_type(c->private_data, - struct cmd_lookupname_state); - *sid = talloc_steal(mem_ctx, state->result); - } talloc_free(c); return status; } -NTSTATUS wb_cmd_lookupname(struct wbsrv_call *call, const char *name, - TALLOC_CTX *mem_ctx, struct wb_sid_object **sid) +NTSTATUS wb_cmd_checkmachacc(struct wbsrv_call *call) { - struct composite_context *c = - wb_cmd_lookupname_send(call, name); - return wb_cmd_lookupname_recv(c, mem_ctx, sid); + struct composite_context *c = wb_cmd_checkmachacc_send(call); + return wb_cmd_checkmachacc_recv(c); } +#endif -struct cmd_checkmachacc_state { +struct samr_getuserdomgroups_state { struct composite_context *ctx; - struct wbsrv_call *call; - struct wbsrv_domain *domain; + struct dcerpc_pipe *samr_pipe; + + int num_rids; + uint32_t *rids; + + struct policy_handle *user_handle; + struct samr_OpenUser o; + struct samr_GetGroupsForUser g; + struct samr_Close c; }; -static void cmd_checkmachacc_recv_init(struct composite_context *ctx); +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_cmd_checkmachacc_send(struct wbsrv_call *call) +struct composite_context *wb_samr_userdomgroups_send(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *samr_pipe, + struct policy_handle *domain_handle, + uint32_t rid) { - struct composite_context *result, *ctx; - struct cmd_checkmachacc_state *state; - struct wbsrv_service *service = call->wbconn->listen_socket->service; + struct composite_context *result; + struct rpc_request *req; + struct samr_getuserdomgroups_state *state; - result = talloc(call, struct composite_context); + result = talloc(mem_ctx, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; - result->event_ctx = call->event_ctx; + result->async.fn = NULL; + result->event_ctx = samr_pipe->conn->event_ctx; - state = talloc(result, struct cmd_checkmachacc_state); + state = talloc(result, struct samr_getuserdomgroups_state); if (state == NULL) goto failed; - state->ctx = result; result->private_data = state; - state->call = call; + state->ctx = result; - state->domain = service->domains; + state->samr_pipe = samr_pipe; - ctx = wb_init_domain_send(state->domain, result->event_ctx, - call->wbconn->conn->msg_ctx); - if (ctx == NULL) goto failed; - ctx->async.fn = cmd_checkmachacc_recv_init; - ctx->async.private_data = state; + state->user_handle = talloc(state, struct policy_handle); + if (state->user_handle == NULL) goto failed; + + state->o.in.domain_handle = domain_handle; + state->o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + state->o.in.rid = rid; + state->o.out.user_handle = state->user_handle; + + req = dcerpc_samr_OpenUser_send(state->samr_pipe, state, &state->o); + if (req == NULL) goto failed; + req->async.callback = samr_usergroups_recv_open; + req->async.private = state; return result; failed: talloc_free(result); return NULL; } + +static void samr_usergroups_recv_open(struct rpc_request *req) +{ + struct samr_getuserdomgroups_state *state = + talloc_get_type(req->async.private, + struct samr_getuserdomgroups_state); -static void cmd_checkmachacc_recv_init(struct composite_context *ctx) + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = state->o.out.result; + if (!composite_is_ok(state->ctx)) return; + + state->g.in.user_handle = state->user_handle; + + req = dcerpc_samr_GetGroupsForUser_send(state->samr_pipe, state, + &state->g); + composite_continue_rpc(state->ctx, req, samr_usergroups_recv_groups, + state); +} + +static void samr_usergroups_recv_groups(struct rpc_request *req) { - struct cmd_checkmachacc_state *state = - talloc_get_type(ctx->async.private_data, - struct cmd_checkmachacc_state); + struct samr_getuserdomgroups_state *state = + talloc_get_type(req->async.private, + struct samr_getuserdomgroups_state); - state->ctx->status = wb_init_domain_recv(ctx); + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = state->g.out.result; if (!composite_is_ok(state->ctx)) return; - composite_done(state->ctx); + state->c.in.handle = state->user_handle; + state->c.out.handle = state->user_handle; + + req = dcerpc_samr_Close_send(state->samr_pipe, state, &state->c); + composite_continue_rpc(state->ctx, req, samr_usergroups_recv_close, + state); } -NTSTATUS wb_cmd_checkmachacc_recv(struct composite_context *c) +static void samr_usergroups_recv_close(struct rpc_request *req) { - NTSTATUS status = composite_wait(c); - talloc_free(c); - return status; + struct samr_getuserdomgroups_state *state = + talloc_get_type(req->async.private, + struct samr_getuserdomgroups_state); + + state->ctx->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(state->ctx)) return; + state->ctx->status = state->c.out.result; + if (!composite_is_ok(state->ctx)) return; + + composite_done(state->ctx); } -NTSTATUS wb_cmd_checkmachacc(struct wbsrv_call *call) +NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx, + TALLOC_CTX *mem_ctx, + int *num_rids, uint32_t **rids) { - struct composite_context *c = wb_cmd_checkmachacc_send(call); - return wb_cmd_checkmachacc_recv(c); + struct samr_getuserdomgroups_state *state = + talloc_get_type(ctx->private_data, + struct samr_getuserdomgroups_state); + + int i; + NTSTATUS status = composite_wait(ctx); + if (!NT_STATUS_IS_OK(status)) goto done; + + *num_rids = state->g.out.rids->count; + *rids = talloc_array(mem_ctx, uint32_t, *num_rids); + if (*rids == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0; i<*num_rids; i++) { + (*rids)[i] = state->g.out.rids->rids[i].rid; + } + + done: + talloc_free(ctx); + return status; }