summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/libnet_join.c2
-rw-r--r--source4/winbind/config.mk3
-rw-r--r--source4/winbind/wb_async_helpers.c82
-rw-r--r--source4/winbind/wb_cmd_getdcname.c155
-rw-r--r--source4/winbind/wb_cmd_lookupname.c107
-rw-r--r--source4/winbind/wb_connect_sam.c210
-rw-r--r--source4/winbind/wb_init_domain.c45
-rw-r--r--source4/winbind/wb_samba3_cmd.c51
-rw-r--r--source4/winbind/wb_samba3_protocol.c3
-rw-r--r--source4/winbind/wb_server.h5
10 files changed, 579 insertions, 84 deletions
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index e3ed325d92..bbf493a817 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -990,7 +990,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- return cu_status;
+ return status;
}
static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
diff --git a/source4/winbind/config.mk b/source4/winbind/config.mk
index a33a886bcc..530aa83b80 100644
--- a/source4/winbind/config.mk
+++ b/source4/winbind/config.mk
@@ -11,6 +11,9 @@ INIT_OBJ_FILES = \
winbind/wb_samba3_cmd.o \
winbind/wb_init_domain.o \
winbind/wb_connect_lsa.o \
+ winbind/wb_connect_sam.o \
+ winbind/wb_cmd_lookupname.o \
+ winbind/wb_cmd_getdcname.o \
winbind/wb_pam_auth.o \
winbind/wb_async_helpers.o
REQUIRED_SUBSYSTEMS = RPC_NDR_LSA
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 146a957727..eeed108719 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -501,87 +501,6 @@ NTSTATUS wb_lsa_lookupnames(struct dcerpc_pipe *lsa_pipe,
return wb_lsa_lookupnames_recv(c, mem_ctx, sids);
}
-struct cmd_lookupname_state {
- struct composite_context *ctx;
- struct wbsrv_call *call;
- struct wbsrv_domain *domain;
- const char *name;
- struct wb_sid_object *result;
-};
-
-static struct composite_context *lookupname_send_req(void *p);
-static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p);
-
-struct composite_context *wb_cmd_lookupname_send(struct wbsrv_call *call,
- const char *name)
-{
- struct cmd_lookupname_state *state;
- struct wbsrv_service *service = call->wbconn->listen_socket->service;
-
- state = talloc(NULL, struct cmd_lookupname_state);
- state->domain = service->domains;
- state->call = call;
- state->name = talloc_strdup(state, name);
- state->ctx = wb_queue_domain_send(state, state->domain,
- call->event_ctx,
- call->wbconn->conn->msg_ctx,
- lookupname_send_req,
- lookupname_recv_req,
- state);
- if (state->ctx == NULL) {
- talloc_free(state);
- return NULL;
- }
- state->ctx->private_data = state;
- return state->ctx;
-}
-
-static struct composite_context *lookupname_send_req(void *p)
-{
- struct cmd_lookupname_state *state =
- talloc_get_type(p, struct cmd_lookupname_state);
-
- return wb_lsa_lookupnames_send(state->domain->lsa_pipe,
- state->domain->lsa_policy,
- 1, &state->name);
-}
-
-static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p)
-{
- struct cmd_lookupname_state *state =
- talloc_get_type(p, struct cmd_lookupname_state);
- struct wb_sid_object **sids;
- NTSTATUS status;
-
- status = wb_lsa_lookupnames_recv(ctx, state, &sids);
- if (NT_STATUS_IS_OK(status)) {
- state->result = sids[0];
- }
- return status;
-}
-
-NTSTATUS wb_cmd_lookupname_recv(struct composite_context *c,
- TALLOC_CTX *mem_ctx,
- struct wb_sid_object **sid)
-{
- struct cmd_lookupname_state *state =
- talloc_get_type(c->private_data, struct cmd_lookupname_state);
- NTSTATUS status = composite_wait(c);
- if (NT_STATUS_IS_OK(status)) {
- *sid = talloc_steal(mem_ctx, state->result);
- }
- talloc_free(state);
- return status;
-}
-
-NTSTATUS wb_cmd_lookupname(struct wbsrv_call *call, const char *name,
- TALLOC_CTX *mem_ctx, struct wb_sid_object **sid)
-{
- struct composite_context *c =
- wb_cmd_lookupname_send(call, name);
- return wb_cmd_lookupname_recv(c, mem_ctx, sid);
-}
-
struct cmd_checkmachacc_state {
struct composite_context *ctx;
struct wbsrv_call *call;
@@ -690,3 +609,4 @@ NTSTATUS composite_netr_LogonSamLogon_recv(struct composite_context *ctx)
talloc_free(ctx);
return status;
}
+
diff --git a/source4/winbind/wb_cmd_getdcname.c b/source4/winbind/wb_cmd_getdcname.c
new file mode 100644
index 0000000000..3ddcbc8962
--- /dev/null
+++ b/source4/winbind/wb_cmd_getdcname.c
@@ -0,0 +1,155 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Command backend for wbinfo --getdcname
+
+ 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 "winbind/wb_server.h"
+#include "smbd/service_stream.h"
+
+#include "librpc/gen_ndr/ndr_netlogon.h"
+
+static void composite_netr_GetAnyDCName_recv_rpc(struct rpc_request *req);
+
+static struct composite_context *composite_netr_GetAnyDCName_send(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ struct netr_GetAnyDCName *r)
+{
+ struct composite_context *result;
+ struct rpc_request *req;
+
+ 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 = p->conn->event_ctx;
+
+ req = dcerpc_netr_GetAnyDCName_send(p, mem_ctx, r);
+ if (req == NULL) goto failed;
+ req->async.callback = composite_netr_GetAnyDCName_recv_rpc;
+ req->async.private = result;
+ return result;
+
+ failed:
+ talloc_free(result);
+ return NULL;
+}
+
+static void composite_netr_GetAnyDCName_recv_rpc(struct rpc_request *req)
+{
+ struct composite_context *ctx =
+ talloc_get_type(req->async.private, struct composite_context);
+
+ ctx->status = dcerpc_ndr_request_recv(req);
+ if (!composite_is_ok(ctx)) return;
+ composite_done(ctx);
+}
+
+NTSTATUS composite_netr_GetAnyDCName_recv(struct composite_context *ctx)
+{
+ NTSTATUS status = composite_wait(ctx);
+ talloc_free(ctx);
+ return status;
+}
+
+struct cmd_getdcname_state {
+ struct composite_context *ctx;
+ struct wbsrv_domain *domain;
+ const char *domain_name;
+
+ struct netr_GetAnyDCName g;
+};
+
+static struct composite_context *getdcname_send_req(void *p);
+static NTSTATUS getdcname_recv_req(struct composite_context *ctx, void *p);
+
+struct composite_context *wb_cmd_getdcname_send(struct wbsrv_call *call,
+ const char *domain)
+{
+ struct cmd_getdcname_state *state;
+ struct wbsrv_service *service = call->wbconn->listen_socket->service;
+
+ state = talloc(NULL, struct cmd_getdcname_state);
+ state->domain = service->domains;
+ state->domain_name = talloc_strdup(state, domain);
+ state->ctx = wb_queue_domain_send(state, state->domain,
+ call->event_ctx,
+ call->wbconn->conn->msg_ctx,
+ getdcname_send_req,
+ getdcname_recv_req,
+ state);
+ if (state->ctx == NULL) {
+ talloc_free(state);
+ return NULL;
+ }
+ state->ctx->private_data = state;
+ return state->ctx;
+}
+
+static struct composite_context *getdcname_send_req(void *p)
+{
+ struct cmd_getdcname_state *state =
+ talloc_get_type(p, struct cmd_getdcname_state);
+
+ state->g.in.logon_server = talloc_asprintf(
+ state, "\\\\%s",
+ dcerpc_server_name(state->domain->netlogon_pipe));
+ state->g.in.domainname = state->domain_name;
+
+ return composite_netr_GetAnyDCName_send(state->domain->netlogon_pipe,
+ state, &state->g);
+}
+
+static NTSTATUS getdcname_recv_req(struct composite_context *ctx, void *p)
+{
+ struct cmd_getdcname_state *state =
+ talloc_get_type(p, struct cmd_getdcname_state);
+ NTSTATUS status;
+
+ status = composite_netr_GetAnyDCName_recv(ctx);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ if (!W_ERROR_IS_OK(state->g.out.result)) {
+ return werror_to_ntstatus(state->g.out.result);
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS wb_cmd_getdcname_recv(struct composite_context *c,
+ TALLOC_CTX *mem_ctx,
+ const char **dcname)
+{
+ struct cmd_getdcname_state *state =
+ talloc_get_type(c->private_data, struct cmd_getdcname_state);
+ NTSTATUS status = composite_wait(c);
+ if (NT_STATUS_IS_OK(status)) {
+ const char *p = state->g.out.dcname;
+ if (*p == '\\') p += 1;
+ if (*p == '\\') p += 1;
+ *dcname = talloc_strdup(mem_ctx, p);
+ if (*dcname == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ }
+ }
+ talloc_free(state);
+ return status;
+}
diff --git a/source4/winbind/wb_cmd_lookupname.c b/source4/winbind/wb_cmd_lookupname.c
new file mode 100644
index 0000000000..9889b70d84
--- /dev/null
+++ b/source4/winbind/wb_cmd_lookupname.c
@@ -0,0 +1,107 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Command backend for wbinfo -n
+
+ 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 "winbind/wb_server.h"
+#include "smbd/service_stream.h"
+
+struct cmd_lookupname_state {
+ struct composite_context *ctx;
+ struct wbsrv_call *call;
+ struct wbsrv_domain *domain;
+ const char *name;
+ struct wb_sid_object *result;
+};
+
+static struct composite_context *lookupname_send_req(void *p);
+static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p);
+
+struct composite_context *wb_cmd_lookupname_send(struct wbsrv_call *call,
+ const char *name)
+{
+ struct cmd_lookupname_state *state;
+ struct wbsrv_service *service = call->wbconn->listen_socket->service;
+
+ state = talloc(NULL, struct cmd_lookupname_state);
+ state->domain = service->domains;
+ state->call = call;
+ state->name = talloc_strdup(state, name);
+ state->ctx = wb_queue_domain_send(state, state->domain,
+ call->event_ctx,
+ call->wbconn->conn->msg_ctx,
+ lookupname_send_req,
+ lookupname_recv_req,
+ state);
+ if (state->ctx == NULL) {
+ talloc_free(state);
+ return NULL;
+ }
+ state->ctx->private_data = state;
+ return state->ctx;
+}
+
+static struct composite_context *lookupname_send_req(void *p)
+{
+ struct cmd_lookupname_state *state =
+ talloc_get_type(p, struct cmd_lookupname_state);
+
+ return wb_lsa_lookupnames_send(state->domain->lsa_pipe,
+ state->domain->lsa_policy,
+ 1, &state->name);
+}
+
+static NTSTATUS lookupname_recv_req(struct composite_context *ctx, void *p)
+{
+ struct cmd_lookupname_state *state =
+ talloc_get_type(p, struct cmd_lookupname_state);
+ struct wb_sid_object **sids;
+ NTSTATUS status;
+
+ status = wb_lsa_lookupnames_recv(ctx, state, &sids);
+ if (NT_STATUS_IS_OK(status)) {
+ state->result = sids[0];
+ }
+ return status;
+}
+
+NTSTATUS wb_cmd_lookupname_recv(struct composite_context *c,
+ TALLOC_CTX *mem_ctx,
+ struct wb_sid_object **sid)
+{
+ struct cmd_lookupname_state *state =
+ talloc_get_type(c->private_data, struct cmd_lookupname_state);
+ NTSTATUS status = composite_wait(c);
+ if (NT_STATUS_IS_OK(status)) {
+ *sid = talloc_steal(mem_ctx, state->result);
+ }
+ talloc_free(state);
+ return status;
+}
+
+NTSTATUS wb_cmd_lookupname(struct wbsrv_call *call, const char *name,
+ TALLOC_CTX *mem_ctx, struct wb_sid_object **sid)
+{
+ struct composite_context *c =
+ wb_cmd_lookupname_send(call, name);
+ return wb_cmd_lookupname_recv(c, mem_ctx, sid);
+}
diff --git a/source4/winbind/wb_connect_sam.c b/source4/winbind/wb_connect_sam.c
new file mode 100644
index 0000000000..8693356c7a
--- /dev/null
+++ b/source4/winbind/wb_connect_sam.c
@@ -0,0 +1,210 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Connect to the SAMR pipe, given an smbcli_tree and possibly some
+ credentials. Try ntlmssp, schannel and anon in that order.
+
+ 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/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+
+
+/* Helper to initialize SAMR with a specific auth methods. Verify by opening
+ * the SAM handle */
+
+struct connect_samr_state {
+ struct composite_context *ctx;
+ uint8_t auth_type;
+ struct cli_credentials *creds;
+ struct dom_sid *sid;
+
+ struct dcerpc_pipe *samr_pipe;
+ struct policy_handle *connect_handle;
+ struct policy_handle *domain_handle;
+
+ struct samr_Connect2 c;
+ struct samr_OpenDomain o;
+};
+
+static void connect_samr_recv_pipe(struct composite_context *ctx);
+static void connect_samr_recv_conn(struct rpc_request *req);
+static void connect_samr_recv_open(struct rpc_request *req);
+
+struct composite_context *wb_connect_sam_send(struct smbcli_tree *tree,
+ uint8_t auth_type,
+ struct cli_credentials *creds,
+ const struct dom_sid *domain_sid)
+{
+ struct composite_context *result, *ctx;
+ struct connect_samr_state *state;
+
+ result = talloc(NULL, struct composite_context);
+ if (result == NULL) goto failed;
+ result->state = COMPOSITE_STATE_IN_PROGRESS;
+ result->async.fn = NULL;
+ result->event_ctx = tree->session->transport->socket->event.ctx;
+
+ state = talloc(result, struct connect_samr_state);
+ if (state == NULL) goto failed;
+ state->ctx = result;
+ result->private_data = state;
+
+ state->auth_type = auth_type;
+ state->creds = creds;
+ state->sid = dom_sid_dup(state, domain_sid);
+ if (state->sid == NULL) goto failed;
+
+ state->samr_pipe = dcerpc_pipe_init(state, result->event_ctx);
+ if (state->samr_pipe == NULL) goto failed;
+
+ ctx = dcerpc_pipe_open_smb_send(state->samr_pipe->conn, tree,
+ "\\samr");
+ ctx->async.fn = connect_samr_recv_pipe;
+ ctx->async.private_data = state;
+ return result;
+
+ failed:
+ talloc_free(result);
+ return NULL;
+}
+
+static void connect_samr_recv_pipe(struct composite_context *ctx)
+{
+ struct connect_samr_state *state =
+ talloc_get_type(ctx->async.private_data,
+ struct connect_samr_state);
+ struct rpc_request *req;
+
+ state->ctx->status = dcerpc_pipe_open_smb_recv(ctx);
+ if (!composite_is_ok(state->ctx)) return;
+
+ switch (state->auth_type) {
+ case DCERPC_AUTH_TYPE_NONE:
+ state->ctx->status =
+ dcerpc_bind_auth_none(state->samr_pipe,
+ DCERPC_SAMR_UUID,
+ DCERPC_SAMR_VERSION);
+ break;
+ case DCERPC_AUTH_TYPE_NTLMSSP:
+ case DCERPC_AUTH_TYPE_SCHANNEL:
+ if (state->creds == NULL) {
+ composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
+ state->samr_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
+ state->ctx->status =
+ dcerpc_bind_auth_password(state->samr_pipe,
+ DCERPC_SAMR_UUID,
+ DCERPC_SAMR_VERSION,
+ state->creds,
+ state->auth_type,
+ NULL);
+ break;
+ default:
+ state->ctx->status = NT_STATUS_INTERNAL_ERROR;
+
+ }
+
+ state->connect_handle = talloc(state, struct policy_handle);
+ if (composite_nomem(state->connect_handle, state->ctx)) return;
+
+ state->c.in.system_name =
+ talloc_asprintf(state, "\\\\%s",
+ dcerpc_server_name(state->samr_pipe));
+ state->c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ state->c.out.connect_handle = state->connect_handle;
+
+ req = dcerpc_samr_Connect2_send(state->samr_pipe, state, &state->c);
+ composite_continue_rpc(state->ctx, req, connect_samr_recv_conn, state);
+}
+
+static void connect_samr_recv_conn(struct rpc_request *req)
+{
+ struct connect_samr_state *state =
+ talloc_get_type(req->async.private,
+ struct connect_samr_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;
+
+ state->domain_handle = talloc(state, struct policy_handle);
+ if (composite_nomem(state->domain_handle, state->ctx)) return;
+
+ state->o.in.connect_handle = state->connect_handle;
+ state->o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ state->o.in.sid = state->sid;
+ state->o.out.domain_handle = state->domain_handle;
+
+ req = dcerpc_samr_OpenDomain_send(state->samr_pipe, state, &state->o);
+ composite_continue_rpc(state->ctx, req,
+ connect_samr_recv_open, state);
+}
+
+static void connect_samr_recv_open(struct rpc_request *req)
+{
+ struct connect_samr_state *state =
+ talloc_get_type(req->async.private,
+ struct connect_samr_state);
+
+ 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;
+
+ composite_done(state->ctx);
+}
+
+NTSTATUS wb_connect_sam_recv(struct composite_context *c,
+ TALLOC_CTX *mem_ctx,
+ struct dcerpc_pipe **samr_pipe,
+ struct policy_handle **connect_handle,
+ struct policy_handle **domain_handle)
+{
+ NTSTATUS status = composite_wait(c);
+ if (NT_STATUS_IS_OK(status)) {
+ struct connect_samr_state *state =
+ talloc_get_type(c->private_data,
+ struct connect_samr_state);
+ *samr_pipe = talloc_steal(mem_ctx, state->samr_pipe);
+ *connect_handle = talloc_steal(mem_ctx, state->connect_handle);
+ *domain_handle = talloc_steal(mem_ctx, state->domain_handle);
+ }
+ talloc_free(c);
+ return status;
+}
+
+NTSTATUS wb_connect_sam(struct smbcli_tree *tree,
+ uint8_t auth_type,
+ struct cli_credentials *creds,
+ const struct dom_sid *domain_sid,
+ TALLOC_CTX *mem_ctx,
+ struct dcerpc_pipe **samr_pipe,
+ struct policy_handle **connect_handle,
+ struct policy_handle **domain_handle)
+{
+ struct composite_context *c =
+ wb_connect_sam_send(tree, auth_type, creds, domain_sid);
+ return wb_connect_sam_recv(c, mem_ctx, samr_pipe, connect_handle,
+ domain_handle);
+}
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c
index fbe44244f4..e89d70d5c6 100644
--- a/source4/winbind/wb_init_domain.c
+++ b/source4/winbind/wb_init_domain.c
@@ -76,6 +76,10 @@ struct init_domain_state {
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 lsa_QueryInfoPolicy queryinfo;
};
@@ -85,6 +89,7 @@ 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(struct composite_context *ctx);
static void init_domain_recv_queryinfo(struct rpc_request *req);
+static void init_domain_recv_samr(struct composite_context *ctx);
struct composite_context *wb_init_domain_send(struct wbsrv_domain *domain,
struct event_context *event_ctx,
@@ -242,6 +247,7 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx)
state->domain->schannel_creds,
DCERPC_AUTH_TYPE_SCHANNEL,
NULL);
+ if (!composite_is_ok(state->ctx)) return;
ctx = wb_connect_lsa_send(state->conn.out.tree,
state->domain->schannel_creds);
@@ -255,9 +261,9 @@ static void init_domain_recv_lsa(struct composite_context *ctx)
struct init_domain_state);
struct rpc_request *req;
- uint8_t auth_type;
- state->ctx->status = wb_connect_lsa_recv(ctx, state, &auth_type,
+ state->ctx->status = wb_connect_lsa_recv(ctx, state,
+ &state->domain->lsa_auth_type,
&state->lsa_pipe,
&state->lsa_policy);
if (!composite_is_ok(state->ctx)) return;
@@ -283,6 +289,7 @@ static void init_domain_recv_queryinfo(struct rpc_request *req)
struct init_domain_state *state =
talloc_get_type(req->async.private, struct init_domain_state);
struct lsa_DomainInfo *dominfo;
+ struct composite_context *ctx;
state->ctx->status = dcerpc_ndr_request_recv(req);
if (!composite_is_ok(state->ctx)) return;
@@ -309,6 +316,28 @@ static void init_domain_recv_queryinfo(struct rpc_request *req)
return;
}
+ state->samr_pipe = dcerpc_pipe_init(state, state->ctx->event_ctx);
+ if (composite_nomem(state->samr_pipe, state->ctx)) return;
+
+ ctx = wb_connect_sam_send(state->conn.out.tree,
+ state->domain->lsa_auth_type,
+ state->domain->schannel_creds,
+ state->domain->sid);
+ composite_continue(state->ctx, ctx,
+ init_domain_recv_samr, state);
+}
+
+static void init_domain_recv_samr(struct composite_context *ctx)
+{
+ struct init_domain_state *state =
+ 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);
+ if (!composite_is_ok(state->ctx)) return;
+
composite_done(state->ctx);
}
@@ -337,6 +366,18 @@ NTSTATUS wb_init_domain_recv(struct composite_context *c)
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;
}
talloc_free(c);
diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c
index 339b29c5b0..fb43eacb5c 100644
--- a/source4/winbind/wb_samba3_cmd.c
+++ b/source4/winbind/wb_samba3_cmd.c
@@ -123,6 +123,57 @@ static void checkmachacc_recv_creds(struct composite_context *ctx)
}
}
+static void getdcname_recv_dc(struct composite_context *ctx);
+
+NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
+{
+ struct composite_context *ctx;
+
+ DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
+
+ ctx = wb_cmd_getdcname_send(s3call->call,
+ s3call->request.domain_name);
+ NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+ ctx->async.fn = getdcname_recv_dc;
+ ctx->async.private_data = s3call;
+ s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ return NT_STATUS_OK;
+}
+
+static void getdcname_recv_dc(struct composite_context *ctx)
+{
+ struct wbsrv_samba3_call *s3call =
+ talloc_get_type(ctx->async.private_data,
+ struct wbsrv_samba3_call);
+ const char *dcname;
+ NTSTATUS status;
+
+ status = wb_cmd_getdcname_recv(ctx, s3call, &dcname);
+ if (!NT_STATUS_IS_OK(status)) goto done;
+
+ s3call->response.result = WINBINDD_OK;
+ WBSRV_SAMBA3_SET_STRING(s3call->response.data.dc_name, dcname);
+
+ done:
+ if (!NT_STATUS_IS_OK(status)) {
+ struct winbindd_response *resp = &s3call->response;
+ resp->result = WINBINDD_ERROR;
+ WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
+ nt_errstr(status));
+ WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
+ nt_errstr(status));
+ resp->data.auth.pam_error = nt_status_to_pam(status);
+ }
+
+ status = wbsrv_send_reply(s3call->call);
+ if (!NT_STATUS_IS_OK(status)) {
+ wbsrv_terminate_connection(s3call->call->wbconn,
+ "wbsrv_queue_reply() failed");
+ return;
+ }
+}
+
static void lookupname_recv_sid(struct composite_context *ctx);
NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
diff --git a/source4/winbind/wb_samba3_protocol.c b/source4/winbind/wb_samba3_protocol.c
index 6e206e32da..135d9a3d1f 100644
--- a/source4/winbind/wb_samba3_protocol.c
+++ b/source4/winbind/wb_samba3_protocol.c
@@ -99,6 +99,9 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call)
case WINBINDD_PAM_AUTH_CRAP:
return wbsrv_samba3_pam_auth_crap(s3call);
+
+ case WINBINDD_GETDCNAME:
+ return wbsrv_samba3_getdcname(s3call);
}
s3call->response.result = WINBINDD_ERROR;
diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h
index 52e7256570..e511325c72 100644
--- a/source4/winbind/wb_server.h
+++ b/source4/winbind/wb_server.h
@@ -54,6 +54,11 @@ struct wbsrv_domain {
struct dcerpc_pipe *lsa_pipe;
struct policy_handle *lsa_policy;
+ uint8_t lsa_auth_type;
+
+ struct dcerpc_pipe *samr_pipe;
+ struct policy_handle *samr_handle;
+ struct policy_handle *domain_handle;
struct dcerpc_pipe *netlogon_auth2_pipe;
struct dcerpc_pipe *netlogon_pipe;