diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/wrepl_server/wrepl_apply_records.c | 119 |
1 files changed, 115 insertions, 4 deletions
diff --git a/source4/wrepl_server/wrepl_apply_records.c b/source4/wrepl_server/wrepl_apply_records.c index 4b7eb24cab..36464db84a 100644 --- a/source4/wrepl_server/wrepl_apply_records.c +++ b/source4/wrepl_server/wrepl_apply_records.c @@ -27,6 +27,7 @@ #include "smbd/service_task.h" #include "smbd/service_stream.h" #include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_irpc.h" #include "librpc/gen_ndr/ndr_winsrepl.h" #include "wrepl_server/wrepl_server.h" #include "wrepl_server/wrepl_out_helpers.h" @@ -728,18 +729,99 @@ static NTSTATUS r_not_replace(struct wreplsrv_partner *partner, return NT_STATUS_OK; } +struct r_do_challenge_state { + struct messaging_context *msg_ctx; + struct wreplsrv_partner *partner; + struct winsdb_record *rec; + struct wrepl_wins_owner owner; + struct wrepl_name replica; + struct nbtd_proxy_wins_challenge r; +}; + +static void r_do_challenge_handler(struct irpc_request *ireq) +{ + NTSTATUS status; + struct r_do_challenge_state *state = talloc_get_type(ireq->async.private, + struct r_do_challenge_state); + + 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); + return; + } + + DEBUG(0,("TODO: r_do_challenge_handler: do MHOMED merging for %s: %s\n", + nbt_name_string(state, &state->replica.name), nt_errstr(status))); + /* TODO: handle MHOMED merging */ +} + 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) { - /* TODO: !!! */ - DEBUG(0,("TODO: challenge record %s\n", + struct irpc_request *ireq; + struct r_do_challenge_state *state; + uint32_t *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, "nbt_server"); + if ((nbt_servers == NULL) || (nbt_servers[0] == 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; } +static void r_do_release_demand_handler(struct irpc_request *ireq) +{ + NTSTATUS status; + status = irpc_call_recv(ireq); + /* don't care about the result */ +} + static NTSTATUS r_do_release_demand(struct wreplsrv_partner *partner, TALLOC_CTX *mem_ctx, struct winsdb_record *rec, @@ -747,7 +829,12 @@ static NTSTATUS r_do_release_demand(struct wreplsrv_partner *partner, struct wrepl_name *replica) { NTSTATUS status; + struct irpc_request *ireq; + uint32_t *nbt_servers; + const char **addrs; struct winsdb_addr **addresses; + struct nbtd_proxy_wins_release_demand r; + uint32_t i; /* * we need to get a reference to the old addresses, @@ -759,9 +846,33 @@ static NTSTATUS r_do_release_demand(struct wreplsrv_partner *partner, status = r_do_replace(partner, mem_ctx, rec, owner, replica); NT_STATUS_NOT_OK_RETURN(status); - /* TODO: !!! */ - DEBUG(0,("TODO: send release demand for %s\n", + DEBUG(4,("release demand record %s\n", nbt_name_string(mem_ctx, &replica->name))); + + nbt_servers = irpc_servers_byname(partner->service->task->msg_ctx, "nbt_server"); + if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) { + return NT_STATUS_INTERNAL_ERROR; + } + + r.in.name = *rec->name; + r.in.num_addrs = winsdb_addr_list_length(addresses); + r.in.addrs = talloc_array(partner, struct nbtd_proxy_wins_addr, r.in.num_addrs); + NT_STATUS_HAVE_NO_MEMORY(r.in.addrs); + /* TODO: fix pidl to handle inline ipv4address arrays */ + addrs = winsdb_addr_string_list(r.in.addrs, addresses); + NT_STATUS_HAVE_NO_MEMORY(addrs); + for (i=0; i < r.in.num_addrs; i++) { + r.in.addrs[i].addr = addrs[i]; + } + + ireq = IRPC_CALL_SEND(partner->service->task->msg_ctx, nbt_servers[0], + irpc, NBTD_PROXY_WINS_RELEASE_DEMAND, + &r, partner); + NT_STATUS_HAVE_NO_MEMORY(ireq); + + ireq->async.fn = r_do_release_demand_handler; + ireq->async.private = NULL; + return NT_STATUS_OK; } |