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

📄 winsreplication.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   WINS replication testing   Copyright (C) Andrew Tridgell	2005   Copyright (C) Stefan Metzmacher	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 "libcli/wrepl/winsrepl.h"#include "lib/events/events.h"#include "lib/socket/socket.h"#include "libcli/resolve/resolve.h"#include "system/network.h"#include "lib/socket/netif.h"#include "librpc/gen_ndr/ndr_nbt.h"#include "torture/torture.h"#include "torture/nbt/proto.h"#include "param/param.h"#define CHECK_STATUS(tctx, status, correct) \	torture_assert_ntstatus_equal(tctx, status, correct, \								  "Incorrect status")#define CHECK_VALUE(tctx, v, correct) \	torture_assert(tctx, (v) == (correct), \				   talloc_asprintf(tctx, "Incorrect value %s=%d - should be %d\n", \		       #v, v, correct))#define CHECK_VALUE_UINT64(tctx, v, correct) \	torture_assert(tctx, (v) == (correct), \		talloc_asprintf(tctx, "Incorrect value %s=%llu - should be %llu\n", \		       #v, (long long)v, (long long)correct))#define CHECK_VALUE_STRING(tctx, v, correct) \	torture_assert_str_equal(tctx, v, correct, "Invalid value")#define _NBT_NAME(n,t,s) {\	.name	= n,\	.type	= t,\	.scope	= s\}static const char *wrepl_name_type_string(enum wrepl_name_type type){	switch (type) {	case WREPL_TYPE_UNIQUE: return "UNIQUE";	case WREPL_TYPE_GROUP: return "GROUP";	case WREPL_TYPE_SGROUP: return "SGROUP";	case WREPL_TYPE_MHOMED: return "MHOMED";	}	return "UNKNOWN_TYPE";}static const char *wrepl_name_state_string(enum wrepl_name_state state){	switch (state) {	case WREPL_STATE_ACTIVE: return "ACTIVE";	case WREPL_STATE_RELEASED: return "RELEASED";	case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";	case WREPL_STATE_RESERVED: return "RESERVED";	}	return "UNKNOWN_STATE";}/*  test how assoc_ctx's are only usable on the connection  they are created on.*/static bool test_assoc_ctx1(struct torture_context *tctx){	bool ret = true;	struct wrepl_request *req;	struct wrepl_socket *wrepl_socket1;	struct wrepl_associate associate1;	struct wrepl_socket *wrepl_socket2;	struct wrepl_associate associate2;	struct wrepl_pull_table pull_table;	struct wrepl_packet packet;	struct wrepl_send_ctrl ctrl;	struct wrepl_packet *rep_packet;	struct wrepl_associate_stop assoc_stop;	NTSTATUS status;	struct nbt_name name;	const char *address;	if (!torture_nbt_get_name(tctx, &name, &address))		return false;	torture_comment(tctx, "Test if assoc_ctx is only valid on the conection it was created on\n");	wrepl_socket1 = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));	wrepl_socket2 = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));	torture_comment(tctx, "Setup 2 wrepl connections\n");	status = wrepl_connect(wrepl_socket1, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	status = wrepl_connect(wrepl_socket2, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send a start association request (conn1)\n");	status = wrepl_associate(wrepl_socket1, &associate1);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "association context (conn1): 0x%x\n", associate1.out.assoc_ctx);	torture_comment(tctx, "Send a start association request (conn2)\n");	status = wrepl_associate(wrepl_socket2, &associate2);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "association context (conn2): 0x%x\n", associate2.out.assoc_ctx);	torture_comment(tctx, "Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");	ZERO_STRUCT(packet);	packet.opcode                      = WREPL_OPCODE_BITS;	packet.assoc_ctx                   = associate1.out.assoc_ctx;	packet.mess_type                   = WREPL_REPLICATION;	packet.message.replication.command = WREPL_REPL_TABLE_QUERY;	ZERO_STRUCT(ctrl);	ctrl.send_only = true;	req = wrepl_request_send(wrepl_socket2, &packet, &ctrl);	status = wrepl_request_recv(req, tctx, &rep_packet);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send a association request (conn2), to make sure the last request was ignored\n");	status = wrepl_associate(wrepl_socket2, &associate2);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");	pull_table.in.assoc_ctx = 0;	req = wrepl_pull_table_send(wrepl_socket1, &pull_table);	status = wrepl_request_recv(req, tctx, &rep_packet);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send a association request (conn1), to make sure the last request was handled correct\n");	status = wrepl_associate(wrepl_socket1, &associate2);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	assoc_stop.in.assoc_ctx	= associate1.out.assoc_ctx;	assoc_stop.in.reason	= 4;	torture_comment(tctx, "Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);	status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);	CHECK_STATUS(tctx, status, NT_STATUS_END_OF_FILE);	assoc_stop.in.assoc_ctx	= associate2.out.assoc_ctx;	assoc_stop.in.reason	= 0;	torture_comment(tctx, "Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);	status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Close 2 wrepl connections\n");	talloc_free(wrepl_socket1);	talloc_free(wrepl_socket2);	return ret;}/*  test if we always get back the same assoc_ctx*/static bool test_assoc_ctx2(struct torture_context *tctx){	struct wrepl_socket *wrepl_socket;	struct wrepl_associate associate;	uint32_t assoc_ctx1;	struct nbt_name name;	NTSTATUS status;	const char *address;	if (!torture_nbt_get_name(tctx, &name, &address))		return false;	torture_comment(tctx, "Test if we always get back the same assoc_ctx\n");	wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));		torture_comment(tctx, "Setup wrepl connections\n");	status = wrepl_connect(wrepl_socket, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send 1st start association request\n");	status = wrepl_associate(wrepl_socket, &associate);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	assoc_ctx1 = associate.out.assoc_ctx;	torture_comment(tctx, "1st association context: 0x%x\n", associate.out.assoc_ctx);	torture_comment(tctx, "Send 2nd start association request\n");	status = wrepl_associate(wrepl_socket, &associate);	torture_assert_ntstatus_ok(tctx, status, "2nd start association failed");	torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1, 				   "Different context returned");	torture_comment(tctx, "2nd association context: 0x%x\n", associate.out.assoc_ctx);	torture_comment(tctx, "Send 3rd start association request\n");	status = wrepl_associate(wrepl_socket, &associate);	torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1, 				   "Different context returned");	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "3rd association context: 0x%x\n", associate.out.assoc_ctx);	torture_comment(tctx, "Close wrepl connections\n");	talloc_free(wrepl_socket);	return true;}/*  display a replication entry*/static void display_entry(struct torture_context *tctx, struct wrepl_name *name){	int i;	torture_comment(tctx, "%s\n", nbt_name_string(tctx, &name->name));	torture_comment(tctx, "\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",		name->type, name->state, name->node, name->is_static, (long long)name->version_id);	torture_comment(tctx, "\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",		name->raw_flags, name->owner);	for (i=0;i<name->num_addresses;i++) {		torture_comment(tctx, "\tADDR: %-15s OWNER: %-15s\n", 			name->addresses[i].address, name->addresses[i].owner);	}}/*  test a full replication dump from a WINS server*/static bool test_wins_replication(struct torture_context *tctx){	struct wrepl_socket *wrepl_socket;	NTSTATUS status;	int i, j;	struct wrepl_associate associate;	struct wrepl_pull_table pull_table;	struct wrepl_pull_names pull_names;	struct nbt_name name;	const char *address;	if (!torture_nbt_get_name(tctx, &name, &address))		return false;	torture_comment(tctx, "Test one pull replication cycle\n");	wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));		torture_comment(tctx, "Setup wrepl connections\n");	status = wrepl_connect(wrepl_socket, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Send a start association request\n");	status = wrepl_associate(wrepl_socket, &associate);	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "association context: 0x%x\n", associate.out.assoc_ctx);	torture_comment(tctx, "Send a replication table query\n");	pull_table.in.assoc_ctx = associate.out.assoc_ctx;	status = wrepl_pull_table(wrepl_socket, tctx, &pull_table);	if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {		struct wrepl_packet packet;		struct wrepl_request *req;		ZERO_STRUCT(packet);		packet.opcode                      = WREPL_OPCODE_BITS;		packet.assoc_ctx                   = associate.out.assoc_ctx;		packet.mess_type                   = WREPL_STOP_ASSOCIATION;		packet.message.stop.reason         = 0;		req = wrepl_request_send(wrepl_socket, &packet, NULL);		talloc_free(req);		torture_fail(tctx, "We are not a valid pull partner for the server");	}	CHECK_STATUS(tctx, status, NT_STATUS_OK);	torture_comment(tctx, "Found %d replication partners\n", pull_table.out.num_partners);	for (i=0;i<pull_table.out.num_partners;i++) {		struct wrepl_wins_owner *partner = &pull_table.out.partners[i];		torture_comment(tctx, "%s   max_version=%6llu   min_version=%6llu type=%d\n",		       partner->address, 		       (long long)partner->max_version, 		       (long long)partner->min_version, 		       partner->type);		pull_names.in.assoc_ctx = associate.out.assoc_ctx;		pull_names.in.partner = *partner;				status = wrepl_pull_names(wrepl_socket, tctx, &pull_names);		CHECK_STATUS(tctx, status, NT_STATUS_OK);		torture_comment(tctx, "Received %d names\n", pull_names.out.num_names);		for (j=0;j<pull_names.out.num_names;j++) {			display_entry(tctx, &pull_names.out.names[j]);		}	}	torture_comment(tctx, "Close wrepl connections\n");	talloc_free(wrepl_socket);	return true;}struct test_wrepl_conflict_conn {	const char *address;	struct wrepl_socket *pull;	uint32_t pull_assoc;#define TEST_OWNER_A_ADDRESS "127.65.65.1"#define TEST_ADDRESS_A_PREFIX "127.0.65"#define TEST_OWNER_B_ADDRESS "127.66.66.1"#define TEST_ADDRESS_B_PREFIX "127.0.66"#define TEST_OWNER_X_ADDRESS "127.88.88.1"#define TEST_ADDRESS_X_PREFIX "127.0.88"	struct wrepl_wins_owner a, b, c, x;	struct socket_address *myaddr;	struct socket_address *myaddr2;	struct nbt_name_socket *nbtsock;	struct nbt_name_socket *nbtsock2;	struct nbt_name_socket *nbtsock_srv;	struct nbt_name_socket *nbtsock_srv2;	uint32_t addresses_best_num;	struct wrepl_ip *addresses_best;	uint32_t addresses_best2_num;	struct wrepl_ip *addresses_best2;	uint32_t addresses_all_num;	struct wrepl_ip *addresses_all;	uint32_t addresses_mhomed_num;	struct wrepl_ip *addresses_mhomed;};static const struct wrepl_ip addresses_A_1[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".1"	}};static const struct wrepl_ip addresses_A_2[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".2"	}};static const struct wrepl_ip addresses_A_3_4[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	}};static const struct wrepl_ip addresses_A_3_4_X_3_4[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".3"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".4"	}};static const struct wrepl_ip addresses_A_3_4_B_3_4[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".4"	}};static const struct wrepl_ip addresses_A_3_4_OWNER_B[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	}};static const struct wrepl_ip addresses_A_3_4_X_3_4_OWNER_B[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".4"	}};static const struct wrepl_ip addresses_A_3_4_X_1_2[] = {	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".3"	},	{	.owner	= TEST_OWNER_A_ADDRESS,	.ip	= TEST_ADDRESS_A_PREFIX".4"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".1"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".2"	}};static const struct wrepl_ip addresses_B_1[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".1"	}};static const struct wrepl_ip addresses_B_2[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".2"	}};static const struct wrepl_ip addresses_B_3_4[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".4"	}};static const struct wrepl_ip addresses_B_3_4_X_3_4[] = {	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".3"	},	{	.owner	= TEST_OWNER_B_ADDRESS,	.ip	= TEST_ADDRESS_B_PREFIX".4"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".3"	},	{	.owner	= TEST_OWNER_X_ADDRESS,	.ip	= TEST_ADDRESS_X_PREFIX".4"	}};static const struct wrepl_ip addresses_B_3_4_X_1_2[] = {

⌨️ 快捷键说明

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