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

📄 wrepl_apply_records.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
							     struct r_do_challenge_state);	bool old_is_subset = false;	bool new_is_subset = false;	bool found = false;	uint32_t i,j;	uint32_t num_rec_addrs;	status = irpc_call_recv(ireq);	DEBUG(4,("r_do_challenge_handler: %s: %s\n", 		 nbt_name_string(state, &state->replica.name), nt_errstr(status)));	if (NT_STATUS_EQUAL(NT_STATUS_IO_TIMEOUT, status) ||	    NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {		r_do_replace(state->partner, state, state->rec, &state->owner, &state->replica);		talloc_free(state);		return;	}	for (i=0; i < state->replica.num_addresses; i++) {		found = false;		new_is_subset = true;		for (j=0; j < state->r.out.num_addrs; j++) {			if (strcmp(state->replica.addresses[i].address, state->r.out.addrs[j].addr) == 0) {				found = true;				break;			}		}		if (found) continue;		new_is_subset = false;		break;	}	if (!new_is_subset) {		r_not_replace(state->partner, state, state->rec, &state->owner, &state->replica);		talloc_free(state);		return;	}	num_rec_addrs = winsdb_addr_list_length(state->rec->addresses);	for (i=0; i < num_rec_addrs; i++) {		found = false;		old_is_subset = true;		for (j=0; j < state->r.out.num_addrs; j++) {			if (strcmp(state->rec->addresses[i]->address, state->r.out.addrs[j].addr) == 0) {				found = true;				break;			}		}		if (found) continue;		old_is_subset = false;		break;	}	if (!old_is_subset) {		status = r_do_late_release_demand(state);		/* 		 * only free state on error, because we pass it down,		 * and r_do_late_release_demand() will free it		 */		if (!NT_STATUS_IS_OK(status)) {			talloc_free(state);		}		return;	}	r_do_mhomed_merge(state->partner, state, state->rec, &state->owner, &state->replica);	talloc_free(state);}static NTSTATUS r_do_challenge(struct wreplsrv_partner *partner,			       TALLOC_CTX *mem_ctx,			       struct winsdb_record *rec,			       struct wrepl_wins_owner *owner,			       struct wrepl_name *replica){	struct irpc_request *ireq;	struct r_do_challenge_state *state;	struct server_id *nbt_servers;	const char **addrs;	uint32_t i;	DEBUG(4,("challenge record %s\n",		 nbt_name_string(mem_ctx, &replica->name)));	state = talloc_zero(mem_ctx, struct r_do_challenge_state);	NT_STATUS_HAVE_NO_MEMORY(state);	state->msg_ctx	= partner->service->task->msg_ctx;	state->partner	= partner;	state->rec	= talloc_steal(state, rec);	state->owner	= *owner;	state->replica	= *replica;	/* some stuff to have valid memory pointers in the async complete function */	state->replica.name = *state->rec->name;	talloc_steal(state, replica->owner);	talloc_steal(state, replica->addresses);	nbt_servers = irpc_servers_byname(state->msg_ctx, state, "nbt_server");	if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) {		return NT_STATUS_INTERNAL_ERROR;	}	state->r.in.name	= *rec->name;	state->r.in.num_addrs	= winsdb_addr_list_length(rec->addresses);	state->r.in.addrs	= talloc_array(state, struct nbtd_proxy_wins_addr, state->r.in.num_addrs);	NT_STATUS_HAVE_NO_MEMORY(state->r.in.addrs);	/* TODO: fix pidl to handle inline ipv4address arrays */	addrs			= winsdb_addr_string_list(state->r.in.addrs, rec->addresses);	NT_STATUS_HAVE_NO_MEMORY(addrs);	for (i=0; i < state->r.in.num_addrs; i++) {		state->r.in.addrs[i].addr = addrs[i];	}	ireq = IRPC_CALL_SEND(state->msg_ctx, nbt_servers[0],			      irpc, NBTD_PROXY_WINS_CHALLENGE,			      &state->r, state);	NT_STATUS_HAVE_NO_MEMORY(ireq);	ireq->async.fn		= r_do_challenge_handler;	ireq->async.private	= state;	talloc_steal(partner, state);	return NT_STATUS_OK;}struct r_do_release_demand_state {	struct messaging_context *msg_ctx;	struct nbtd_proxy_wins_release_demand r;};static void r_do_release_demand_handler(struct irpc_request *ireq){	NTSTATUS status;	struct r_do_release_demand_state *state = talloc_get_type(ireq->async.private,						  struct r_do_release_demand_state);	status = irpc_call_recv(ireq);	/* don't care about the result */	talloc_free(state);}static NTSTATUS r_do_release_demand(struct wreplsrv_partner *partner,				    TALLOC_CTX *mem_ctx,				    struct winsdb_record *rec,				    struct wrepl_wins_owner *owner,				    struct wrepl_name *replica){	NTSTATUS status;	struct irpc_request *ireq;	struct server_id *nbt_servers;	const char **addrs;	struct winsdb_addr **addresses;	struct r_do_release_demand_state *state;	uint32_t i;	/*	 * we need to get a reference to the old addresses,	 * as we need to send a release demand to them after replacing the record	 * and r_do_replace() will modify rec->addresses	 */	addresses = rec->addresses;	status = r_do_replace(partner, mem_ctx, rec, owner, replica);	NT_STATUS_NOT_OK_RETURN(status);	DEBUG(4,("release demand record %s\n",		 nbt_name_string(mem_ctx, &replica->name)));	state = talloc_zero(mem_ctx, struct r_do_release_demand_state);	NT_STATUS_HAVE_NO_MEMORY(state);	state->msg_ctx	= partner->service->task->msg_ctx;	nbt_servers = irpc_servers_byname(state->msg_ctx, state, "nbt_server");	if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) {		return NT_STATUS_INTERNAL_ERROR;	}	state->r.in.name	= *rec->name;	state->r.in.num_addrs	= winsdb_addr_list_length(addresses);	state->r.in.addrs	= talloc_array(state, struct nbtd_proxy_wins_addr,					       state->r.in.num_addrs);	NT_STATUS_HAVE_NO_MEMORY(state->r.in.addrs);	/* TODO: fix pidl to handle inline ipv4address arrays */	addrs			= winsdb_addr_string_list(state->r.in.addrs, addresses);	NT_STATUS_HAVE_NO_MEMORY(addrs);	for (i=0; i < state->r.in.num_addrs; i++) {		state->r.in.addrs[i].addr = addrs[i];	}	ireq = IRPC_CALL_SEND(state->msg_ctx, nbt_servers[0],			      irpc, NBTD_PROXY_WINS_RELEASE_DEMAND,			      &state->r, state);	NT_STATUS_HAVE_NO_MEMORY(ireq);	ireq->async.fn		= r_do_release_demand_handler;	ireq->async.private	= state;	talloc_steal(partner, state);	return NT_STATUS_OK;}/*SGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4 vs. B:A_3_4 => NOT REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4 vs. B:NULL => NOT REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4_X_3_4 vs. B:A_3_4 => NOT REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:B_3_4 vs. B:A_3_4 => REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4 vs. B:A_3_4_OWNER_B => REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4_OWNER_B vs. B:A_3_4 => REPLACESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4 vs. B:B_3_4 => C:A_3_4_B_3_4 => SGROUP_MERGESGROUP,ACTIVE vs. SGROUP,ACTIVE A:B_3_4_X_3_4 vs. B:A_3_4 => B:A_3_4_X_3_4 => SGROUP_MERGESGROUP,ACTIVE vs. SGROUP,ACTIVE A:X_3_4 vs. B:A_3_4 => C:A_3_4_X_3_4 => SGROUP_MERGESGROUP,ACTIVE vs. SGROUP,ACTIVE A:A_3_4_X_3_4 vs. B:A_3_4_OWNER_B => B:A_3_4_OWNER_B_X_3_4 => SGROUP_MERGESGROUP,ACTIVE vs. SGROUP,ACTIVE A:B_3_4_X_3_4 vs. B:B_3_4_X_1_2 => C:B_3_4_X_1_2_3_4 => SGROUP_MERGESGROUP,ACTIVE vs. SGROUP,ACTIVE A:B_3_4_X_3_4 vs. B:NULL => B:X_3_4 => SGROUP_MERGETest Replica vs. owned active: SGROUP vs. SGROUP tests_SA_SA_DI_U<1c> => SGROUP_MERGE_SA_SA_SI_U<1c> => SGROUP_MERGE_SA_SA_SP_U<1c> => SGROUP_MERGE_SA_SA_SB_U<1c> => SGROUP_MERGE*/static NTSTATUS r_do_sgroup_merge(struct wreplsrv_partner *partner,				  TALLOC_CTX *mem_ctx,				  struct winsdb_record *rec,				  struct wrepl_wins_owner *owner,				  struct wrepl_name *replica){	struct winsdb_record *merge;	uint32_t modify_flags = 0;	uint32_t i,j;	uint8_t ret;	size_t len;	bool changed_old_addrs = false;	bool become_owner = true;	merge = talloc(mem_ctx, struct winsdb_record);	NT_STATUS_HAVE_NO_MEMORY(merge);	merge->name		= &replica->name;	merge->type		= replica->type;	merge->state		= replica->state;	merge->node		= replica->node;	merge->is_static	= replica->is_static;	merge->expire_time	= time(NULL) + partner->service->config.verify_interval;	merge->version		= replica->version_id;	merge->wins_owner	= replica->owner;	merge->addresses	= winsdb_addr_list_make(merge);	NT_STATUS_HAVE_NO_MEMORY(merge->addresses);	merge->registered_by = NULL;	len = winsdb_addr_list_length(rec->addresses);	for (i=0; i < len; i++) {		bool found = false;		for (j=0; j < replica->num_addresses; j++) {			if (strcmp(rec->addresses[i]->address, replica->addresses[j].address) != 0) {				continue;			}			found = true;			if (strcmp(rec->addresses[i]->wins_owner, replica->addresses[j].owner) != 0) {				changed_old_addrs = true;				break;			}			break;		}		/* 		 * if the address isn't in the replica and is owned by replicas owner,		 * it won't be added to the merged record		 */		if (!found && strcmp(rec->addresses[i]->wins_owner, owner->address) == 0) {			changed_old_addrs = true;			continue;		}		/*		 * add the address to the merge result, with the old owner and expire_time,		 * the owner and expire_time will be overwritten later if the address is		 * in the replica too		 */		merge->addresses = winsdb_addr_list_add(partner->service->wins_db,							merge, merge->addresses,							rec->addresses[i]->address,							rec->addresses[i]->wins_owner,							rec->addresses[i]->expire_time,							false);		NT_STATUS_HAVE_NO_MEMORY(merge->addresses);	}	for (i=0; i < replica->num_addresses; i++) {		merge->addresses = winsdb_addr_list_add(partner->service->wins_db,							merge, merge->addresses,							replica->addresses[i].address,							replica->addresses[i].owner,							merge->expire_time,							false);		NT_STATUS_HAVE_NO_MEMORY(merge->addresses);	}	/* we the old addresses change changed we don't become the owner */	if (changed_old_addrs) {		become_owner = false;	}	/* if we're the owner of the old record, we'll be the owner of the new one too */	if (strcmp(rec->wins_owner, partner->service->wins_db->local_owner)==0) {		become_owner = true;	}	/*	 * if the result has no addresses we take the ownership	 */	len = winsdb_addr_list_length(merge->addresses);	if (len == 0) {		become_owner = true;	}	/* 	 * if addresses of the old record will be changed the replica owner	 * will be owner of the merge result, otherwise we take the ownership	 */	if (become_owner) {		modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;	}	ret = winsdb_modify(partner->service->wins_db, merge, modify_flags);	if (ret != NBT_RCODE_OK) {		DEBUG(0,("Failed to modify sgroup merge record %s: %u\n",			nbt_name_string(mem_ctx, &replica->name), ret));		return NT_STATUS_FOOBAR;	}	DEBUG(4,("sgroup merge record %s\n",		nbt_name_string(mem_ctx, &replica->name)));	return NT_STATUS_OK;}static NTSTATUS wreplsrv_apply_one_record(struct wreplsrv_partner *partner,					  TALLOC_CTX *mem_ctx,					  struct wrepl_wins_owner *owner,					  struct wrepl_name *replica){	NTSTATUS status;	struct winsdb_record *rec = NULL;	enum _R_ACTION action = R_INVALID;	bool same_owner = false;	bool replica_vs_replica = false;	bool local_vs_replica = false;	status = winsdb_lookup(partner->service->wins_db,			       &replica->name, mem_ctx, &rec);	if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {		return r_do_add(partner, mem_ctx, owner, replica);	}	NT_STATUS_NOT_OK_RETURN(status);	if (strcmp(rec->wins_owner, partner->service->wins_db->local_owner)==0) {		local_vs_replica = true;	} else if (strcmp(rec->wins_owner, owner->address)==0) {		same_owner = true;	} else {		replica_vs_replica = true;	}	if (rec->is_static && !same_owner) {		action = R_NOT_REPLACE;		/*		 * if we own the local record, then propagate it back to		 * the other wins servers.		 * to prevent ping-pong with other servers, we don't do this		 * if the replica is static too.		 *		 * It seems that w2k3 doesn't do this, but I thing that's a bug		 * and doing propagation helps to have consistent data on all servers		 */		if (local_vs_replica && !replica->is_static) {			action = R_DO_PROPAGATE;		}	} else if (replica->is_static && !rec->is_static && !same_owner) {		action = R_DO_REPLACE;	} else if (same_owner) {		action = replace_same_owner(rec, replica);	} else if (replica_vs_replica) {		switch (rec->type) {		case WREPL_TYPE_UNIQUE:			action = replace_unique_replica_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_GROUP:			action = replace_group_replica_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_SGROUP:			action = replace_sgroup_replica_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_MHOMED:			action = replace_mhomed_replica_vs_X_replica(rec, replica);			break;		}	} else if (local_vs_replica) {		switch (rec->type) {		case WREPL_TYPE_UNIQUE:			action = replace_unique_owned_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_GROUP:			action = replace_group_owned_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_SGROUP:			action = replace_sgroup_owned_vs_X_replica(rec, replica);			break;		case WREPL_TYPE_MHOMED:			action = replace_mhomed_owned_vs_X_replica(rec, replica);			break;		}	}	DEBUG(4,("apply record %s: %s\n",		 nbt_name_string(mem_ctx, &replica->name), _R_ACTION_enum_string(action)));	switch (action) {	case R_INVALID: break;	case R_DO_REPLACE:		return r_do_replace(partner, mem_ctx, rec, owner, replica);	case R_NOT_REPLACE:		return r_not_replace(partner, mem_ctx, rec, owner, replica);	case R_DO_PROPAGATE:		return r_do_propagate(partner, mem_ctx, rec, owner, replica);	case R_DO_CHALLENGE:		return r_do_challenge(partner, mem_ctx, rec, owner, replica);	case R_DO_RELEASE_DEMAND:		return r_do_release_demand(partner, mem_ctx, rec, owner, replica);	case R_DO_SGROUP_MERGE:		return r_do_sgroup_merge(partner, mem_ctx, rec, owner, replica);	}	return NT_STATUS_INTERNAL_ERROR;}NTSTATUS wreplsrv_apply_records(struct wreplsrv_partner *partner,				struct wrepl_wins_owner *owner,				uint32_t num_names, struct wrepl_name *names){	NTSTATUS status;	uint32_t i;	DEBUG(4,("apply records count[%u]:owner[%s]:min[%llu]:max[%llu]:partner[%s]\n",		num_names, owner->address,		(long long)owner->min_version, 		(long long)owner->max_version,		partner->address));	for (i=0; i < num_names; i++) {		TALLOC_CTX *tmp_mem = talloc_new(partner);		NT_STATUS_HAVE_NO_MEMORY(tmp_mem);		status = wreplsrv_apply_one_record(partner, tmp_mem,						   owner, &names[i]);		talloc_free(tmp_mem);		NT_STATUS_NOT_OK_RETURN(status);	}	status = wreplsrv_add_table(partner->service,				    partner->service,				    &partner->service->table,				    owner->address,				    owner->max_version);	NT_STATUS_NOT_OK_RETURN(status);	return NT_STATUS_OK;}

⌨️ 快捷键说明

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