⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wb_init_domain.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   A composite API for initializing a domain   Copyright (C) Volker Lendecke 2005   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007   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 3 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, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "libcli/composite/composite.h"#include "libcli/smb_composite/smb_composite.h"#include "winbind/wb_server.h"#include "winbind/wb_async_helpers.h"#include "winbind/wb_helper.h"#include "smbd/service_task.h"#include "librpc/gen_ndr/ndr_netlogon.h"#include "librpc/gen_ndr/ndr_lsa_c.h"#include "librpc/gen_ndr/ndr_samr_c.h"#include "libcli/libcli.h"#include "libcli/auth/credentials.h"#include "libcli/security/security.h"#include "libcli/ldap/ldap_client.h"#include "auth/credentials/credentials.h"#include "param/param.h"/* * Initialize a domain: * * - With schannel credentials, try to open the SMB connection and *   NETLOGON pipe with the machine creds. This works against W2k3SP1 *   with an NTLMSSP session setup. Fall back to anonymous (for the CIFS level). * * - If we have schannel creds, do the auth2 and open the schannel'ed netlogon *   pipe. * * - Open LSA. If we have machine creds, try to open with SPNEGO or NTLMSSP. Fall back *   to schannel. * * - With queryinfopolicy, verify that we're talking to the right domain * * A bit complex, but with all the combinations I think it's the best we can * get. NT4, W2k3 and W2k all have different combinations, but in the end we * have a signed&sealed lsa connection on all of them. * * Not sure if it is overkill, but it seems to work. */struct init_domain_state {	struct composite_context *ctx;	struct wbsrv_domain *domain;	struct wbsrv_service *service;	struct lsa_ObjectAttribute objectattr;	struct lsa_OpenPolicy2 lsa_openpolicy;	struct lsa_QueryInfoPolicy queryinfo;};static void init_domain_recv_netlogonpipe(struct composite_context *ctx);static void init_domain_recv_lsa_pipe(struct composite_context *ctx);static void init_domain_recv_lsa_policy(struct rpc_request *req);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);static struct dcerpc_binding *init_domain_binding(struct init_domain_state *state, 						  const struct ndr_interface_table *table) {	struct dcerpc_binding *binding;	NTSTATUS status;	/* Make a binding string */	{		char *s = talloc_asprintf(state, "ncacn_np:%s", state->domain->dc_name);		if (s == NULL) return NULL;		status = dcerpc_parse_binding(state, s, &binding);		talloc_free(s);		if (!NT_STATUS_IS_OK(status)) {			return NULL;		}	}	/* Alter binding to contain hostname, but also address (so we don't look it up twice) */	binding->target_hostname = state->domain->dc_name;	binding->host = state->domain->dc_address;	/* This shouldn't make a network call, as the mappings for named pipes are well known */	status = dcerpc_epm_map_binding(binding, binding, table, state->service->task->event_ctx,					state->service->task->lp_ctx);	if (!NT_STATUS_IS_OK(status)) {		return NULL;	}	return binding;}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 = composite_create(mem_ctx, service->task->event_ctx);	if (result == NULL) goto failed;	state = talloc_zero(result, struct init_domain_state);	if (state == NULL) goto failed;	state->ctx = result;	result->private_data = state;	state->service = service;	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;	/* Caller should check, but to be safe: */	if (dom_info->num_dcs < 1) {		goto failed;	}		/* For now, we just pick the first.  The next step will be to	 * walk the entire list.  Also need to fix finddcs() to return	 * the entire list */	state->domain->dc_name = dom_info->dcs[0].name;	state->domain->dc_address = dom_info->dcs[0].address;	state->domain->libnet_ctx = libnet_context_init(service->task->event_ctx, 							service->task->lp_ctx);	/* Create a credentials structure */	state->domain->libnet_ctx->cred = cli_credentials_init(state->domain);	if (state->domain->libnet_ctx->cred == NULL) goto failed;	cli_credentials_set_conf(state->domain->libnet_ctx->cred, service->task->lp_ctx);	/* Connect the machine account to the credentials */	state->ctx->status =		cli_credentials_set_machine_account(state->domain->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx);	if (!NT_STATUS_IS_OK(state->ctx->status)) goto failed;	state->domain->netlogon_binding = init_domain_binding(state, &ndr_table_netlogon);	state->domain->netlogon_pipe = NULL;	if ((!cli_credentials_is_anonymous(state->domain->libnet_ctx->cred)) &&	    ((lp_server_role(service->task->lp_ctx) == ROLE_DOMAIN_MEMBER) ||	     (lp_server_role(service->task->lp_ctx) == ROLE_DOMAIN_CONTROLLER)) &&	    (dom_sid_equal(state->domain->info->sid,			   state->service->primary_sid))) {		state->domain->netlogon_binding->flags |= DCERPC_SCHANNEL;		/* For debugging, it can be a real pain if all the traffic is encrypted */		if (lp_winbind_sealed_pipes(service->task->lp_ctx)) {			state->domain->netlogon_binding->flags |= (DCERPC_SIGN | DCERPC_SEAL );		} else {			state->domain->netlogon_binding->flags |= (DCERPC_SIGN);		}	}	/* No encryption on anonymous pipes */	ctx = dcerpc_pipe_connect_b_send(state, state->domain->netlogon_binding, 					 &ndr_table_netlogon,					 state->domain->libnet_ctx->cred,					 service->task->event_ctx,					 service->task->lp_ctx);		if (composite_nomem(ctx, state->ctx)) {		goto failed;	}		composite_continue(state->ctx, ctx, init_domain_recv_netlogonpipe,			   state);	return result; failed:	talloc_free(result);	return NULL;}/* Having make a netlogon connection (possibly secured with schannel), * make an LSA connection to the same DC, on the same IPC$ share */static void init_domain_recv_netlogonpipe(struct composite_context *ctx){	struct init_domain_state *state =		talloc_get_type(ctx->async.private_data,				struct init_domain_state);	state->ctx->status = dcerpc_pipe_connect_b_recv(ctx, state->domain, 						   &state->domain->netlogon_pipe);		if (!composite_is_ok(state->ctx)) {		return;	}	talloc_steal(state->domain->netlogon_pipe, state->domain->netlogon_binding);	state->domain->lsa_binding = init_domain_binding(state, &ndr_table_lsarpc);	/* For debugging, it can be a real pain if all the traffic is encrypted */	if (lp_winbind_sealed_pipes(state->service->task->lp_ctx)) {		state->domain->lsa_binding->flags |= (DCERPC_SIGN | DCERPC_SEAL );	} else {		state->domain->lsa_binding->flags |= (DCERPC_SIGN);	}	state->domain->libnet_ctx->lsa.pipe = NULL;	/* this will make the secondary connection on the same IPC$ share, 	   secured with SPNEGO or NTLMSSP */	ctx = dcerpc_secondary_auth_connection_send(state->domain->netlogon_pipe,						    state->domain->lsa_binding,						    &ndr_table_lsarpc,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -