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

📄 samsync.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    Unix SMB/CIFS implementation.   test suite for netlogon rpc operations   Copyright (C) Andrew Tridgell 2003   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004   Copyright (C) Tim Potter      2003      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 "torture/torture.h"#include "auth/auth.h"#include "lib/util/dlinklist.h"#include "lib/crypto/crypto.h"#include "system/time.h"#include "torture/rpc/rpc.h"#include "auth/gensec/schannel_proto.h"#include "auth/gensec/gensec.h"#include "libcli/auth/libcli_auth.h"#include "libcli/security/security.h"#include "librpc/gen_ndr/ndr_netlogon.h"#include "librpc/gen_ndr/ndr_netlogon_c.h"#include "librpc/gen_ndr/ndr_lsa_c.h"#include "librpc/gen_ndr/ndr_samr_c.h"#include "librpc/gen_ndr/ndr_security.h"#include "param/param.h"#define TEST_MACHINE_NAME "samsynctest"#define TEST_WKSTA_MACHINE_NAME "samsynctest2"#define TEST_USER_NAME "samsynctestuser"/*  try a netlogon SamLogon*/static NTSTATUS test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 			      struct creds_CredentialState *creds, 			      const char *domain, const char *account_name,			      const char *workstation, 			      struct samr_Password *lm_hash, 			      struct samr_Password *nt_hash, 			      struct netr_SamInfo3 **info3){	NTSTATUS status;	struct netr_LogonSamLogon r;	struct netr_Authenticator auth, auth2;	struct netr_NetworkInfo ninfo;	ninfo.identity_info.domain_name.string = domain;	ninfo.identity_info.parameter_control = 0;	ninfo.identity_info.logon_id_low = 0;	ninfo.identity_info.logon_id_high = 0;	ninfo.identity_info.account_name.string = account_name;	ninfo.identity_info.workstation.string = workstation;	generate_random_buffer(ninfo.challenge, 			       sizeof(ninfo.challenge));	if (nt_hash) {		ninfo.nt.length = 24;		ninfo.nt.data = talloc_array(mem_ctx, uint8_t, 24);		SMBOWFencrypt(nt_hash->hash, ninfo.challenge, ninfo.nt.data);	} else {		ninfo.nt.length = 0;		ninfo.nt.data = NULL;	}		if (lm_hash) {		ninfo.lm.length = 24;		ninfo.lm.data = talloc_array(mem_ctx, uint8_t, 24);		SMBOWFencrypt(lm_hash->hash, ninfo.challenge, ninfo.lm.data);	} else {		ninfo.lm.length = 0;		ninfo.lm.data = NULL;	}	r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));	r.in.computer_name = workstation;	r.in.credential = &auth;	r.in.return_authenticator = &auth2;	r.in.logon_level = 2;	r.in.logon.network = &ninfo;	ZERO_STRUCT(auth2);	creds_client_authenticator(creds, &auth);		r.in.validation_level = 3;		status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);	if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {		printf("Credential chaining failed\n");	}	if (info3) {		*info3 = r.out.validation.sam3;	}	return status;}struct samsync_state {/* we remember the sequence numbers so we can easily do a DatabaseDelta */	uint64_t seq_num[3];	const char *domain_name[2];	struct samsync_secret *secrets;	struct samsync_trusted_domain *trusted_domains;	struct creds_CredentialState *creds;	struct creds_CredentialState *creds_netlogon_wksta;	struct policy_handle *connect_handle;	struct policy_handle *domain_handle[2];	struct dom_sid *sid[2];	struct dcerpc_pipe *p;	struct dcerpc_pipe *p_netlogon_wksta;	struct dcerpc_pipe *p_samr;	struct dcerpc_pipe *p_lsa;	struct policy_handle *lsa_handle;};struct samsync_secret {	struct samsync_secret *prev, *next;	DATA_BLOB secret;	const char *name;	NTTIME mtime;};struct samsync_trusted_domain {	struct samsync_trusted_domain *prev, *next;        struct dom_sid *sid;	const char *name;};static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, 						 struct samsync_state *samsync_state, 						 const char *domain, 						 struct dom_sid **sid){	struct lsa_String name;	struct samr_OpenDomain o;	struct samr_LookupDomain l;	struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle);	NTSTATUS nt_status;	name.string = domain;	l.in.connect_handle = samsync_state->connect_handle;	l.in.domain_name = &name;	nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l);	if (!NT_STATUS_IS_OK(nt_status)) {		printf("LookupDomain failed - %s\n", nt_errstr(nt_status));		return NULL;	}	o.in.connect_handle = samsync_state->connect_handle;	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;	o.in.sid = l.out.sid;	o.out.domain_handle = domain_handle;		if (sid) {		*sid = l.out.sid;	}	nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o);	if (!NT_STATUS_IS_OK(nt_status)) {		printf("OpenDomain failed - %s\n", nt_errstr(nt_status));		return NULL;	}	return domain_handle;}static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx, 							struct samsync_state *samsync_state, 							struct policy_handle *handle) {	struct samr_QuerySecurity r;	NTSTATUS status;	r.in.handle = handle;	r.in.sec_info = 0x7;	status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r);	if (!NT_STATUS_IS_OK(status)) {		printf("SAMR QuerySecurity failed - %s\n", nt_errstr(status));		return NULL;	}	return r.out.sdbuf;}static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, 						       struct samsync_state *samsync_state, 						       struct policy_handle *handle) {	struct lsa_QuerySecurity r;	NTSTATUS status;	r.in.handle = handle;	r.in.sec_info = 0x7;	status = dcerpc_lsa_QuerySecurity(samsync_state->p_lsa, mem_ctx, &r);	if (!NT_STATUS_IS_OK(status)) {		printf("LSA QuerySecurity failed - %s\n", nt_errstr(status));		return NULL;	}	return r.out.sdbuf;}#define TEST_UINT64_EQUAL(i1, i2) do {\	if (i1 != i2) {\              printf("%s: uint64 mismatch: " #i1 ": 0x%016llx (%lld) != " #i2 ": 0x%016llx (%lld)\n", \		     __location__, \		     (long long)i1, (long long)i1, \		     (long long)i2, (long long)i2);\	      ret = false;\	} \} while (0)#define TEST_INT_EQUAL(i1, i2) do {\	if (i1 != i2) {\	      printf("%s: integer mismatch: " #i1 ": 0x%08x (%d) != " #i2 ": 0x%08x (%d)\n", \		     __location__, i1, i1, i2, i2);			\	      ret = false;\	} \} while (0)#define TEST_TIME_EQUAL(t1, t2) do {\	if (t1 != t2) {\	      printf("%s: NTTIME mismatch: " #t1 ":%s != " #t2 ": %s\n", \		     __location__, nt_time_string(mem_ctx, t1),  nt_time_string(mem_ctx, t2));\	      ret = false;\	} \} while (0)#define TEST_STRING_EQUAL(s1, s2) do {\	if (!((!s1.string || s1.string[0]=='\0') && (!s2.string || s2.string[0]=='\0')) \	    && strcmp_safe(s1.string, s2.string) != 0) {\	      printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \		     __location__, s1.string, s2.string);\	      ret = false;\	} \} while (0)#define TEST_SID_EQUAL(s1, s2) do {\	if (!dom_sid_equal(s1, s2)) {\	      printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \		     __location__, dom_sid_string(mem_ctx, s1), dom_sid_string(mem_ctx, s2));\	      ret = false;\	} \} while (0)/* The ~SEC_DESC_SACL_PRESENT is because we don't, as administrator, * get back the SACL part of the SD when we ask over SAMR */#define TEST_SEC_DESC_EQUAL(sd1, pipe, handle) do {\        struct sec_desc_buf *sdbuf = samsync_query_ ##pipe## _sec_desc(mem_ctx, samsync_state, \						            handle); \	if (!sdbuf || !sdbuf->sd) { \                printf("Could not obtain security descriptor to match " #sd1 "\n");\	        ret = false; \        } else {\		if (!security_descriptor_mask_equal(sd1.sd, sdbuf->sd, \ 			    ~SEC_DESC_SACL_PRESENT)) {\			printf("Security Descriptor Mismatch for %s:\n", #sd1);\		        ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "SamSync", sd1.sd);\		        ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "SamR", sdbuf->sd);\			ret = false;\		}\	}\} while (0)static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state,			   int database_id, struct netr_DELTA_ENUM *delta) {	struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain;	struct dom_sid *dom_sid;	struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */	uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};	NTSTATUS nt_status;	int i;	bool ret = true;		samsync_state->seq_num[database_id] = 		domain->sequence_num;	switch (database_id) {	case SAM_DATABASE_DOMAIN:		break;	case SAM_DATABASE_BUILTIN:		if (strcasecmp_m("BUILTIN", domain->domain_name.string) != 0) {			printf("BUILTIN domain has different name: %s\n", domain->domain_name.string);		}		break;	case SAM_DATABASE_PRIVS:		printf("DOMAIN entry on privs DB!\n");		return false;		break;	}		if (!samsync_state->domain_name[database_id]) {		samsync_state->domain_name[database_id] = 			talloc_reference(samsync_state, domain->domain_name.string);	} else {		if (strcasecmp_m(samsync_state->domain_name[database_id], domain->domain_name.string) != 0) {			printf("Domain has name varies!: %s != %s\n", samsync_state->domain_name[database_id], 			       domain->domain_name.string);			return false;		}	}	if (!samsync_state->domain_handle[database_id]) {		samsync_state->domain_handle[database_id]			= talloc_reference(samsync_state, 					   samsync_open_domain(mem_ctx, samsync_state, samsync_state->domain_name[database_id], 							       &dom_sid));	}	if (samsync_state->domain_handle[database_id]) {		samsync_state->sid[database_id] = talloc_reference(samsync_state, dom_sid);	}	printf("\tsequence_nums[%d/%s]=%llu\n",	       database_id, domain->domain_name.string,	       (long long)samsync_state->seq_num[database_id]);	for (i=0;i<ARRAY_SIZE(levels);i++) {		q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id];		q[levels[i]].in.level = levels[i];		nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]);		if (!NT_STATUS_IS_OK(nt_status)) {			printf("QueryDomainInfo level %u failed - %s\n", 			       q[levels[i]].in.level, nt_errstr(nt_status));			return false;		}	}	TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name);		TEST_STRING_EQUAL(q[2].out.info->info2.comment, domain->comment);	TEST_STRING_EQUAL(q[4].out.info->info4.comment, domain->comment);	TEST_TIME_EQUAL(q[2].out.info->info2.force_logoff_time, domain->force_logoff_time);	TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time);	TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length);	TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length);	TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age);	TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age);	TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num, 			domain->sequence_num);	TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time, 			domain->domain_create_time);	TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time, 			domain->domain_create_time);	TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]);	return ret;}static bool samsync_handle_policy(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state,			   int database_id, struct netr_DELTA_ENUM *delta) {	struct netr_DELTA_POLICY *policy = delta->delta_union.policy;	samsync_state->seq_num[database_id] = 		policy->sequence_num;		if (!samsync_state->domain_name[SAM_DATABASE_DOMAIN]) {		samsync_state->domain_name[SAM_DATABASE_DOMAIN] = 			talloc_reference(samsync_state, policy->primary_domain_name.string);	} else {		if (strcasecmp_m(samsync_state->domain_name[SAM_DATABASE_DOMAIN], policy->primary_domain_name.string) != 0) {			printf("PRIMARY domain has name varies between DOMAIN and POLICY!: %s != %s\n", samsync_state->domain_name[SAM_DATABASE_DOMAIN], 			       policy->primary_domain_name.string);			return false;		}	}	if (!dom_sid_equal(samsync_state->sid[SAM_DATABASE_DOMAIN], policy->sid)) {		printf("Domain SID from POLICY (%s) does not match domain sid from SAMR (%s)\n", 		       dom_sid_string(mem_ctx, policy->sid), dom_sid_string(mem_ctx, samsync_state->sid[SAM_DATABASE_DOMAIN]));		return false;	}	printf("\tsequence_nums[%d/PRIVS]=%llu\n",	       database_id, 	       (long long)samsync_state->seq_num[database_id]);	return true;}static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state,				int database_id, struct netr_DELTA_ENUM *delta) {	uint32_t rid = delta->delta_id_union.rid;	struct netr_DELTA_USER *user = delta->delta_union.user;	struct netr_SamInfo3 *info3;	struct samr_Password lm_hash;	struct samr_Password nt_hash;	struct samr_Password *lm_hash_p = NULL;

⌨️ 快捷键说明

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