summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/ldap/ldap_client.h2
-rw-r--r--source4/winbind/config.mk2
-rw-r--r--source4/winbind/wb_async_helpers.c3
-rw-r--r--source4/winbind/wb_async_helpers.h4
-rw-r--r--source4/winbind/wb_dom_info.c166
-rw-r--r--source4/winbind/wb_dom_info_trusted.c240
-rw-r--r--source4/winbind/wb_init_domain.c268
-rw-r--r--source4/winbind/wb_samba3_cmd.c2
-rw-r--r--source4/winbind/wb_samba3_protocol.c2
-rw-r--r--source4/winbind/wb_server.c38
-rw-r--r--source4/winbind/wb_server.h22
-rw-r--r--source4/winbind/wb_sid2domain.c177
12 files changed, 571 insertions, 355 deletions
diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h
index b61f765b40..38e043da1f 100644
--- a/source4/libcli/ldap/ldap_client.h
+++ b/source4/libcli/ldap/ldap_client.h
@@ -21,6 +21,8 @@
*/
+#include "libcli/ldap/ldap.h"
+
enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE};
/* this is the handle that the caller gets when an async ldap message
diff --git a/source4/winbind/config.mk b/source4/winbind/config.mk
index 6ed4f51cfc..d940a4daf1 100644
--- a/source4/winbind/config.mk
+++ b/source4/winbind/config.mk
@@ -10,6 +10,8 @@ INIT_OBJ_FILES = \
wb_samba3_protocol.o \
wb_samba3_cmd.o \
wb_init_domain.o \
+ wb_dom_info.o \
+ wb_dom_info_trusted.o \
wb_sid2domain.o \
wb_connect_lsa.o \
wb_connect_sam.o \
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index f00c0725b4..915638abb7 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -666,6 +666,8 @@ NTSTATUS wb_lsa_lookupnames(TALLOC_CTX *mem_ctx,
return wb_lsa_lookupnames_recv(c, mem_ctx, sids);
}
+#if 0
+
struct cmd_checkmachacc_state {
struct composite_context *ctx;
struct wbsrv_call *call;
@@ -730,6 +732,7 @@ NTSTATUS wb_cmd_checkmachacc(struct wbsrv_call *call)
struct composite_context *c = wb_cmd_checkmachacc_send(call);
return wb_cmd_checkmachacc_recv(c);
}
+#endif
struct samr_getuserdomgroups_state {
struct composite_context *ctx;
diff --git a/source4/winbind/wb_async_helpers.h b/source4/winbind/wb_async_helpers.h
index 413747090c..532cd9730c 100644
--- a/source4/winbind/wb_async_helpers.h
+++ b/source4/winbind/wb_async_helpers.h
@@ -34,7 +34,3 @@ struct wb_sid_object {
const char *name;
};
-struct wb_dom_info {
- const char *name;
- const struct dom_sid *sid;
-};
diff --git a/source4/winbind/wb_dom_info.c b/source4/winbind/wb_dom_info.c
new file mode 100644
index 0000000000..5be28cc055
--- /dev/null
+++ b/source4/winbind/wb_dom_info.c
@@ -0,0 +1,166 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Get a struct wb_dom_info for a domain using DNS, netbios, possibly cldap
+ etc.
+
+ 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 "libcli/smb_composite/smb_composite.h"
+#include "winbind/wb_async_helpers.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_stream.h"
+#include "smbd/service_task.h"
+#include "librpc/gen_ndr/nbt.h"
+#include "librpc/gen_ndr/ndr_irpc.h"
+#include "librpc/gen_ndr/samr.h"
+#include "lib/messaging/irpc.h"
+
+struct get_dom_info_state {
+ struct composite_context *ctx;
+ struct wbsrv_service *service;
+ struct nbtd_getdcname r;
+ struct wb_dom_info *info;
+};
+
+static void get_dom_info_recv_addrs(struct composite_context *ctx);
+static void get_dom_info_recv_dcname(struct irpc_request *ireq);
+
+struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ const char *domain_name,
+ const struct dom_sid *sid)
+{
+ struct composite_context *result, *ctx;
+ struct get_dom_info_state *state;
+ struct nbt_name name;
+
+ 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 get_dom_info_state);
+ if (state == NULL) goto failed;
+ state->ctx = result;
+ result->private_data = state;
+
+ state->service = service;
+
+ state->info = talloc_zero(state, struct wb_dom_info);
+ if (state->info == NULL) goto failed;
+
+ state->info->name = talloc_strdup(state->info, domain_name);
+ if (state->info->name == NULL) goto failed;
+ state->info->sid = dom_sid_dup(state->info, sid);
+ if (state->info->sid == NULL) goto failed;
+
+ make_nbt_name(&name, state->info->name, NBT_NAME_LOGON);
+
+ ctx = resolve_name_send(&name, result->event_ctx,
+ lp_name_resolve_order());
+ if (ctx == NULL) goto failed;
+
+ ctx->async.fn = get_dom_info_recv_addrs;
+ ctx->async.private_data = state;
+ return result;
+
+ failed:
+ talloc_free(result);
+ return NULL;
+}
+
+static void get_dom_info_recv_addrs(struct composite_context *ctx)
+{
+ struct get_dom_info_state *state =
+ talloc_get_type(ctx->async.private_data,
+ struct get_dom_info_state);
+ uint32_t *nbt_servers;
+ struct irpc_request *ireq;
+
+ state->ctx->status = resolve_name_recv(ctx, state->info,
+ &state->info->dc_address);
+ if (!composite_is_ok(state->ctx)) return;
+
+ nbt_servers = irpc_servers_byname(state->service->task->msg_ctx,
+ "nbt_server");
+ if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) {
+ composite_error(state->ctx, NT_STATUS_NO_LOGON_SERVERS);
+ return;
+ }
+
+ state->r.in.domainname = state->info->name;
+ state->r.in.ip_address = state->info->dc_address;
+ state->r.in.my_computername = lp_netbios_name();
+ state->r.in.my_accountname = talloc_asprintf(state, "%s$",
+ lp_netbios_name());
+ if (composite_nomem(state->r.in.my_accountname, state->ctx)) return;
+ state->r.in.account_control = ACB_WSTRUST;
+ state->r.in.domain_sid = dom_sid_dup(state, state->info->sid);
+ if (composite_nomem(state->r.in.domain_sid, state->ctx)) return;
+
+ ireq = irpc_call_send(state->service->task->msg_ctx, nbt_servers[0],
+ &dcerpc_table_irpc, DCERPC_NBTD_GETDCNAME,
+ &state->r, state);
+ composite_continue_irpc(state->ctx, ireq, get_dom_info_recv_dcname,
+ state);
+}
+
+static void get_dom_info_recv_dcname(struct irpc_request *ireq)
+{
+ struct get_dom_info_state *state =
+ talloc_get_type(ireq->async.private,
+ struct get_dom_info_state);
+
+
+ state->ctx->status = irpc_call_recv(ireq);
+ talloc_free(ireq);
+ if (!composite_is_ok(state->ctx)) return;
+
+ state->info->dc_name = talloc_steal(state->info, state->r.out.dcname);
+ composite_done(state->ctx);
+}
+
+NTSTATUS wb_get_dom_info_recv(struct composite_context *ctx,
+ TALLOC_CTX *mem_ctx,
+ struct wb_dom_info **result)
+{
+ NTSTATUS status = composite_wait(ctx);
+ if (NT_STATUS_IS_OK(status)) {
+ struct get_dom_info_state *state =
+ talloc_get_type(ctx->private_data,
+ struct get_dom_info_state);
+ *result = talloc_steal(mem_ctx, state->info);
+ }
+ talloc_free(ctx);
+ return status;
+}
+
+NTSTATUS wb_get_dom_info(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ const char *domain_name,
+ const struct dom_sid *sid,
+ struct wb_dom_info **result)
+{
+ struct composite_context *ctx =
+ wb_get_dom_info_send(mem_ctx, service, domain_name, sid);
+ return wb_get_dom_info_recv(ctx, mem_ctx, result);
+}
diff --git a/source4/winbind/wb_dom_info_trusted.c b/source4/winbind/wb_dom_info_trusted.c
new file mode 100644
index 0000000000..ce9e5b9c47
--- /dev/null
+++ b/source4/winbind/wb_dom_info_trusted.c
@@ -0,0 +1,240 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Get a struct wb_dom_info for a trusted domain, relying on "our" DC.
+
+ 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 "libcli/smb_composite/smb_composite.h"
+#include "winbind/wb_async_helpers.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_stream.h"
+#include "smbd/service_task.h"
+#include "librpc/gen_ndr/nbt.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
+
+struct trusted_dom_info_state {
+ struct composite_context *ctx;
+ struct wbsrv_service *service;
+ struct wbsrv_domain *my_domain;
+
+ struct netr_DsRGetDCName d;
+ struct netr_GetAnyDCName g;
+
+ struct wb_dom_info *info;
+};
+
+static void trusted_dom_info_recv_domain(struct composite_context *ctx);
+static void trusted_dom_info_recv_dsr(struct rpc_request *req);
+static void trusted_dom_info_recv_dcname(struct rpc_request *req);
+static void trusted_dom_info_recv_dcaddr(struct composite_context *ctx);
+
+struct composite_context *wb_trusted_dom_info_send(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ const char *domain_name,
+ const struct dom_sid *sid)
+{
+ struct composite_context *result, *ctx;
+ struct trusted_dom_info_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(result, struct trusted_dom_info_state);
+ if (state == NULL) goto failed;
+ state->ctx = result;
+ result->private_data = state;
+
+ state->info = talloc_zero(state, struct wb_dom_info);
+ if (state->info == NULL) goto failed;
+
+ state->service = service;
+
+ state->info->sid = dom_sid_dup(state->info, sid);
+ if (state->info->sid == NULL) goto failed;
+
+ state->info->name = talloc_strdup(state->info, domain_name);
+ if (state->info->name == NULL) goto failed;
+
+ ctx = wb_sid2domain_send(state, service, service->primary_sid);
+ if (ctx == NULL) goto failed;
+
+ ctx->async.fn = trusted_dom_info_recv_domain;
+ ctx->async.private_data = state;
+ return result;
+
+ failed:
+ talloc_free(result);
+ return NULL;
+}
+
+static void trusted_dom_info_recv_domain(struct composite_context *ctx)
+{
+ struct trusted_dom_info_state *state =
+ talloc_get_type(ctx->async.private_data,
+ struct trusted_dom_info_state);
+ struct rpc_request *req;
+
+ state->ctx->status = wb_sid2domain_recv(ctx, &state->my_domain);
+ if (!composite_is_ok(state->ctx)) return;
+
+ state->d.in.server_unc =
+ talloc_asprintf(state, "\\\\%s",
+ state->my_domain->info->dc_name);
+ if (composite_nomem(state->d.in.server_unc,
+ state->ctx)) return;
+
+ state->d.in.domain_name = state->info->name;
+ state->d.in.domain_guid = NULL;
+ state->d.in.site_guid = NULL;
+ state->d.in.flags = 0x40000000;
+
+ req = dcerpc_netr_DsRGetDCName_send(state->my_domain->netlogon_pipe,
+ state, &state->d);
+ composite_continue_rpc(state->ctx, req, trusted_dom_info_recv_dsr,
+ state);
+}
+
+/*
+ * dcerpc_netr_DsRGetDCName has replied
+ */
+
+static void trusted_dom_info_recv_dsr(struct rpc_request *req)
+{
+ struct trusted_dom_info_state *state =
+ talloc_get_type(req->async.private,
+ struct trusted_dom_info_state);
+
+ 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->d.out.result);
+ if (!NT_STATUS_IS_OK(state->ctx->status)) {
+ DEBUG(9, ("dsrgetdcname returned %s\n",
+ nt_errstr(state->ctx->status)));
+ goto fallback;
+ }
+
+ /* Hey, that was easy! */
+
+ state->info->dc_name = talloc_steal(state->info,
+ state->d.out.info->dc_unc);
+ if (*state->info->dc_name == '\\') state->info->dc_name++;
+ if (*state->info->dc_name == '\\') state->info->dc_name++;
+
+ state->info->dc_address = talloc_steal(state->info,
+ state->d.out.info->dc_address);
+ if (*state->info->dc_address == '\\') state->info->dc_address++;
+ if (*state->info->dc_address == '\\') state->info->dc_address++;
+
+ state->info->dns_name = talloc_steal(state->info,
+ state->d.out.info->domain_name);
+
+ composite_done(state->ctx);
+ return;
+
+ fallback:
+
+ state->g.in.logon_server = talloc_asprintf(
+ state, "\\\\%s",
+ dcerpc_server_name(state->my_domain->netlogon_pipe));
+ state->g.in.domainname = state->info->name;
+
+ req = dcerpc_netr_GetAnyDCName_send(state->my_domain->netlogon_pipe,
+ state, &state->g);
+ if (composite_nomem(req, state->ctx)) return;
+
+ composite_continue_rpc(state->ctx, req, trusted_dom_info_recv_dcname,
+ state);
+}
+
+static void trusted_dom_info_recv_dcname(struct rpc_request *req)
+{
+ struct trusted_dom_info_state *state =
+ talloc_get_type(req->async.private,
+ struct trusted_dom_info_state);
+ struct composite_context *ctx;
+ struct nbt_name name;
+
+ 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;
+
+ state->info->dc_name = talloc_steal(state->info,
+ state->g.out.dcname);
+
+ if (*state->info->dc_name == '\\') state->info->dc_name++;
+ if (*state->info->dc_name == '\\') state->info->dc_name++;
+
+ make_nbt_name(&name, state->info->dc_name, 0x20);
+ ctx = resolve_name_send(&name, state->service->task->event_ctx,
+ lp_name_resolve_order());
+
+ composite_continue(state->ctx, ctx, trusted_dom_info_recv_dcaddr,
+ state);
+}
+
+static void trusted_dom_info_recv_dcaddr(struct composite_context *ctx)
+{
+ struct trusted_dom_info_state *state =
+ talloc_get_type(ctx->async.private_data,
+ struct trusted_dom_info_state);
+
+ state->ctx->status = resolve_name_recv(ctx, state->info,
+ &state->info->dc_address);
+ if (!composite_is_ok(state->ctx)) return;
+
+ composite_done(state->ctx);
+}
+
+NTSTATUS wb_trusted_dom_info_recv(struct composite_context *ctx,
+ TALLOC_CTX *mem_ctx,
+ struct wb_dom_info **result)
+{
+ NTSTATUS status = composite_wait(ctx);
+ if (NT_STATUS_IS_OK(status)) {
+ struct trusted_dom_info_state *state =
+ talloc_get_type(ctx->private_data,
+ struct trusted_dom_info_state);
+ *result = talloc_steal(mem_ctx, state->info);
+ }
+ talloc_free(ctx);
+ return status;
+}
+
+NTSTATUS wb_trusted_dom_info(TALLOC_CTX *mem_ctx,
+ struct wbsrv_service *service,
+ const char *domain_name,
+ const struct dom_sid *sid,
+ struct wb_dom_info **result)
+{
+ struct composite_context *ctx =
+ wb_trusted_dom_info_send(mem_ctx, service, domain_name, sid);
+ return wb_trusted_dom_info_recv(ctx, mem_ctx, result);
+}
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);
}
diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c
index a5e7cb722b..d7496c2263 100644
--- a/source4/winbind/wb_samba3_cmd.c
+++ b/source4/winbind/wb_samba3_cmd.c
@@ -136,6 +136,7 @@ NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
return NT_STATUS_OK;
}
+#if 0
/*
Validate that we have a working pipe to the domain controller.
Return any NT error found in the process
@@ -169,6 +170,7 @@ static void checkmachacc_recv_creds(struct composite_context *ctx)
wbsrv_samba3_async_auth_epilogue(status, s3call);
}
+#endif
/*
Find the name of a suitable domain controller, by query on the
diff --git a/source4/winbind/wb_samba3_protocol.c b/source4/winbind/wb_samba3_protocol.c
index f9e4c54ce2..f9eb7a09d4 100644
--- a/source4/winbind/wb_samba3_protocol.c
+++ b/source4/winbind/wb_samba3_protocol.c
@@ -75,8 +75,10 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call)
case WINBINDD_INTERFACE_VERSION:
return wbsrv_samba3_interface_version(s3call);
+#if 0
case WINBINDD_CHECK_MACHACC:
return wbsrv_samba3_check_machacc(s3call);
+#endif
case WINBINDD_PING:
return wbsrv_samba3_ping(s3call);
diff --git a/source4/winbind/wb_server.c b/source4/winbind/wb_server.c
index d12adfc9d4..a66bc0832f 100644
--- a/source4/winbind/wb_server.c
+++ b/source4/winbind/wb_server.c
@@ -248,32 +248,6 @@ static const struct wbsrv_protocol_ops wbsrv_samba3_protocol_ops = {
.push_reply = wbsrv_samba3_push_reply
};
-static NTSTATUS init_my_domain(TALLOC_CTX *mem_ctx,
- struct wbsrv_domain **domain)
-{
- struct wbsrv_domain *result;
-
- result = talloc_zero(mem_ctx, struct wbsrv_domain);
- NT_STATUS_HAVE_NO_MEMORY(result);
-
- result->name = talloc_strdup(result, lp_workgroup());
- if (result->name == NULL) {
- talloc_free(result);
- return NT_STATUS_NO_MEMORY;
- }
-
- result->sid = secrets_get_domain_sid(result, lp_workgroup());
- if (result->sid == NULL) {
- talloc_free(result);
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
- result->initialized = False;
-
- *domain = result;
- return NT_STATUS_OK;
-}
-
/*
startup the winbind task
*/
@@ -304,16 +278,14 @@ static void winbind_task_init(struct task_server *task)
if (!service) goto nomem;
service->task = task;
- status = init_my_domain(service, &service->domains);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Could not init my domain: %s\n",
- nt_errstr(status)));
- task_server_terminate(task, nt_errstr(status));
+ service->primary_sid = secrets_get_domain_sid(service,
+ lp_workgroup());
+ if (service->primary_sid == NULL) {
+ task_server_terminate(
+ task, nt_errstr(NT_STATUS_CANT_ACCESS_DOMAIN_INFO));
return;
}
- service->primary_sid = talloc_reference(service, service->domains->sid);
-
/* setup the unprivileged samba3 socket */
listen_socket = talloc(service, struct wbsrv_listen_socket);
if (!listen_socket) goto nomem;
diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h
index 0407d89371..09afffb0c9 100644
--- a/source4/winbind/wb_server.h
+++ b/source4/winbind/wb_server.h
@@ -45,16 +45,20 @@ struct wbsrv_samconn {
NTSTATUS (*seqnum_recv)(struct composite_context *, uint64_t *);
};
-struct wbsrv_domain {
- struct wbsrv_domain *next, *prev;
-
- BOOL initialized;
-
+struct wb_dom_info {
const char *name;
+ const char *dns_name;
const struct dom_sid *sid;
- const char *dcname;
- const char *dc_dnsname;
+
+ const char *dc_name;
+ const char *dc_dns_name;
const char *dc_address;
+};
+
+struct wbsrv_domain {
+ struct wbsrv_domain *next, *prev;
+
+ struct wb_dom_info *info;
struct dcerpc_pipe *lsa_pipe;
struct policy_handle *lsa_policy;
@@ -66,12 +70,8 @@ struct wbsrv_domain {
struct ldap_connection *ldap_conn;
- struct dcerpc_pipe *netlogon_auth2_pipe;
struct dcerpc_pipe *netlogon_pipe;
struct cli_credentials *schannel_creds;
-
- BOOL busy;
- struct domain_request_state *request_queue;
};
/*
diff --git a/source4/winbind/wb_sid2domain.c b/source4/winbind/wb_sid2domain.c
index 8940c8e9b7..70f8f4c626 100644
--- a/source4/winbind/wb_sid2domain.c
+++ b/source4/winbind/wb_sid2domain.c
@@ -31,37 +31,16 @@
#include "winbind/wb_async_helpers.h"
#include "include/dlinklist.h"
-static const char *sam_name(void)
-{
- if (lp_server_role() == ROLE_STANDALONE) {
- return lp_netbios_name();
- }
- return lp_workgroup();
-}
-
-static struct wbsrv_domain *find_primary_domain(struct wbsrv_service *service)
-{
- const char *my_domain_name = sam_name();
- struct wbsrv_domain *domain;
-
- for (domain = service->domains; domain!=NULL; domain = domain->next) {
- if (strcasecmp(domain->name, my_domain_name) == 0) {
- break;
- }
- }
- return domain;
-}
-
static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
const struct dom_sid *sid)
{
struct wbsrv_domain *domain;
for (domain = service->domains; domain!=NULL; domain = domain->next) {
- if (dom_sid_equal(domain->sid, sid)) {
+ if (dom_sid_equal(domain->info->sid, sid)) {
break;
}
- if (dom_sid_in_domain(domain->sid, sid)) {
+ if (dom_sid_in_domain(domain->info->sid, sid)) {
break;
}
}
@@ -71,22 +50,14 @@ static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
struct sid2domain_state {
struct composite_context *ctx;
struct wbsrv_service *service;
- const struct dom_sid *sid;
-
- const char *domain_name;
- const char *dc_name;
- struct dom_sid *domain_sid;
+ struct dom_sid *sid;
- struct wbsrv_domain *my_domain;
- struct wbsrv_domain *result;
-
- struct netr_DsRGetDCName dsr_getdcname;
- struct netr_GetAnyDCName getdcname;
+ struct wbsrv_domain *domain;
};
+static void sid2domain_recv_dom_info(struct composite_context *ctx);
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_trusted_dom_info(struct composite_context *ctx);
static void sid2domain_recv_init(struct composite_context *ctx);
struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
@@ -111,24 +82,20 @@ struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
state->sid = dom_sid_dup(state, sid);
if (state->sid == NULL) goto failed;
- state->result = find_domain_from_sid(service, sid);
- if (state->result != NULL) {
+ state->domain = find_domain_from_sid(service, sid);
+ if (state->domain != NULL) {
result->status = NT_STATUS_OK;
- if (!state->result->initialized) {
- ctx = wb_init_domain_send(service, state->result);
- if (ctx == NULL) goto failed;
- ctx->async.fn = sid2domain_recv_init;
- ctx->async.private_data = state;
- return result;
- }
composite_trigger_done(result);
return result;
}
- state->my_domain = find_primary_domain(service);
- if (state->my_domain == NULL) {
- result->status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- composite_trigger_error(result);
+ if (dom_sid_equal(service->primary_sid, sid) ||
+ dom_sid_in_domain(service->primary_sid, sid)) {
+ ctx = wb_get_dom_info_send(state, service, lp_workgroup(),
+ service->primary_sid);
+ if (ctx == NULL) goto failed;
+ ctx->async.fn = sid2domain_recv_dom_info;
+ ctx->async.private_data = state;
return result;
}
@@ -141,110 +108,62 @@ struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
failed:
talloc_free(result);
return NULL;
+
}
-static void sid2domain_recv_name(struct composite_context *ctx)
+static void sid2domain_recv_dom_info(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;
+ struct wb_dom_info *info;
- state->ctx->status = wb_cmd_lookupsid_recv(ctx, state, &name);
+ state->ctx->status = wb_get_dom_info_recv(ctx, state, &info);
if (!composite_is_ok(state->ctx)) return;
- if (name->type == SID_NAME_UNKNOWN) {
- composite_error(state->ctx, NT_STATUS_NO_SUCH_DOMAIN);
- return;
- }
+ ctx = wb_init_domain_send(state, state->service, info);
- 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;
- }
-
- 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);
+ composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
}
-static void sid2domain_recv_dsr_dcname(struct rpc_request *req)
+static void sid2domain_recv_name(struct composite_context *ctx)
{
struct sid2domain_state *state =
- talloc_get_type(req->async.private,
+ talloc_get_type(ctx->async.private_data,
struct sid2domain_state);
- struct composite_context *ctx;
+ struct wb_sid_object *name;
- 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 = wb_cmd_lookupsid_recv(ctx, state, &name);
+ if (!composite_is_ok(state->ctx)) return;
- 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;
+ if (name->type == SID_NAME_UNKNOWN) {
+ composite_error(state->ctx, NT_STATUS_NO_SUCH_DOMAIN);
+ return;
}
- 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));
+ if (name->type != SID_NAME_DOMAIN) {
+ state->sid->num_auths -= 1;
+ }
- fallback:
+ ctx = wb_trusted_dom_info_send(state, state->service, name->domain,
+ state->sid);
- ctx = wb_cmd_getdcname_send(state, state->service, state->domain_name);
- composite_continue(state->ctx, ctx, sid2domain_recv_dcname, state);
+ composite_continue(state->ctx, ctx, sid2domain_recv_trusted_dom_info,
+ state);
}
-static void sid2domain_recv_dcname(struct composite_context *ctx)
+static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
{
struct sid2domain_state *state =
talloc_get_type(ctx->async.private_data,
struct sid2domain_state);
+ struct wb_dom_info *info;
- state->ctx->status = wb_cmd_getdcname_recv(ctx, state,
- &state->dc_name);
+ state->ctx->status = wb_trusted_dom_info_recv(ctx, state, &info);
if (!composite_is_ok(state->ctx)) return;
- state->result = talloc_zero(state, struct wbsrv_domain);
- if (composite_nomem(state->result, state->ctx)) return;
+ ctx = wb_init_domain_send(state, state->service, info);
- state->result->name = talloc_steal(state->result, state->domain_name);
- state->result->sid = talloc_steal(state->result, state->domain_sid);
- state->result->dcname = talloc_steal(state->result, state->dc_name);
-
- state->result->schannel_creds = cli_credentials_init(state->result);
- if (composite_nomem(state->result->schannel_creds, state->ctx)) return;
- cli_credentials_set_conf(state->result->schannel_creds);
- cli_credentials_set_machine_account(state->result->schannel_creds);
-
- talloc_steal(state->service, state->result);
- DLIST_ADD(state->service->domains, state->result);
-
- ctx = wb_init_domain_send(state->service, state->result);
composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
}
@@ -253,13 +172,25 @@ static void sid2domain_recv_init(struct composite_context *ctx)
struct sid2domain_state *state =
talloc_get_type(ctx->async.private_data,
struct sid2domain_state);
+ struct wbsrv_domain *existing;
- state->ctx->status = wb_init_domain_recv(ctx);
+ state->ctx->status = wb_init_domain_recv(ctx, state,
+ &state->domain);
if (!composite_is_ok(state->ctx)) {
DEBUG(10, ("Could not init domain\n"));
return;
}
+ existing = find_domain_from_sid(state->service, state->sid);
+ if (existing != NULL) {
+ DEBUG(5, ("Initialized domain twice, dropping second one\n"));
+ talloc_free(state->domain);
+ state->domain = existing;
+ }
+
+ talloc_steal(state->service, state->domain);
+ DLIST_ADD(state->service->domains, state->domain);
+
composite_done(state->ctx);
}
@@ -271,7 +202,7 @@ NTSTATUS wb_sid2domain_recv(struct composite_context *ctx,
struct sid2domain_state *state =
talloc_get_type(ctx->private_data,
struct sid2domain_state);
- *result = state->result;
+ *result = state->domain;
}
talloc_free(ctx);
return status;