diff options
Diffstat (limited to 'source4/winbind/wb_init_domain.c')
-rw-r--r-- | source4/winbind/wb_init_domain.c | 268 |
1 files changed, 84 insertions, 184 deletions
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index c5082a9a3e..21ea668043 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -39,6 +39,8 @@ #include "librpc/gen_ndr/ndr_lsa.h" #include "libcli/auth/credentials.h" +#include "libcli/ldap/ldap_client.h" + /* * Initialize a domain: @@ -67,29 +69,11 @@ struct init_domain_state { struct wbsrv_domain *domain; struct wbsrv_service *service; - int num_dcs; - struct nbt_dc_name *dcs; - const char *dcaddr; - struct smb_composite_connect conn; - struct dcerpc_pipe *auth2_pipe; - struct dcerpc_pipe *netlogon_pipe; - - struct dcerpc_pipe *lsa_pipe; - struct policy_handle *lsa_policy; - - struct dcerpc_pipe *samr_pipe; - struct policy_handle *samr_handle; - struct policy_handle *domain_handle; - - struct ldap_connection *ldap_conn; - struct lsa_QueryInfoPolicy queryinfo; }; -static void init_domain_recv_dcs(struct composite_context *ctx); -static void init_domain_recv_dcip(struct composite_context *ctx); 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); @@ -98,13 +82,14 @@ static void init_domain_recv_queryinfo(struct rpc_request *req); static void init_domain_recv_ldapconn(struct composite_context *ctx); static void init_domain_recv_samr(struct composite_context *ctx); -struct composite_context *wb_init_domain_send(struct wbsrv_service *service, - struct wbsrv_domain *domain) +struct composite_context *wb_init_domain_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, + struct wb_dom_info *dom_info) { struct composite_context *result, *ctx; struct init_domain_state *state; - result = talloc(domain, 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; @@ -116,112 +101,43 @@ struct composite_context *wb_init_domain_send(struct wbsrv_service *service, result->private_data = state; state->service = service; - state->domain = domain; - - if (domain->dcname != NULL) { - struct nbt_name name; - make_nbt_name(&name, domain->dcname, 0x20); - ctx = resolve_name_send(&name, result->event_ctx, - lp_name_resolve_order()); - if (ctx == NULL) goto failed; - ctx->async.fn = init_domain_recv_dcip; - ctx->async.private_data = state; - return result; - } - if (state->domain->schannel_creds != NULL) { - talloc_free(state->domain->schannel_creds); - } + state->domain = talloc(state, struct wbsrv_domain); + if (state->domain == NULL) goto failed; + + state->domain->info = talloc_reference(state->domain, dom_info); + if (state->domain->info == NULL) goto failed; state->domain->schannel_creds = cli_credentials_init(state->domain); if (state->domain->schannel_creds == NULL) goto failed; + cli_credentials_set_conf(state->domain->schannel_creds); state->ctx->status = cli_credentials_set_machine_account(state->domain-> schannel_creds); if (!NT_STATUS_IS_OK(state->ctx->status)) goto failed; - 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; - ctx->async.private_data = state; - return result; - - failed: - talloc_free(result); - return NULL; -} - -static void init_domain_recv_dcs(struct composite_context *ctx) -{ - struct init_domain_state *state = - talloc_get_type(ctx->async.private_data, - struct init_domain_state); - - state->ctx->status = wb_finddcs_recv(ctx, state, &state->num_dcs, - &state->dcs); - if (!composite_is_ok(state->ctx)) return; - - if (state->num_dcs < 1) { - composite_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS); - return; - } - - 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.dest_host = dom_info->dc_address; state->conn.in.port = 0; - state->conn.in.called_name = state->dcs[0].name; + state->conn.in.called_name = dom_info->dc_name; state->conn.in.service = "IPC$"; state->conn.in.service_type = "IPC"; - state->conn.in.workgroup = state->domain->name; - + state->conn.in.workgroup = dom_info->name; state->conn.in.credentials = state->domain->schannel_creds; - 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; ctx = smb_composite_connect_send(&state->conn, state->domain, - state->ctx->event_ctx); - composite_continue(state->ctx, ctx, init_domain_recv_tree, state); -} - -static void init_domain_recv_dcip(struct composite_context *ctx) -{ - struct init_domain_state *state = - talloc_get_type(ctx->async.private_data, - struct init_domain_state); - - state->ctx->status = resolve_name_recv(ctx, state, &state->dcaddr); - if (!composite_is_ok(state->ctx)) return; - - state->conn.in.dest_host = state->dcaddr; - state->conn.in.port = 0; - state->conn.in.called_name = state->domain->dcname; - state->conn.in.service = "IPC$"; - state->conn.in.service_type = "IPC"; - state->conn.in.workgroup = state->domain->name; - state->conn.in.credentials = state->domain->schannel_creds; + result->event_ctx); + if (ctx == NULL) goto failed; - state->conn.in.fallback_to_anonymous = True; + ctx->async.fn = init_domain_recv_tree; + ctx->async.private_data = state; + return result; - ctx = smb_composite_connect_send(&state->conn, state->domain, - state->ctx->event_ctx); - composite_continue(state->ctx, ctx, init_domain_recv_tree, state); + failed: + talloc_free(result); + return NULL; } static void init_domain_recv_tree(struct composite_context *ctx) @@ -235,7 +151,7 @@ static void init_domain_recv_tree(struct composite_context *ctx) if ((state->domain->schannel_creds != NULL) && (!cli_credentials_is_anonymous(state->domain->schannel_creds)) && ((lp_server_role() == ROLE_DOMAIN_MEMBER) && - (dom_sid_equal(state->domain->sid, + (dom_sid_equal(state->domain->info->sid, state->service->primary_sid)))) { ctx = wb_get_schannel_creds_send(state, state->domain->schannel_creds, @@ -255,37 +171,36 @@ static void init_domain_recv_netlogoncreds(struct composite_context *ctx) struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); + struct dcerpc_pipe *auth2_pipe; struct smbcli_tree *tree = NULL; - state->ctx->status = wb_get_schannel_creds_recv(ctx, state, - &state->auth2_pipe); + state->ctx->status = + wb_get_schannel_creds_recv(ctx, state, &auth2_pipe); if (!composite_is_ok(state->ctx)) return; if (!lp_winbind_sealed_pipes()) { - state->netlogon_pipe = talloc_reference(state, - state->auth2_pipe); + state->domain->netlogon_pipe = talloc_reference(state->domain, + auth2_pipe); ctx = wb_connect_lsa_send(state, state->conn.out.tree, NULL); composite_continue(state->ctx, ctx, init_domain_recv_lsa, state); return; } - state->netlogon_pipe = dcerpc_pipe_init(state, state->ctx->event_ctx); - if (composite_nomem(state->netlogon_pipe, state->ctx)) return; - - if (state->auth2_pipe != NULL) { - tree = dcerpc_smb_tree(state->auth2_pipe->conn); - } + state->domain->netlogon_pipe = + dcerpc_pipe_init(state->domain, state->ctx->event_ctx); + if (composite_nomem(state->domain->netlogon_pipe, state->ctx)) return; + tree = dcerpc_smb_tree(auth2_pipe->conn); if (tree == NULL) { composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); return; } - ctx = dcerpc_pipe_open_smb_send(state->netlogon_pipe->conn, tree, - "\\netlogon"); - composite_continue(state->ctx, ctx, - init_domain_recv_netlogonpipe, state); + ctx = dcerpc_pipe_open_smb_send(state->domain->netlogon_pipe->conn, + tree, "\\netlogon"); + composite_continue(state->ctx, ctx, init_domain_recv_netlogonpipe, + state); } static void init_domain_recv_netlogonpipe(struct composite_context *ctx) @@ -297,9 +212,10 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) state->ctx->status = dcerpc_pipe_open_smb_recv(ctx); if (!composite_is_ok(state->ctx)) return; - state->netlogon_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); + state->domain->netlogon_pipe->conn->flags |= + (DCERPC_SIGN | DCERPC_SEAL); state->ctx->status = - dcerpc_bind_auth_password(state->netlogon_pipe, + dcerpc_bind_auth_password(state->domain->netlogon_pipe, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION, state->domain->schannel_creds, @@ -320,19 +236,19 @@ static void init_domain_recv_lsa(struct composite_context *ctx) struct rpc_request *req; - state->ctx->status = wb_connect_lsa_recv(ctx, state, + state->ctx->status = wb_connect_lsa_recv(ctx, state->domain, &state->domain->lsa_auth_type, - &state->lsa_pipe, - &state->lsa_policy); + &state->domain->lsa_pipe, + &state->domain->lsa_policy); if (!composite_is_ok(state->ctx)) return; /* Give the tree to the pipes. */ -// talloc_unlink(state, state->conn.out.tree); + talloc_unlink(state, state->conn.out.tree); - state->queryinfo.in.handle = state->lsa_policy; + state->queryinfo.in.handle = state->domain->lsa_policy; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; - req = dcerpc_lsa_QueryInfoPolicy_send(state->lsa_pipe, state, + req = dcerpc_lsa_QueryInfoPolicy_send(state->domain->lsa_pipe, state, &state->queryinfo); composite_continue_rpc(state->ctx, req, init_domain_recv_queryinfo, state); @@ -353,31 +269,33 @@ static void init_domain_recv_queryinfo(struct rpc_request *req) dominfo = &state->queryinfo.out.info->account_domain; - if (strcasecmp(state->domain->name, dominfo->name.string) != 0) { + if (strcasecmp(state->domain->info->name, dominfo->name.string) != 0) { DEBUG(2, ("Expected domain name %s, DC %s said %s\n", - state->domain->name, - dcerpc_server_name(state->lsa_pipe), + state->domain->info->name, + dcerpc_server_name(state->domain->lsa_pipe), dominfo->name.string)); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } - if (!dom_sid_equal(state->domain->sid, dominfo->sid)) { + if (!dom_sid_equal(state->domain->info->sid, dominfo->sid)) { DEBUG(2, ("Expected domain sid %s, DC %s said %s\n", - dom_sid_string(state, state->domain->sid), - dcerpc_server_name(state->lsa_pipe), + dom_sid_string(state, state->domain->info->sid), + dcerpc_server_name(state->domain->lsa_pipe), dom_sid_string(state, dominfo->sid))); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } - state->ldap_conn = ldap_new_connection(state, state->ctx->event_ctx); - composite_nomem(state->ldap_conn, state->ctx); + state->domain->ldap_conn = + ldap_new_connection(state->domain, state->ctx->event_ctx); + composite_nomem(state->domain->ldap_conn, state->ctx); - ldap_url = talloc_asprintf(state, "ldap://%s/", state->dcaddr); + ldap_url = talloc_asprintf(state, "ldap://%s/", + state->domain->info->dc_address); composite_nomem(ldap_url, state->ctx); - ctx = ldap_connect_send(state->ldap_conn, ldap_url); + ctx = ldap_connect_send(state->domain->ldap_conn, ldap_url); composite_continue(state->ctx, ctx, init_domain_recv_ldapconn, state); } @@ -388,16 +306,25 @@ static void init_domain_recv_ldapconn(struct composite_context *ctx) struct init_domain_state); state->ctx->status = ldap_connect_recv(ctx); - DEBUG(0, ("ldap_connect returned %s\n", - nt_errstr(state->ctx->status))); + if (NT_STATUS_IS_OK(state->ctx->status)) { + state->domain->ldap_conn->host = + talloc_strdup(state->domain->ldap_conn, + state->domain->info->dc_name); + state->ctx->status = + ldap_bind_sasl(state->domain->ldap_conn, + state->domain->schannel_creds); + DEBUG(0, ("ldap_bind returned %s\n", + nt_errstr(state->ctx->status))); + } - state->samr_pipe = dcerpc_pipe_init(state, state->ctx->event_ctx); - if (composite_nomem(state->samr_pipe, state->ctx)) return; + state->domain->samr_pipe = + dcerpc_pipe_init(state->domain, state->ctx->event_ctx); + if (composite_nomem(state->domain->samr_pipe, state->ctx)) return; ctx = wb_connect_sam_send(state, state->conn.out.tree, state->domain->lsa_auth_type, state->domain->schannel_creds, - state->domain->sid); + state->domain->info->sid); composite_continue(state->ctx, ctx, init_domain_recv_samr, state); } @@ -407,61 +334,34 @@ static void init_domain_recv_samr(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct init_domain_state); - state->ctx->status = wb_connect_sam_recv(ctx, state, &state->samr_pipe, - &state->samr_handle, - &state->domain_handle); + state->ctx->status = wb_connect_sam_recv( + ctx, state->domain, &state->domain->samr_pipe, + &state->domain->samr_handle, &state->domain->domain_handle); if (!composite_is_ok(state->ctx)) return; composite_done(state->ctx); } -NTSTATUS wb_init_domain_recv(struct composite_context *c) +NTSTATUS wb_init_domain_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + struct wbsrv_domain **result) { NTSTATUS status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct init_domain_state *state = talloc_get_type(c->private_data, struct init_domain_state); - struct wbsrv_domain *domain = state->domain; - - talloc_free(domain->netlogon_auth2_pipe); - domain->netlogon_auth2_pipe = - talloc_steal(domain, state->auth2_pipe); - - talloc_free(domain->netlogon_pipe); - domain->netlogon_pipe = - talloc_steal(domain, state->netlogon_pipe); - - talloc_free(domain->lsa_pipe); - domain->lsa_pipe = - talloc_steal(domain, state->lsa_pipe); - - talloc_free(domain->lsa_policy); - domain->lsa_policy = - talloc_steal(domain, state->lsa_policy); - - talloc_free(domain->samr_pipe); - domain->samr_pipe = - talloc_steal(domain, state->samr_pipe); - - talloc_free(domain->samr_handle); - domain->samr_handle = - talloc_steal(domain, state->samr_handle); - - talloc_free(domain->domain_handle); - domain->domain_handle = - talloc_steal(domain, state->domain_handle); - - domain->initialized = True; + *result = talloc_steal(mem_ctx, state->domain); } talloc_free(c); return status; } -NTSTATUS wb_init_domain(struct wbsrv_service *service, - struct wbsrv_domain *domain) +NTSTATUS wb_init_domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, + struct wb_dom_info *dom_info, + struct wbsrv_domain **result) { struct composite_context *c = - wb_init_domain_send(service, domain); - return wb_init_domain_recv(c); + wb_init_domain_send(mem_ctx, service, dom_info); + return wb_init_domain_recv(c, mem_ctx, result); } |