winsserver: add "wreplsrv:propagate name releases" option
authorStefan Metzmacher <metze@sernet.de>
Tue, 25 Mar 2008 16:35:33 +0000 (17:35 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 19 Jan 2009 06:05:52 +0000 (07:05 +0100)
Add an option to propagate name releases directly.
This make the results for #1C name queries more consistent
among all servers.

It's off by default to match windows.

metze
(from samba4wins tree 166e9fdffb9f4e26513c3b4ec1f6f168ecbe18f8)

source4/nbt_server/wins/winsserver.c
source4/wrepl_server/wrepl_scavenging.c

index 464bf804a7000f8b6987a206c64b7a721974dad4..798e9c743ac6ccfbbfc8b0648b306259c71faf3e 100644 (file)
@@ -950,6 +950,13 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
                if (strcmp(rec->wins_owner, winssrv->wins_db->local_owner) != 0) {
                        modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
                }
                if (strcmp(rec->wins_owner, winssrv->wins_db->local_owner) != 0) {
                        modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
                }
+               if (lp_parm_bool(iface->nbtsrv->task->lp_ctx, NULL, "wreplsrv", "propagate name releases", false)) {
+                       /*
+                        * We have an option to propagate every name release,
+                        * this is off by default to match windows servers
+                        */
+                       modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
+               }
        } else if (rec->state == WREPL_STATE_RELEASED) {
                /*
                 * if we're not the owner, we need to take the owner ship
        } else if (rec->state == WREPL_STATE_RELEASED) {
                /*
                 * if we're not the owner, we need to take the owner ship
index a1edd9e8ce3d184cfd31497396e3287b577e5170..9f6a49ef09da0c3991d42f991fb97302bebff423 100644 (file)
@@ -30,6 +30,7 @@
 #include "lib/messaging/irpc.h"
 #include "librpc/gen_ndr/ndr_irpc.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
 #include "lib/messaging/irpc.h"
 #include "librpc/gen_ndr/ndr_irpc.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
+#include "param/param.h"
 
 const char *wreplsrv_owner_filter(struct wreplsrv_service *service,
                                  TALLOC_CTX *mem_ctx,
 
 const char *wreplsrv_owner_filter(struct wreplsrv_service *service,
                                  TALLOC_CTX *mem_ctx,
@@ -63,11 +64,12 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi
        bool delete_record;
        bool delete_tombstones;
        struct timeval tombstone_extra_time;
        bool delete_record;
        bool delete_tombstones;
        struct timeval tombstone_extra_time;
+       const char *local_owner = service->wins_db->local_owner;
+       bool propagate = lp_parm_bool(service->task->lp_ctx, NULL, "wreplsrv", "propagate name releases", false);
 
        now_timestr = ldb_timestring(tmp_mem, now);
        NT_STATUS_HAVE_NO_MEMORY(now_timestr);
 
        now_timestr = ldb_timestring(tmp_mem, now);
        NT_STATUS_HAVE_NO_MEMORY(now_timestr);
-       owner_filter = wreplsrv_owner_filter(service, tmp_mem,
-                                            service->wins_db->local_owner);
+       owner_filter = wreplsrv_owner_filter(service, tmp_mem, local_owner);
        NT_STATUS_HAVE_NO_MEMORY(owner_filter);
        filter = talloc_asprintf(tmp_mem,
                                 "(&%s(objectClass=winsRecord)"
        NT_STATUS_HAVE_NO_MEMORY(owner_filter);
        filter = talloc_asprintf(tmp_mem,
                                 "(&%s(objectClass=winsRecord)"
@@ -84,6 +86,8 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi
        delete_tombstones = timeval_expired(&tombstone_extra_time);
 
        for (i=0; i < res->count; i++) {
        delete_tombstones = timeval_expired(&tombstone_extra_time);
 
        for (i=0; i < res->count; i++) {
+               bool has_replicas = false;
+
                /*
                 * we pass '0' as 'now' here,
                 * because we want to get the raw timestamps which are in the DB
                /*
                 * we pass '0' as 'now' here,
                 * because we want to get the raw timestamps which are in the DB
@@ -110,10 +114,40 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi
                                modify_record   = true;
                                break;
                        }
                                modify_record   = true;
                                break;
                        }
-                       new_state       = "released";
-                       rec->state      = WREPL_STATE_RELEASED;
-                       rec->expire_time= service->config.tombstone_interval + now;
-                       modify_flags    = 0;
+                       if (rec->type != WREPL_TYPE_SGROUP || !propagate) {
+                               new_state       = "released";
+                               rec->state      = WREPL_STATE_RELEASED;
+                               rec->expire_time= service->config.tombstone_interval + now;
+                               modify_flags    = 0;
+                               modify_record   = true;
+                               break;
+                       }
+                       /* check if there's any replica address */
+                       for (i=0;rec->addresses[i];i++) {
+                               if (strcmp(rec->addresses[i]->wins_owner, local_owner) != 0) {
+                                       has_replicas = true;
+                                       rec->addresses[i]->expire_time= service->config.renew_interval + now;
+                               }
+                       }
+                       if (has_replicas) {
+                               /* if it has replica addresses propagate them */
+                               new_state       = "active(propagated)";
+                               rec->state      = WREPL_STATE_ACTIVE;
+                               rec->expire_time= service->config.renew_interval + now;
+                               modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
+                               modify_record   = true;
+                               break;
+                       }
+                       /*
+                        * if it doesn't have replica addresses, make it a tombstone,
+                        * so that the released owned addresses are propagated
+                        */
+                       new_state       = "tombstone";
+                       rec->state      = WREPL_STATE_TOMBSTONE;
+                       rec->expire_time= time(NULL) +
+                                         service->config.tombstone_interval +
+                                         service->config.tombstone_timeout;
+                       modify_flags    = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;
                        modify_record   = true;
                        break;
 
                        modify_record   = true;
                        break;