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

📄 wrepl_in_call.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		 *		 * make sure we really only replicate ACTIVE and TOMBSTONE records		 */		if (rec->state == WREPL_STATE_ACTIVE || rec->state == WREPL_STATE_TOMBSTONE) {			status = wreplsrv_record2wins_name(names, &names[j], rec);			NT_STATUS_NOT_OK_RETURN(status);			j++;		}		talloc_free(rec);		talloc_free(res->msgs[i]);	}	/* sort the names before we send them */	qsort(names, j, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name);	DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n",		j, owner_in->address, 		(long long)owner_in->min_version, 		(long long)owner_in->max_version,		call->wreplconn->partner->address));	reply_out->num_names	= j;	reply_out->names	= names;	return NT_STATUS_OK;}struct wreplsrv_in_update_state {	struct wreplsrv_in_connection *wrepl_in;	struct wreplsrv_out_connection *wrepl_out;	struct composite_context *creq;	struct wreplsrv_pull_cycle_io cycle_io;};static void wreplsrv_in_update_handler(struct composite_context *creq){	struct wreplsrv_in_update_state *update_state = talloc_get_type(creq->async.private_data,							struct wreplsrv_in_update_state);	NTSTATUS status;	status = wreplsrv_pull_cycle_recv(creq);	talloc_free(update_state->wrepl_out);	wreplsrv_terminate_in_connection(update_state->wrepl_in, nt_errstr(status));}static NTSTATUS wreplsrv_in_update(struct wreplsrv_in_call *call){	struct wreplsrv_in_connection *wrepl_in = call->wreplconn;	struct wreplsrv_out_connection *wrepl_out;	struct wrepl_table *update_in = &call->req_packet.message.replication.info.table;	struct wreplsrv_in_update_state *update_state;	uint16_t fde_flags;	DEBUG(2,("WREPL_REPL_UPDATE: partner[%s] initiator[%s] num_owners[%u]\n",		call->wreplconn->partner->address,		update_in->initiator, update_in->partner_count));	/* 	 * we need to flip the connection into a client connection	 * and do a WREPL_REPL_SEND_REQUEST's on the that connection	 * and then stop this connection	 */	fde_flags = event_get_fd_flags(wrepl_in->conn->event.fde);	talloc_free(wrepl_in->conn->event.fde);	wrepl_in->conn->event.fde = NULL;	update_state = talloc(wrepl_in, struct wreplsrv_in_update_state);	NT_STATUS_HAVE_NO_MEMORY(update_state);	wrepl_out = talloc(update_state, struct wreplsrv_out_connection);	NT_STATUS_HAVE_NO_MEMORY(wrepl_out);	wrepl_out->service		= wrepl_in->service;	wrepl_out->partner		= wrepl_in->partner;	wrepl_out->assoc_ctx.our_ctx	= wrepl_in->assoc_ctx.our_ctx;	wrepl_out->assoc_ctx.peer_ctx	= wrepl_in->assoc_ctx.peer_ctx;	wrepl_out->sock			= wrepl_socket_merge(wrepl_out,							     wrepl_in->conn->event.ctx,							     wrepl_in->conn->socket,							     wrepl_in->packet);	NT_STATUS_HAVE_NO_MEMORY(wrepl_out->sock);	event_set_fd_flags(wrepl_out->sock->event.fde, fde_flags);	update_state->wrepl_in			= wrepl_in;	update_state->wrepl_out			= wrepl_out;	update_state->cycle_io.in.partner	= wrepl_out->partner;	update_state->cycle_io.in.num_owners	= update_in->partner_count;	update_state->cycle_io.in.owners	= update_in->partners;	talloc_steal(update_state, update_in->partners);	update_state->cycle_io.in.wreplconn	= wrepl_out;	update_state->creq = wreplsrv_pull_cycle_send(update_state, &update_state->cycle_io);	if (!update_state->creq) {		return NT_STATUS_INTERNAL_ERROR;	}	update_state->creq->async.fn		= wreplsrv_in_update_handler;	update_state->creq->async.private_data	= update_state;	return ERROR_INVALID_PARAMETER;}static NTSTATUS wreplsrv_in_update2(struct wreplsrv_in_call *call){	return wreplsrv_in_update(call);}static NTSTATUS wreplsrv_in_inform(struct wreplsrv_in_call *call){	struct wrepl_table *inform_in = &call->req_packet.message.replication.info.table;	DEBUG(2,("WREPL_REPL_INFORM: partner[%s] initiator[%s] num_owners[%u]\n",		call->wreplconn->partner->address,		inform_in->initiator, inform_in->partner_count));	wreplsrv_out_partner_pull(call->wreplconn->partner, inform_in);	/* we don't reply to WREPL_REPL_INFORM messages */	return ERROR_INVALID_PARAMETER;}static NTSTATUS wreplsrv_in_inform2(struct wreplsrv_in_call *call){	return wreplsrv_in_inform(call);}static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call){	struct wrepl_replication *repl_in = &call->req_packet.message.replication;	NTSTATUS status;	/*	 * w2k only check the assoc_ctx if the opcode has the 0x00007800 bits are set	 */	if (call->req_packet.opcode & WREPL_OPCODE_BITS) {		/*		 *if the assoc_ctx doesn't match ignore the packet		 */		if (call->req_packet.assoc_ctx != call->wreplconn->assoc_ctx.our_ctx) {			return ERROR_INVALID_PARAMETER;		}	}	if (!call->wreplconn->partner) {		struct socket_address *partner_ip = socket_get_peer_addr(call->wreplconn->conn->socket, call);		call->wreplconn->partner = wreplsrv_find_partner(call->wreplconn->service, partner_ip->addr);		if (!call->wreplconn->partner) {			DEBUG(1,("Failing WINS replication from non-partner %s\n",				 partner_ip ? partner_ip->addr : NULL));			return wreplsrv_in_stop_assoc_ctx(call);		}	}	switch (repl_in->command) {		case WREPL_REPL_TABLE_QUERY:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) {				DEBUG(2,("Failing WINS replication TABLE_QUERY from non-push-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_table_query(call);			break;		case WREPL_REPL_TABLE_REPLY:			return ERROR_INVALID_PARAMETER;		case WREPL_REPL_SEND_REQUEST:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PUSH)) {				DEBUG(2,("Failing WINS replication SEND_REQUESET from non-push-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_send_request(call);			break;		case WREPL_REPL_SEND_REPLY:			return ERROR_INVALID_PARAMETER;			case WREPL_REPL_UPDATE:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) {				DEBUG(2,("Failing WINS replication UPDATE from non-pull-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_update(call);			break;		case WREPL_REPL_UPDATE2:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) {				DEBUG(2,("Failing WINS replication UPDATE2 from non-pull-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_update2(call);			break;		case WREPL_REPL_INFORM:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) {				DEBUG(2,("Failing WINS replication INFORM from non-pull-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_inform(call);			break;		case WREPL_REPL_INFORM2:			if (!(call->wreplconn->partner->type & WINSREPL_PARTNER_PULL)) {				DEBUG(2,("Failing WINS replication INFORM2 from non-pull-partner %s\n",					 call->wreplconn->partner->address));				return wreplsrv_in_stop_assoc_ctx(call);			}			status = wreplsrv_in_inform2(call);			break;		default:			return ERROR_INVALID_PARAMETER;	}	if (NT_STATUS_IS_OK(status)) {		call->rep_packet.mess_type = WREPL_REPLICATION;	}	return status;}static NTSTATUS wreplsrv_in_invalid_assoc_ctx(struct wreplsrv_in_call *call){	struct wrepl_start *start	= &call->rep_packet.message.start;	call->rep_packet.opcode		= 0x00008583;	call->rep_packet.assoc_ctx	= 0;	call->rep_packet.mess_type	= WREPL_START_ASSOCIATION;	start->assoc_ctx		= 0x0000000a;	start->minor_version		= 0x0001;	start->major_version		= 0x0000;	call->rep_packet.padding	= data_blob_talloc(call, NULL, 4);	memset(call->rep_packet.padding.data, '\0', call->rep_packet.padding.length);	return NT_STATUS_OK;}NTSTATUS wreplsrv_in_call(struct wreplsrv_in_call *call){	NTSTATUS status;	if (!(call->req_packet.opcode & WREPL_OPCODE_BITS)	    && (call->wreplconn->assoc_ctx.our_ctx == WREPLSRV_INVALID_ASSOC_CTX)) {		return wreplsrv_in_invalid_assoc_ctx(call);	}	switch (call->req_packet.mess_type) {		case WREPL_START_ASSOCIATION:			status = wreplsrv_in_start_association(call);			break;		case WREPL_START_ASSOCIATION_REPLY:			/* this is not valid here, so we ignore it */			return ERROR_INVALID_PARAMETER;		case WREPL_STOP_ASSOCIATION:			status = wreplsrv_in_stop_association(call);			break;		case WREPL_REPLICATION:			status = wreplsrv_in_replication(call);			break;		default:			/* everythingelse is also not valid here, so we ignore it */			return ERROR_INVALID_PARAMETER;	}	if (call->wreplconn->assoc_ctx.our_ctx == WREPLSRV_INVALID_ASSOC_CTX) {		return wreplsrv_in_invalid_assoc_ctx(call);	}	if (NT_STATUS_IS_OK(status)) {		/* let the backend to set some of the opcode bits, but always add the standards */		call->rep_packet.opcode		|= WREPL_OPCODE_BITS;		call->rep_packet.assoc_ctx	= call->wreplconn->assoc_ctx.peer_ctx;	}	return status;}

⌨️ 快捷键说明

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