📄 wrepl_in_call.c
字号:
* * 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 + -