From 17355fbbd4c4a904bb75c1d8ba98948edaf0fe68 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Oct 2005 22:01:15 +0000 Subject: r11094: Connect to SAM, implement getdcname (This used to be commit a14398715eceecf204caf815a8769ba8214d0576) --- source4/libnet/libnet_join.c | 2 +- source4/winbind/config.mk | 3 + source4/winbind/wb_async_helpers.c | 82 +------------- source4/winbind/wb_cmd_getdcname.c | 155 ++++++++++++++++++++++++++ source4/winbind/wb_cmd_lookupname.c | 107 ++++++++++++++++++ source4/winbind/wb_connect_sam.c | 210 +++++++++++++++++++++++++++++++++++ source4/winbind/wb_init_domain.c | 45 +++++++- source4/winbind/wb_samba3_cmd.c | 51 +++++++++ source4/winbind/wb_samba3_protocol.c | 3 + source4/winbind/wb_server.h | 5 + 10 files changed, 579 insertions(+), 84 deletions(-) create mode 100644 source4/winbind/wb_cmd_getdcname.c create mode 100644 source4/winbind/wb_cmd_lookupname.c create mode 100644 source4/winbind/wb_connect_sam.c 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; -- cgit