dssync.c

来自「samba最新软件」· C语言 代码 · 共 835 行 · 第 1/2 页

C
835
字号
/*    Unix SMB/CIFS implementation.   DsGetNCChanges replication test   Copyright (C) Stefan (metze) Metzmacher 2005   Copyright (C) Brad Henry 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 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 "lib/cmdline/popt_common.h"#include "librpc/gen_ndr/ndr_drsuapi_c.h"#include "libcli/cldap/cldap.h"#include "libcli/ldap/ldap_client.h"#include "torture/torture.h"#include "torture/ldap/proto.h"#include "libcli/auth/libcli_auth.h"#include "lib/crypto/crypto.h"#include "auth/credentials/credentials.h"#include "libcli/auth/libcli_auth.h"#include "auth/gensec/gensec.h"#include "param/param.h"struct DsSyncBindInfo {	struct dcerpc_pipe *pipe;	struct drsuapi_DsBind req;	struct GUID bind_guid;	struct drsuapi_DsBindInfoCtr our_bind_info_ctr;	struct drsuapi_DsBindInfo28 our_bind_info28;	struct drsuapi_DsBindInfo28 peer_bind_info28;	struct policy_handle bind_handle;};struct DsSyncLDAPInfo {	struct ldap_connection *conn;};struct DsSyncTest {	struct dcerpc_binding *drsuapi_binding;		const char *ldap_url;	const char *site_name;		const char *domain_dn;	/* what we need to do as 'Administrator' */	struct {		struct cli_credentials *credentials;		struct DsSyncBindInfo drsuapi;		struct DsSyncLDAPInfo ldap;	} admin;	/* what we need to do as the new dc machine account */	struct {		struct cli_credentials *credentials;		struct DsSyncBindInfo drsuapi;		struct drsuapi_DsGetDCInfo2 dc_info2;		struct GUID invocation_id;		struct GUID object_guid;	} new_dc;	/* info about the old dc */	struct {		struct drsuapi_DsGetDomainControllerInfo dc_info;	} old_dc;};static struct DsSyncTest *test_create_context(struct torture_context *tctx){	NTSTATUS status;	struct DsSyncTest *ctx;	struct drsuapi_DsBindInfo28 *our_bind_info28;	struct drsuapi_DsBindInfoCtr *our_bind_info_ctr;	const char *binding = torture_setting_string(tctx, "binding", NULL);	ctx = talloc_zero(tctx, struct DsSyncTest);	if (!ctx) return NULL;	status = dcerpc_parse_binding(ctx, binding, &ctx->drsuapi_binding);	if (!NT_STATUS_IS_OK(status)) {		printf("Bad binding string %s\n", binding);		return NULL;	}	ctx->drsuapi_binding->flags |= DCERPC_SIGN | DCERPC_SEAL;	ctx->ldap_url = talloc_asprintf(ctx, "ldap://%s/", ctx->drsuapi_binding->host);	/* ctx->admin ...*/	ctx->admin.credentials				= cmdline_credentials;	our_bind_info28				= &ctx->admin.drsuapi.our_bind_info28;	our_bind_info28->supported_extensions	= 0xFFFFFFFF;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;	our_bind_info28->site_guid		= GUID_zero();	our_bind_info28->u1			= 0;	our_bind_info28->repl_epoch		= 1;	our_bind_info_ctr			= &ctx->admin.drsuapi.our_bind_info_ctr;	our_bind_info_ctr->length		= 28;	our_bind_info_ctr->info.info28		= *our_bind_info28;	GUID_from_string(DRSUAPI_DS_BIND_GUID, &ctx->admin.drsuapi.bind_guid);	ctx->admin.drsuapi.req.in.bind_guid		= &ctx->admin.drsuapi.bind_guid;	ctx->admin.drsuapi.req.in.bind_info		= our_bind_info_ctr;	ctx->admin.drsuapi.req.out.bind_handle		= &ctx->admin.drsuapi.bind_handle;	/* ctx->new_dc ...*/	ctx->new_dc.credentials			= cmdline_credentials;	our_bind_info28				= &ctx->new_dc.drsuapi.our_bind_info28;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_BASE;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;	our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;	if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "xpress", false)) {		our_bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;	}	our_bind_info28->site_guid		= GUID_zero();	our_bind_info28->u1			= 508;	our_bind_info28->repl_epoch		= 0;	our_bind_info_ctr			= &ctx->new_dc.drsuapi.our_bind_info_ctr;	our_bind_info_ctr->length		= 28;	our_bind_info_ctr->info.info28		= *our_bind_info28;	GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3, &ctx->new_dc.drsuapi.bind_guid);	ctx->new_dc.drsuapi.req.in.bind_guid		= &ctx->new_dc.drsuapi.bind_guid;	ctx->new_dc.drsuapi.req.in.bind_info		= our_bind_info_ctr;	ctx->new_dc.drsuapi.req.out.bind_handle		= &ctx->new_dc.drsuapi.bind_handle;	ctx->new_dc.invocation_id			= ctx->new_dc.drsuapi.bind_guid;	/* ctx->old_dc ...*/	return ctx;}static bool _test_DsBind(struct torture_context *tctx,			 struct DsSyncTest *ctx, struct cli_credentials *credentials, struct DsSyncBindInfo *b){	NTSTATUS status;	bool ret = true;	status = dcerpc_pipe_connect_b(ctx,				       &b->pipe, ctx->drsuapi_binding, 				       &ndr_table_drsuapi,				       credentials, tctx->ev, tctx->lp_ctx);		if (!NT_STATUS_IS_OK(status)) {		printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status));		return false;	}	status = dcerpc_drsuapi_DsBind(b->pipe, ctx, &b->req);	if (!NT_STATUS_IS_OK(status)) {		const char *errstr = nt_errstr(status);		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {			errstr = dcerpc_errstr(ctx, b->pipe->last_fault_code);		}		printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);		ret = false;	} else if (!W_ERROR_IS_OK(b->req.out.result)) {		printf("DsBind failed - %s\n", win_errstr(b->req.out.result));		ret = false;	}	ZERO_STRUCT(b->peer_bind_info28);	if (b->req.out.bind_info) {		switch (b->req.out.bind_info->length) {		case 24: {			struct drsuapi_DsBindInfo24 *info24;			info24 = &b->req.out.bind_info->info.info24;			b->peer_bind_info28.supported_extensions= info24->supported_extensions;			b->peer_bind_info28.site_guid		= info24->site_guid;			b->peer_bind_info28.u1			= info24->u1;			b->peer_bind_info28.repl_epoch		= 0;			break;		}		case 28:			b->peer_bind_info28 = b->req.out.bind_info->info.info28;			break;		}	}	return ret;}static bool test_LDAPBind(struct torture_context *tctx, struct DsSyncTest *ctx, 			  struct cli_credentials *credentials, struct DsSyncLDAPInfo *l){	NTSTATUS status;	bool ret = true;	status = torture_ldap_connection(tctx, &l->conn, ctx->ldap_url);	if (!NT_STATUS_IS_OK(status)) {		printf("failed to connect to LDAP: %s\n", ctx->ldap_url);		return false;	}	printf("connected to LDAP: %s\n", ctx->ldap_url);	status = torture_ldap_bind_sasl(l->conn, credentials, tctx->lp_ctx);	if (!NT_STATUS_IS_OK(status)) {		printf("failed to bind to LDAP:\n");		return false;	}	printf("bound to LDAP.\n");	return ret;}static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx){	NTSTATUS status;	struct drsuapi_DsCrackNames r;	struct drsuapi_DsNameString names[1];	bool ret = true;	struct cldap_socket *cldap;	struct cldap_netlogon search;	cldap = cldap_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));	r.in.bind_handle		= &ctx->admin.drsuapi.bind_handle;	r.in.level			= 1;	r.in.req.req1.codepage		= 1252; /* western european */	r.in.req.req1.language		= 0x00000407; /* german */	r.in.req.req1.count		= 1;	r.in.req.req1.names		= names;	r.in.req.req1.format_flags	= DRSUAPI_DS_NAME_FLAG_NO_FLAGS;			r.in.req.req1.format_offered	= DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;	r.in.req.req1.format_desired	= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;	names[0].str = talloc_asprintf(ctx, "%s\\", lp_workgroup(tctx->lp_ctx));	status = dcerpc_drsuapi_DsCrackNames(ctx->admin.drsuapi.pipe, ctx, &r);	if (!NT_STATUS_IS_OK(status)) {		const char *errstr = nt_errstr(status);		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {			errstr = dcerpc_errstr(ctx, ctx->admin.drsuapi.pipe->last_fault_code);		}		printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);		return false;	} else if (!W_ERROR_IS_OK(r.out.result)) {		printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));		return false;	}	ctx->domain_dn = r.out.ctr.ctr1->array[0].result_name;		ZERO_STRUCT(search);	search.in.dest_address = ctx->drsuapi_binding->host;	search.in.dest_port = lp_cldap_port(tctx->lp_ctx);	search.in.acct_control = -1;	search.in.version		= NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;	search.in.map_response = true;	status = cldap_netlogon(cldap, ctx, &search);	if (!NT_STATUS_IS_OK(status)) {		const char *errstr = nt_errstr(status);		ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");		printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr, ctx->site_name);			} else {		ctx->site_name = talloc_steal(ctx, search.out.netlogon.nt5_ex.client_site);		printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx->site_name);		printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site);	}	return ret;}static DATA_BLOB decrypt_blob(TALLOC_CTX *mem_ctx,			      const DATA_BLOB *gensec_skey,			      bool rcrypt,			      struct drsuapi_DsReplicaObjectIdentifier *id,			      uint32_t rid,			      const DATA_BLOB *buffer){	DATA_BLOB confounder;	DATA_BLOB enc_buffer;	struct MD5Context md5;	uint8_t _enc_key[16];	DATA_BLOB enc_key;	DATA_BLOB dec_buffer;	uint32_t crc32_given;	uint32_t crc32_calc;	DATA_BLOB checked_buffer;	DATA_BLOB plain_buffer;	/*	 * the combination "c[3] s[1] e[1] d[0]..."	 * was successful!!!!!!!!!!!!!!!!!!!!!!!!!!	 */	/* 	 * the first 16 bytes at the beginning are the confounder	 * followed by the 4 byte crc32 checksum	 */	if (buffer->length < 20) {		return data_blob_const(NULL, 0);	}	confounder = data_blob_const(buffer->data, 16);	enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16);	/* 	 * build the encryption key md5 over the session key followed	 * by the confounder	 * 	 * here the gensec session key is used and	 * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key!	 */	enc_key = data_blob_const(_enc_key, sizeof(_enc_key));	MD5Init(&md5);	MD5Update(&md5, gensec_skey->data, gensec_skey->length);	MD5Update(&md5, confounder.data, confounder.length);	MD5Final(enc_key.data, &md5);	/*	 * copy the encrypted buffer part and 	 * decrypt it using the created encryption key using arcfour	 */	dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length);	if (!dec_buffer.data) {		return data_blob_const(NULL, 0);	}	arcfour_crypt_blob(dec_buffer.data, dec_buffer.length, &enc_key);	/* 	 * the first 4 byte are the crc32 checksum	 * of the remaining bytes	 */	crc32_given = IVAL(dec_buffer.data, 0);	crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4);	if (crc32_given != crc32_calc) {		DEBUG(0,("CRC32: given[0x%08X] calc[0x%08X]\n",		      crc32_given, crc32_calc));		return data_blob_const(NULL, 0);	}	checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4);	if (!checked_buffer.data) {		return data_blob_const(NULL, 0);	}	/*	 * some attributes seem to be in a usable form after this decryption	 * (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing,	 *  trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming)	 * At least supplementalCredentials contains plaintext	 * like "Primary:Kerberos" (in unicode form)	 *	 * some attributes seem to have some additional encryption	 * dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory	 *	 * it's the sam_rid_crypt() function, as the value is constant,	 * so it doesn't depend on sessionkeys.	 */	if (rcrypt) {		uint32_t i, num_hashes;		if ((checked_buffer.length % 16) != 0) {			return data_blob_const(NULL, 0);		}		plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length);		if (!plain_buffer.data) {			return data_blob_const(NULL, 0);		}					num_hashes = plain_buffer.length / 16;		for (i = 0; i < num_hashes; i++) {			uint32_t offset = i * 16;			sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0);		}	} else {		plain_buffer = checked_buffer;	}	return plain_buffer;}

⌨️ 快捷键说明

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