summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/wrepl_server/wrepl_apply_records.c119
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;
}