mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
r13060: - return only active addresses in name query responses
- replicate only active addresses
metze
(This used to be commit 6325abd95c
)
This commit is contained in:
parent
b19ca85e97
commit
f25ad21617
@ -446,6 +446,7 @@ NTSTATUS winsdb_lookup(struct winsdb_handle *h,
|
||||
struct winsdb_record *rec;
|
||||
struct ldb_context *wins_db = h->ldb;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* find the record in the WINS database */
|
||||
ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, name), LDB_SCOPE_BASE,
|
||||
@ -461,17 +462,9 @@ NTSTATUS winsdb_lookup(struct winsdb_handle *h,
|
||||
|
||||
talloc_steal(tmp_ctx, res);
|
||||
|
||||
status = winsdb_record(h, res->msgs[0], tmp_ctx, &rec);
|
||||
status = winsdb_record(h, res->msgs[0], tmp_ctx, now, &rec);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
/* see if it has already expired */
|
||||
if (rec->state == WREPL_STATE_ACTIVE &&
|
||||
rec->expire_time <= time(NULL)) {
|
||||
DEBUG(5,("WINS: expiring name %s (expired at %s)\n",
|
||||
nbt_name_string(tmp_ctx, rec->name), timestring(tmp_ctx, rec->expire_time)));
|
||||
rec->state = WREPL_STATE_RELEASED;
|
||||
}
|
||||
|
||||
talloc_steal(mem_ctx, rec);
|
||||
talloc_free(tmp_ctx);
|
||||
*_rec = rec;
|
||||
@ -482,13 +475,13 @@ failed:
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct winsdb_record **_rec)
|
||||
NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_CTX *mem_ctx, time_t now, struct winsdb_record **_rec)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct winsdb_record *rec;
|
||||
struct ldb_message_element *el;
|
||||
struct nbt_name *name;
|
||||
uint32_t i, num_values;
|
||||
uint32_t i, j, num_values;
|
||||
|
||||
rec = talloc(mem_ctx, struct winsdb_record);
|
||||
if (rec == NULL) {
|
||||
@ -549,17 +542,43 @@ NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* see if it has already expired */
|
||||
if (!rec->is_static &&
|
||||
rec->expire_time <= now &&
|
||||
rec->state == WREPL_STATE_ACTIVE) {
|
||||
DEBUG(5,("WINS: expiring name %s (expired at %s)\n",
|
||||
nbt_name_string(mem_ctx, rec->name), timestring(mem_ctx, rec->expire_time)));
|
||||
rec->state = WREPL_STATE_RELEASED;
|
||||
}
|
||||
|
||||
rec->addresses = talloc_array(rec, struct winsdb_addr *, num_values+1);
|
||||
if (rec->addresses == NULL) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i=0;i<num_values;i++) {
|
||||
status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[i]);
|
||||
for (i=0,j=0;i<num_values;i++) {
|
||||
status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[j]);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
/*
|
||||
* the record isn't static and is active
|
||||
* then don't add the address if it's expired
|
||||
*/
|
||||
if (!rec->is_static &&
|
||||
rec->addresses[j]->expire_time <= now &&
|
||||
rec->state == WREPL_STATE_ACTIVE) {
|
||||
DEBUG(5,("WINS: expiring name addr %s of %s (expired at %s)\n",
|
||||
rec->addresses[j]->address, nbt_name_string(rec->addresses[j], rec->name),
|
||||
timestring(rec->addresses[j], rec->addresses[j]->expire_time)));
|
||||
talloc_free(rec->addresses[j]);
|
||||
rec->addresses[j] = NULL;
|
||||
continue;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
rec->addresses[i] = NULL;
|
||||
rec->addresses[j] = NULL;
|
||||
num_values = j;
|
||||
|
||||
if (rec->is_static && rec->state == WREPL_STATE_ACTIVE) {
|
||||
rec->expire_time = get_time_t_max();
|
||||
@ -568,6 +587,14 @@ NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_
|
||||
}
|
||||
}
|
||||
|
||||
if (rec->state == WREPL_STATE_ACTIVE) {
|
||||
if (num_values < 1) {
|
||||
DEBUG(5,("WINS: expiring name %s (because it has no active addresses)\n",
|
||||
nbt_name_string(mem_ctx, rec->name)));
|
||||
rec->state = WREPL_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
*_rec = rec;
|
||||
return NT_STATUS_OK;
|
||||
failed:
|
||||
|
@ -492,7 +492,6 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
|
||||
/*
|
||||
* if the registration is for an address that is currently active, then
|
||||
* just update the expiry time of the record and the address
|
||||
* TODO: is this correct?
|
||||
*/
|
||||
winsdb_addr = winsdb_addr_list_check(rec->addresses, address);
|
||||
if (winsdb_addr) {
|
||||
@ -525,9 +524,7 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
|
||||
|
||||
/*
|
||||
* if the registration is for an address that is currently active, then
|
||||
* just update the expiry time
|
||||
* just update the expiry time of the record and the address
|
||||
* TODO: is this correct?
|
||||
*/
|
||||
winsdb_addr = winsdb_addr_list_check(rec->addresses, address);
|
||||
if (winsdb_addr) {
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "nbt_server/wins/winsdb.h"
|
||||
#include "lib/ldb/include/ldb.h"
|
||||
#include "lib/ldb/include/ldb_errors.h"
|
||||
#include "system/time.h"
|
||||
|
||||
static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call)
|
||||
{
|
||||
@ -178,7 +179,8 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call)
|
||||
struct wrepl_wins_name *names;
|
||||
struct winsdb_record *rec;
|
||||
NTSTATUS status;
|
||||
uint32_t i;
|
||||
uint32_t i, j;
|
||||
time_t now = time(NULL);
|
||||
|
||||
owner = wreplsrv_find_owner(service, service->table, owner_in->address);
|
||||
|
||||
@ -258,26 +260,37 @@ static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call)
|
||||
names = talloc_array(call, struct wrepl_wins_name, res->count);
|
||||
NT_STATUS_HAVE_NO_MEMORY(names);
|
||||
|
||||
for (i = 0; i < res->count; i++) {
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], call, &rec);
|
||||
for (i=0, j=0; i < res->count; i++) {
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], call, now, &rec);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
status = wreplsrv_record2wins_name(names, &names[i], rec);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
/*
|
||||
* it's possible that winsdb_record() made the record RELEASED
|
||||
* because it's expired, but in the database it's still stored
|
||||
* as ACTIVE...
|
||||
*
|
||||
* 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, res->count, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name);
|
||||
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",
|
||||
res->count, owner_in->address,
|
||||
j, owner_in->address,
|
||||
(long long)owner_in->min_version,
|
||||
(long long)owner_in->max_version,
|
||||
call->wreplconn->partner->address));
|
||||
|
||||
reply_out->num_names = res->count;
|
||||
reply_out->num_names = j;
|
||||
reply_out->names = names;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
@ -84,7 +84,11 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi
|
||||
delete_tombstones = timeval_expired(&tombstone_extra_time);
|
||||
|
||||
for (i=0; i < res->count; i++) {
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
|
||||
/*
|
||||
* we pass '0' as 'now' here,
|
||||
* because we want to get the raw timestamps which are in the DB
|
||||
*/
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
talloc_free(res->msgs[i]);
|
||||
|
||||
@ -198,7 +202,11 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s
|
||||
delete_tombstones = timeval_expired(&tombstone_extra_time);
|
||||
|
||||
for (i=0; i < res->count; i++) {
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
|
||||
/*
|
||||
* we pass '0' as 'now' here,
|
||||
* because we want to get the raw timestamps which are in the DB
|
||||
*/
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
talloc_free(res->msgs[i]);
|
||||
|
||||
@ -390,7 +398,11 @@ static NTSTATUS wreplsrv_scavenging_replica_active_records(struct wreplsrv_servi
|
||||
DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));
|
||||
|
||||
for (i=0; i < res->count; i++) {
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
|
||||
/*
|
||||
* we pass '0' as 'now' here,
|
||||
* because we want to get the raw timestamps which are in the DB
|
||||
*/
|
||||
status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
talloc_free(res->msgs[i]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user