diff options
author | Volker Lendecke <vlendec@samba.org> | 2005-10-10 19:57:55 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:39:39 -0500 |
commit | d617556ef50863d6a03c81a04f0f6b05848a250e (patch) | |
tree | c5963dd3778e2cb2f6e3b4942649f1d9e3195677 /source4/winbind/wb_init_domain.c | |
parent | 3dfe8c22b835c34453b23b654cd5649d698da3cb (diff) | |
download | samba-d617556ef50863d6a03c81a04f0f6b05848a250e.tar.gz samba-d617556ef50863d6a03c81a04f0f6b05848a250e.tar.bz2 samba-d617556ef50863d6a03c81a04f0f6b05848a250e.zip |
r10878: Reply to some comments by tridge and metze:
* rename the composite helper functions from comp_* to composite_*
* Move the lsa initialization to wb_connect_lsa.c
* Equip smb_composite_connect with a fallback_to_anonymous
The latter two simplify wb_init_domain.c quite a bit.
Volker
(This used to be commit deb127e04ea01ae93394da5ebffb39d81caeb6d9)
Diffstat (limited to 'source4/winbind/wb_init_domain.c')
-rw-r--r-- | source4/winbind/wb_init_domain.c | 327 |
1 files changed, 52 insertions, 275 deletions
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index 0ac7d11d64..c9389ea7dd 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -1,6 +1,8 @@ /* 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 @@ -17,9 +19,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - a composite API for initializing a domain -*/ #include "includes.h" #include "libcli/composite/composite.h" @@ -39,147 +38,12 @@ #include "libcli/auth/credentials.h" -/* Helper to initialize LSA with different auth methods and opening the lsa - * policy */ - -struct init_lsa_state { - struct composite_context *ctx; - struct dcerpc_pipe *lsa_pipe; - - uint8_t auth_type; - struct cli_credentials *creds; - - struct lsa_ObjectAttribute objectattr; - struct lsa_OpenPolicy2 openpolicy; - struct policy_handle *handle; -}; - -static void init_lsa_recv_pipe(struct composite_context *ctx); -static void init_lsa_recv_openpol(struct rpc_request *req); - -static struct composite_context *wb_init_lsa_send(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); - if (result == NULL) goto failed; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->event_ctx = tree->session->transport->socket->event.ctx; - - state = talloc(result, struct init_lsa_state); - if (state == NULL) goto failed; - state->ctx = result; - result->private_data = state; - - state->auth_type = auth_type; - state->creds = creds; - - state->lsa_pipe = dcerpc_pipe_init(state, result->event_ctx); - if (state->lsa_pipe == NULL) goto failed; - - ctx = dcerpc_pipe_open_smb_send(state->lsa_pipe->conn, tree, - "\\lsarpc"); - ctx->async.fn = init_lsa_recv_pipe; - ctx->async.private_data = state; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void init_lsa_recv_pipe(struct composite_context *ctx) -{ - struct init_lsa_state *state = - talloc_get_type(ctx->async.private_data, - struct init_lsa_state); - struct rpc_request *req; - - state->ctx->status = dcerpc_pipe_open_smb_recv(ctx); - if (!comp_is_ok(state->ctx)) return; - - switch (state->auth_type) { - case DCERPC_AUTH_TYPE_NONE: - state->ctx->status = - dcerpc_bind_auth_none(state->lsa_pipe, - DCERPC_LSARPC_UUID, - DCERPC_LSARPC_VERSION); - break; - case DCERPC_AUTH_TYPE_NTLMSSP: - case DCERPC_AUTH_TYPE_SCHANNEL: - if (state->creds == NULL) { - comp_error(state->ctx, NT_STATUS_INTERNAL_ERROR); - return; - } - state->lsa_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); - state->ctx->status = - dcerpc_bind_auth_password(state->lsa_pipe, - DCERPC_LSARPC_UUID, - DCERPC_LSARPC_VERSION, - state->creds, - state->auth_type, - NULL); - break; - default: - state->ctx->status = NT_STATUS_INTERNAL_ERROR; - - } - - state->handle = talloc(state, struct policy_handle); - if (comp_nomem(state->handle, state->ctx)) return; - - state->openpolicy.in.system_name = - talloc_asprintf(state, "\\\\%s", - dcerpc_server_name(state->lsa_pipe)); - ZERO_STRUCT(state->objectattr); - state->openpolicy.in.attr = &state->objectattr; - state->openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - state->openpolicy.out.handle = state->handle; - - req = dcerpc_lsa_OpenPolicy2_send(state->lsa_pipe, state, - &state->openpolicy); - rpc_cont(state->ctx, req, init_lsa_recv_openpol, state); -} - -static void init_lsa_recv_openpol(struct rpc_request *req) -{ - struct init_lsa_state *state = - talloc_get_type(req->async.private, - struct init_lsa_state); - - state->ctx->status = dcerpc_ndr_request_recv(req); - if (!comp_is_ok(state->ctx)) return; - state->ctx->status = state->openpolicy.out.result; - if (!comp_is_ok(state->ctx)) return; - - comp_done(state->ctx); -} - -static NTSTATUS wb_init_lsa_recv(struct composite_context *c, - TALLOC_CTX *mem_ctx, - struct dcerpc_pipe **lsa_pipe, - struct policy_handle **lsa_policy) -{ - NTSTATUS status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct init_lsa_state *state = - talloc_get_type(c->private_data, - struct init_lsa_state); - *lsa_pipe = talloc_steal(mem_ctx, state->lsa_pipe); - *lsa_policy = talloc_steal(mem_ctx, state->handle); - } - talloc_free(c); - return status; -} - /* * Initialize a domain: * - * - With schannel credentials, try to open the SMB connection with the machine - * creds. Fall back to anonymous. + * - With schannel credentials, try to open the SMB connection with the + * machine creds. This works against W2k3SP1 with an NTLMSSP session + * setup. Fall back to anonymous. * * - If we have schannel creds, do the auth2 and open the schannel'ed netlogon * pipe. @@ -215,17 +79,10 @@ struct init_domain_state { }; static void init_domain_recv_dcs(struct composite_context *ctx); -static void init_domain_recv_authsmb(struct composite_context *ctx); -static void init_domain_anonsmb(struct init_domain_state *state); -static void init_domain_recv_anonsmb(struct composite_context *ctx); -static void init_domain_openpipes(struct init_domain_state *state); -static void init_domain_openlsa(struct init_domain_state *state); +static void init_domain_recv_tree(struct composite_context *ctx); static void init_domain_recv_netlogoncreds(struct composite_context *ctx); static void init_domain_recv_netlogonpipe(struct composite_context *ctx); -static void init_domain_recv_lsa_ntlmssp(struct composite_context *ctx); -static void init_domain_recv_lsa_schannel(struct composite_context *ctx); -static void init_domain_recv_lsa_none(struct composite_context *ctx); -static void init_domain_check_lsa(struct init_domain_state *state); +static void init_domain_recv_lsa(struct composite_context *ctx); static void init_domain_recv_queryinfo(struct rpc_request *req); struct composite_context *wb_init_domain_send(struct wbsrv_domain *domain, @@ -280,10 +137,10 @@ static void init_domain_recv_dcs(struct composite_context *ctx) state->ctx->status = wb_finddcs_recv(ctx, state, &state->num_dcs, &state->dcs); - if (!comp_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) return; if (state->num_dcs < 1) { - comp_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS); + composite_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS); return; } @@ -294,72 +151,46 @@ static void init_domain_recv_dcs(struct composite_context *ctx) state->conn.in.service_type = "IPC"; state->conn.in.workgroup = state->domain->name; - if (state->domain->schannel_creds != NULL) { - /* Try to connect as workstation */ - state->conn.in.credentials = state->domain->schannel_creds; - ctx = smb_composite_connect_send(&state->conn, state, - state->ctx->event_ctx); - comp_cont(state->ctx, ctx, init_domain_recv_authsmb, state); - return; - } - - init_domain_anonsmb(state); -} - -static void init_domain_recv_authsmb(struct composite_context *ctx) -{ - struct init_domain_state *state = - talloc_get_type(ctx->async.private_data, - struct init_domain_state); + state->conn.in.credentials = state->domain->schannel_creds; - state->ctx->status = smb_composite_connect_recv(ctx, state); - if (NT_STATUS_IS_OK(state->ctx->status)) { - init_domain_openpipes(state); - return; + if (state->conn.in.credentials == NULL) { + state->conn.in.credentials = cli_credentials_init(state); + if (composite_nomem(state->conn.in.credentials, state->ctx)) { + return; + } + cli_credentials_set_conf(state->conn.in.credentials); + cli_credentials_set_anonymous(state->conn.in.credentials); } + + state->conn.in.fallback_to_anonymous = True; - init_domain_anonsmb(state); -} - -static void init_domain_anonsmb(struct init_domain_state *state) -{ - struct composite_context *ctx; - - state->conn.in.credentials = cli_credentials_init(state); - if (comp_nomem(state->conn.in.credentials, state->ctx)) return; - cli_credentials_set_conf(state->conn.in.credentials); - cli_credentials_set_anonymous(state->conn.in.credentials); ctx = smb_composite_connect_send(&state->conn, state, state->ctx->event_ctx); - comp_cont(state->ctx, ctx, init_domain_recv_anonsmb, state); + composite_continue(state->ctx, ctx, init_domain_recv_tree, state); } -static void init_domain_recv_anonsmb(struct composite_context *ctx) +static void init_domain_recv_tree(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); state->ctx->status = smb_composite_connect_recv(ctx, state); - if (!comp_is_ok(state->ctx)) return; - - init_domain_openpipes(state); -} - -static void init_domain_openpipes(struct init_domain_state *state) -{ - struct composite_context *ctx; + if (!composite_is_ok(state->ctx)) return; if (state->domain->schannel_creds == NULL) { /* No chance to open netlogon */ - init_domain_openlsa(state); + ctx = wb_connect_lsa_send(state->conn.out.tree, NULL); + composite_continue(state->ctx, ctx, + init_domain_recv_lsa, state); return; } ctx = wb_get_schannel_creds_send(state->domain->schannel_creds, state->conn.out.tree, state->ctx->event_ctx); - comp_cont(state->ctx, ctx, init_domain_recv_netlogoncreds, state); + composite_continue(state->ctx, ctx, + init_domain_recv_netlogoncreds, state); } static void init_domain_recv_netlogoncreds(struct composite_context *ctx) @@ -371,25 +202,26 @@ static void init_domain_recv_netlogoncreds(struct composite_context *ctx) state->ctx->status = wb_get_schannel_creds_recv(ctx, state, &state->auth2_pipe); - if (!comp_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) return; talloc_unlink(state, state->conn.out.tree); /* The pipe owns it now */ state->netlogon_pipe = dcerpc_pipe_init(state, state->ctx->event_ctx); - if (comp_nomem(state->netlogon_pipe, state->ctx)) return; + if (composite_nomem(state->netlogon_pipe, state->ctx)) return; if (state->auth2_pipe != NULL) { tree = dcerpc_smb_tree(state->auth2_pipe->conn); } if (tree == NULL) { - comp_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); return; } ctx = dcerpc_pipe_open_smb_send(state->netlogon_pipe->conn, tree, "\\netlogon"); - comp_cont(state->ctx, ctx, init_domain_recv_netlogonpipe, state); + composite_continue(state->ctx, ctx, + init_domain_recv_netlogonpipe, state); } static void init_domain_recv_netlogonpipe(struct composite_context *ctx) @@ -399,7 +231,7 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) struct init_domain_state); state->ctx->status = dcerpc_pipe_open_smb_recv(ctx); - if (!comp_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) return; state->netlogon_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); state->ctx->status = @@ -409,85 +241,29 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) state->domain->schannel_creds, DCERPC_AUTH_TYPE_SCHANNEL, NULL); - if (!comp_is_ok(state->ctx)) return; - - init_domain_openlsa(state); -} - -static void init_domain_openlsa(struct init_domain_state *state) -{ - struct composite_context *ctx; - - if (state->domain->schannel_creds == NULL) { - ctx = wb_init_lsa_send(state->conn.out.tree, - DCERPC_AUTH_TYPE_NONE, - NULL); - comp_cont(state->ctx, ctx, init_domain_recv_lsa_none, state); - return; - } - ctx = wb_init_lsa_send(state->conn.out.tree, DCERPC_AUTH_TYPE_NTLMSSP, - state->domain->schannel_creds); - comp_cont(state->ctx, ctx, init_domain_recv_lsa_ntlmssp, state); + ctx = wb_connect_lsa_send(state->conn.out.tree, + state->domain->schannel_creds); + composite_continue(state->ctx, ctx, init_domain_recv_lsa, state); } -static void init_domain_recv_lsa_ntlmssp(struct composite_context *ctx) +static void init_domain_recv_lsa(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); - state->ctx->status = wb_init_lsa_recv(ctx, state, &state->lsa_pipe, - &state->lsa_policy); - if (NT_STATUS_IS_OK(state->ctx->status)) { - init_domain_check_lsa(state); - return; - } - - ctx = wb_init_lsa_send(state->conn.out.tree, - DCERPC_AUTH_TYPE_SCHANNEL, - state->domain->schannel_creds); - comp_cont(state->ctx, ctx, init_domain_recv_lsa_schannel, state); -} - -static void init_domain_recv_lsa_schannel(struct composite_context *ctx) -{ - struct init_domain_state *state = - talloc_get_type(ctx->async.private_data, - struct init_domain_state); - - state->ctx->status = wb_init_lsa_recv(ctx, state, &state->lsa_pipe, - &state->lsa_policy); - if (NT_STATUS_IS_OK(state->ctx->status)) { - init_domain_check_lsa(state); - return; - } - - ctx = wb_init_lsa_send(state->conn.out.tree, - DCERPC_AUTH_TYPE_NONE, NULL); - comp_cont(state->ctx, ctx, init_domain_recv_lsa_none, state); -} - -static void init_domain_recv_lsa_none(struct composite_context *ctx) -{ - struct init_domain_state *state = - talloc_get_type(ctx->async.private_data, - struct init_domain_state); - - state->ctx->status = wb_init_lsa_recv(ctx, state, &state->lsa_pipe, - &state->lsa_policy); - if (!comp_is_ok(state->ctx)) return; - - init_domain_check_lsa(state); -} - -static void init_domain_check_lsa(struct init_domain_state *state) -{ struct rpc_request *req; + uint8_t auth_type; + + state->ctx->status = wb_connect_lsa_recv(ctx, state, &auth_type, + &state->lsa_pipe, + &state->lsa_policy); + if (!composite_is_ok(state->ctx)) return; if (state->auth2_pipe == NULL) { - /* Give the tree to the LSA pipe, otherwise it has been given - * to the auth2 pipe already */ + /* 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); state->conn.out.tree = NULL; } @@ -497,7 +273,8 @@ static void init_domain_check_lsa(struct init_domain_state *state) req = dcerpc_lsa_QueryInfoPolicy_send(state->lsa_pipe, state, &state->queryinfo); - rpc_cont(state->ctx, req, init_domain_recv_queryinfo, state); + composite_continue_rpc(state->ctx, req, + init_domain_recv_queryinfo, state); } static void init_domain_recv_queryinfo(struct rpc_request *req) @@ -507,9 +284,9 @@ static void init_domain_recv_queryinfo(struct rpc_request *req) struct lsa_DomainInfo *dominfo; state->ctx->status = dcerpc_ndr_request_recv(req); - if (!comp_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->queryinfo.out.result; - if (!comp_is_ok(state->ctx)) return; + if (!composite_is_ok(state->ctx)) return; dominfo = &state->queryinfo.out.info->account_domain; @@ -518,7 +295,7 @@ static void init_domain_recv_queryinfo(struct rpc_request *req) state->domain->name, dcerpc_server_name(state->lsa_pipe), dominfo->name.string)); - comp_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); + composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } @@ -527,11 +304,11 @@ static void init_domain_recv_queryinfo(struct rpc_request *req) dom_sid_string(state, state->domain->sid), dcerpc_server_name(state->lsa_pipe), dom_sid_string(state, dominfo->sid))); - comp_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); + composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } - comp_done(state->ctx); + composite_done(state->ctx); } NTSTATUS wb_init_domain_recv(struct composite_context *c) |