/*
Unix SMB/CIFS implementation.
WINS Replication server
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include <tevent.h>
#include "samba/service_task.h"
#include "lib/messaging/irpc.h"
#include "librpc/gen_ndr/ndr_irpc_c.h"
#include "librpc/gen_ndr/ndr_winsrepl.h"
#include "wrepl_server/wrepl_server.h"
#include "nbt_server/wins/winsdb.h"
#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,
R_DO_REPLACE,
R_NOT_REPLACE,
R_DO_PROPAGATE,
R_DO_CHALLENGE,
R_DO_RELEASE_DEMAND,
R_DO_SGROUP_MERGE
};
static const char *_R_ACTION_enum_string(enum _R_ACTION action)
{
switch (action) {
case R_INVALID: return "INVALID";
case R_DO_REPLACE: return "REPLACE";
case R_NOT_REPLACE: return "NOT_REPLACE";
case R_DO_PROPAGATE: return "PROPAGATE";
case R_DO_CHALLENGE: return "CHALLEGNE";
case R_DO_RELEASE_DEMAND: return "RELEASE_DEMAND";
case R_DO_SGROUP_MERGE: return "SGROUP_MERGE";
}
return "enum _R_ACTION unknown";
}
#define R_IS_ACTIVE(r) ((r)->state == WREPL_STATE_ACTIVE)
#if 0 /* unused */
#define R_IS_RELEASED(r) ((r)->state == WREPL_STATE_RELEASED)
#endif
#define R_IS_TOMBSTONE(r) ((r)->state == WREPL_STATE_TOMBSTONE)
#define R_IS_UNIQUE(r) ((r)->type == WREPL_TYPE_UNIQUE)
#define R_IS_GROUP(r) ((r)->type == WREPL_TYPE_GROUP)
#define R_IS_SGROUP(r) ((r)->type == WREPL_TYPE_SGROUP)
#if 0 /* unused */
#define R_IS_MHOMED(r) ((r)->type == WREPL_TYPE_MHOMED)
#endif
/* blindly overwrite records from the same owner in all cases */
static enum _R_ACTION replace_same_owner(struct winsdb_record *r1, struct wrepl_name *r2)
{
/* REPLACE */
return R_DO_REPLACE;
}
static bool r_1_is_subset_of_2_address_list(struct winsdb_record *r1, struct wrepl_name *r2, bool check_owners)
{
uint32_t i,j;
size_t len = winsdb_addr_list_length(r1->addresses);
for (i=0; i < len; i++) {
bool found = false;
for (j=0; j < r2->num_addresses; j++) {
if (strcmp(r1->addresses[i]->address, r2->addresses[j].address) != 0) {
continue;
}
if (check_owners && strcmp(r1->addresses[i]->wins_owner, r2->addresses[j].owner) != 0) {
return false;
}
found = true;
break;
}
if (!found) return false;
}
return true;
}
static bool r_1_is_superset_of_2_address_list(struct winsdb_record *r1, struct wrepl_name *r2, bool check_owners)
{
uint32_t i,j;
size_t len = winsdb_addr_list_length(r1->addresses);
for (i=0; i < r2->num_addresses; i++) {
bool found = false;
for (j=0; j < len; j++) {
if (strcmp(r2->addresses[i].address, r1->addresses[j]->address) != 0) {
continue;
}
if (check_owners && strcmp(r2->addresses[i].owner, r1->addresses[j]->wins_owner) != 0) {
return false;
}
found = true;
break;
}
if (!found) return false;
}
return true;
}
static bool r_1_is_same_as_2_address_list(struct winsdb_record *r1, struct wrepl_name *r2, bool check_owners)
{
size_t len = winsdb_addr_list_length(r1->addresses);
if (len != r2->num_addresses) {
return false;
}
return r_1_is_superset_of_2_address_list(r1, r2, check_owners);
}
static bool r_contains_addrs_from_owner(struct winsdb_record *r1, const char *owner)
{
uint32_t i;
size_t len = winsdb_addr_list_length(r1->addresses);
for (i=0; i < len; i++) {
if (strcmp(r1->addresses[i]->wins_owner, owner) == 0) {
return true;
}
}
return false;
}
/*
UNIQUE,ACTIVE vs. UNIQUE,ACTIVE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. UNIQUE,TOMBSTONE with different ip(s) => NOT REPLACE
UNIQUE,RELEASED vs. UNIQUE,ACTIVE with different ip(s) => REPLACE
UNIQUE,RELEASED vs. UNIQUE,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. UNIQUE,ACTIVE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. UNIQUE,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. GROUP,ACTIVE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. GROUP,TOMBSTONE with same ip(s) => NOT REPLACE
UNIQUE,RELEASED vs. GROUP,ACTIVE with different ip(s) => REPLACE
UNIQUE,RELEASED vs. GROUP,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. GROUP,ACTIVE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. GROUP,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. SGROUP,ACTIVE with same ip(s) => NOT REPLACE
UNIQUE,ACTIVE vs. SGROUP,TOMBSTONE with same ip(s) => NOT REPLACE
UNIQUE,RELEASED vs. SGROUP,ACTIVE with different ip(s) => REPLACE
UNIQUE,RELEASED vs. SGROUP,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. SGROUP,ACTIVE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. SGROUP,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. MHOMED,ACTIVE with different ip(s) => REPLACE
UNIQUE,ACTIVE vs. MHOMED,TOMBSTONE with same ip(s) => NOT REPLACE
UNIQUE,RELEASED vs. MHOMED,ACTIVE with different ip(s) => REPLACE
UNIQUE,RELEASED vs. MHOMED,TOMBSTONE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. MHOMED,ACTIVE with different ip(s) => REPLACE
UNIQUE,TOMBSTONE vs. MHOMED,TOMBSTONE with different ip(s) => REPLACE
*/
static enum _R_ACTION replace_unique_replica_vs_X_replica(struct winsdb_record *r1, struct wrepl_name *r2)
{
if (!R_IS_ACTIVE(r1)) {
/* REPLACE */
return R_DO_REPLACE;
}
if (!R_IS_SGROUP(r2) && R_IS_ACTIVE(r2)) {
/* REPLACE */
return R_DO_REPLACE;
}
/* NOT REPLACE */
return R_NOT_REPLACE;
}
/*
GROUP,ACTIVE vs. UNIQUE,ACTIVE with same ip(s) => NOT REPLACE
GROUP,ACTIVE vs. UNIQUE,TOMBSTONE with same ip(s) => NOT REPLACE
GROUP,RELEASED vs. UNIQUE,ACTIVE with same ip(s) => NOT REPLACE
GROUP,RELEASED vs. UNIQUE,TOMBSTONE with same ip(s) => NOT REPLACE
GROUP,TOMBSTONE vs. UNIQUE,ACTIVE with same ip(s) => NOT REPLACE
GROUP,TOMBSTONE vs. UNIQUE,TOMBSTONE with same ip(s) => NOT REPLACE
GROUP,ACTIVE vs. GROUP,ACTIVE with same ip(s) => NOT REPLACE
GROUP,ACTIVE vs. GROUP,TOMBSTONE with same ip(s) => NOT REPLACE
GROUP,RELEASED vs. GROUP,ACTIVE with different ip(s) => REPLACE
GROUP,RELEASED vs. GROUP,TOMBSTONE with different ip(s) => REPLACE
GROUP,TOMBSTONE vs. GROUP,ACTIVE with different ip(s) => REPLACE
GROUP,TOMBSTONE vs. GROUP,TOMBSTONE with different ip(s) => REPLACE
GROUP,ACTIVE vs. SGROUP,ACTIVE with same ip(s) => NOT REPLACE
GROUP,ACTIVE vs. SGROUP,TOMBSTONE with same ip(s) => NOT REPLACE
GROUP,RELEASED vs. SGROUP,ACTIVE with different ip(s) => REPLACE
GROUP,RELEASED vs. SGROUP,TOMBSTONE with same ip(s) => NOT REP
|