r11094: Connect to SAM, implement getdcname
authorVolker Lendecke <vlendec@samba.org>
Sat, 15 Oct 2005 22:01:15 +0000 (22:01 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:44:48 +0000 (13:44 -0500)
source/libnet/libnet_join.c
source/winbind/config.mk
source/winbind/wb_async_helpers.c
source/winbind/wb_cmd_getdcname.c [new file with mode: 0644]
source/winbind/wb_cmd_lookupname.c [new file with mode: 0644]
source/winbind/wb_connect_sam.c [new file with mode: 0644]
source/winbind/wb_init_domain.c
source/winbind/wb_samba3_cmd.c
source/winbind/wb_samba3_protocol.c
source/winbind/wb_server.h

index e3ed325d9224c41ca7fa3fc830d37f2027bbad05..bbf493a817d166e815f96dbe5be59c112373b1e1 100644 (file)
@@ -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, 
index a33a886bcce7236021c2f9c2bd227ab63adea43d..530aa83b80e1a08c7b5256adfcb82424675ee898 100644 (file)
@@ -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
index 146a957727973b2311b1563a9e143e3c0f0de102..eeed108719663e084812b12d94cc402ddac78cf1 100644 (file)
@@ -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/source/winbind/wb_cmd_getdcname.c b/source/winbind/wb_cmd_getdcname.c
new file mode 100644 (file)
index 0000000..3ddcbc8
--- /dev/null
@@ -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/source/winbind/wb_cmd_lookupname.c b/source/winbind/wb_cmd_lookupname.c
new file mode 100644 (file)
index 0000000..9889b70
--- /dev/null
@@ -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/source/winbind/wb_connect_sam.c b/source/winbind/wb_connect_sam.c
new file mode 100644 (file)
index 0000000..8693356
--- /dev/null
@@ -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);
+}
index fbe44244f482ee93cfa20c2f11fdba5f088ced63..e89d70d5c6b9b17689440520c42796b230b9b0a1 100644 (file)
@@ -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);
index 339b29c5b0dfc04ea60e0d6b1983056afc5c4398..fb43eacb5cfb0e2d11e2350353163d4db73cb212 100644 (file)
@@ -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)
index 6e206e32daf2c80258269485428326b9058588ea..135d9a3d1fe30a3cdb70664775e93c175df181b0 100644 (file)
@@ -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;
index 52e72565701af70a4e46511fb84e10b3e00ac398..e511325c725ba2e418413371b0ca421eca44ea23 100644 (file)
@@ -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;