summaryrefslogtreecommitdiff
path: root/source4/winbind/wb_init_domain.c
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2005-11-05 23:46:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:45:49 -0500
commit69307693dc47cdaa931551c99914e85273037886 (patch)
tree538173f824d7e93fc740ccea105f61196a070859 /source4/winbind/wb_init_domain.c
parentf792c4f8f23793b2a99d2cb6beff12bbe4044151 (diff)
downloadsamba-69307693dc47cdaa931551c99914e85273037886.tar.gz
samba-69307693dc47cdaa931551c99914e85273037886.tar.bz2
samba-69307693dc47cdaa931551c99914e85273037886.zip
r11528: Separate finding dcs from initializing a domain. Makes it easier to possibly
support cldap and other stuff in the future. This temporarily disables wbinfo -t, but that will come back soon. Try an ldap bind using gss-spnego. This got me krb5 binds against "our" w2k3 and a trusted w2k, although with some memleaks from krb5 and a BAD_OPTION tgs-rep error. Volker (This used to be commit d14948fdf687c8f70ef9ec35445b7eb04da84253)
Diffstat (limited to 'source4/winbind/wb_init_domain.c')
-rw-r--r--source4/winbind/wb_init_domain.c268
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);
}