#include "libcli/wrepl/winsrepl.h"
#include "system/time.h"
#include "librpc/gen_ndr/ndr_nbt.h"
+#include "param/param.h"
enum _R_ACTION {
R_INVALID,
static void r_do_late_release_demand_handler(struct irpc_request *ireq)
{
NTSTATUS status;
- struct r_do_challenge_state *state = talloc_get_type(ireq->async.private,
+ struct r_do_challenge_state *state = talloc_get_type(ireq->async.private_data,
struct r_do_challenge_state);
status = irpc_call_recv(ireq);
NT_STATUS_HAVE_NO_MEMORY(ireq);
ireq->async.fn = r_do_late_release_demand_handler;
- ireq->async.private = state;
+ ireq->async.private_data= state;
return NT_STATUS_OK;
}
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 *state = talloc_get_type(ireq->async.private_data,
struct r_do_challenge_state);
bool old_is_subset = false;
bool new_is_subset = false;
NT_STATUS_HAVE_NO_MEMORY(ireq);
ireq->async.fn = r_do_challenge_handler;
- ireq->async.private = state;
+ ireq->async.private_data= state;
talloc_steal(partner, state);
return NT_STATUS_OK;
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 *state = talloc_get_type(ireq->async.private_data,
struct r_do_release_demand_state);
status = irpc_call_recv(ireq);
NT_STATUS_HAVE_NO_MEMORY(ireq);
ireq->async.fn = r_do_release_demand_handler;
- ireq->async.private = state;
+ ireq->async.private_data= state;
talloc_steal(partner, state);
return NT_STATUS_OK;
uint8_t ret;
size_t len;
bool changed_old_addrs = false;
+ bool skip_replica_owned_by_us = false;
bool become_owner = true;
+ bool propagate = lpcfg_parm_bool(partner->service->task->lp_ctx, NULL, "wreplsrv", "propagate name releases", false);
const char *local_owner = partner->service->wins_db->local_owner;
merge = talloc(mem_ctx, struct winsdb_record);
}
for (i=0; i < replica->num_addresses; i++) {
+ if (propagate &&
+ strcmp(replica->addresses[i].owner, local_owner) == 0) {
+ const struct winsdb_addr *a;
+
+ /*
+ * NOTE: this is different to the windows behavior
+ * and off by default, but it better propagated
+ * name releases
+ */
+ a = winsdb_addr_list_check(merge->addresses,
+ replica->addresses[i].address);
+ if (!a) {
+ /* don't add addresses owned by us */
+ skip_replica_owned_by_us = true;
+ }
+ continue;
+ }
merge->addresses = winsdb_addr_list_add(partner->service->wins_db,
merge, merge->addresses,
replica->addresses[i].address,
become_owner = false;
}
+ /*
+ * when we notice another server believes an address
+ * is owned by us and that's not the case
+ * we propagate the result
+ */
+ if (skip_replica_owned_by_us) {
+ become_owner = true;
+ }
+
/* if we're the owner of the old record, we'll be the owner of the new one too */
if (strcmp(rec->wins_owner, local_owner)==0) {
become_owner = true;
* will be owner of the merge result, otherwise we take the ownership
*/
if (become_owner) {
+ time_t lh = 0;
+
modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
+
+ /*
+ * if we're the owner, the expire time becomes the highest
+ * expire time of owned addresses
+ */
+ len = winsdb_addr_list_length(merge->addresses);
+
+ for (i=0; i < len; i++) {
+ if (strcmp(merge->addresses[i]->wins_owner, local_owner)==0) {
+ lh = MAX(lh, merge->addresses[i]->expire_time);
+ }
+ }
+
+ if (lh != 0) {
+ merge->expire_time = lh;
+ }
}
ret = winsdb_modify(partner->service->wins_db, merge, modify_flags);
bool replica_vs_replica = false;
bool local_vs_replica = false;
+ if (replica->name.scope) {
+ TALLOC_CTX *parent;
+ const char *scope;
+
+ /*
+ * Windows 2008 truncates the scope to 237 bytes,
+ * so we do...
+ */
+ parent = talloc_parent(replica->name.scope);
+ scope = talloc_strndup(parent, replica->name.scope, 237);
+ NT_STATUS_HAVE_NO_MEMORY(scope);
+ replica->name.scope = scope;
+ }
+
status = winsdb_lookup(partner->service->wins_db,
&replica->name, mem_ctx, &rec);
if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {