r12434: implement database scavenging, the only missing part is the verifying of...
[samba.git] / source / wrepl_server / wrepl_server.c
index e49b5879dc475eb38489055cdb747e512551c0a1..ad1bca3e60c951ecfa32bb3fe89ef04ae40f7ad3 100644 (file)
 #include "wrepl_server/wrepl_server.h"
 #include "nbt_server/wins/winsdb.h"
 #include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+
+static struct ldb_context *wins_config_db_connect(TALLOC_CTX *mem_ctx)
+{
+       return ldb_wrap_connect(mem_ctx, private_path(mem_ctx, lp_wins_config_url()),
+                               system_session(mem_ctx), NULL, 0, NULL);
+}
 
 /*
   open winsdb
@@ -42,6 +49,33 @@ static NTSTATUS wreplsrv_open_winsdb(struct wreplsrv_service *service)
                return NT_STATUS_INTERNAL_DB_ERROR;
        }
 
+       service->config.ldb = wins_config_db_connect(service);
+       if (!service->config.ldb) {
+               return NT_STATUS_INTERNAL_DB_ERROR;
+       }
+
+       /* the default renew interval is 6 days */
+       service->config.renew_interval    = lp_parm_int(-1,"wreplsrv","renew_interval", 6*24*60*60);
+
+       /* the default tombstone (extinction) interval is 6 days */
+       service->config.tombstone_interval= lp_parm_int(-1,"wreplsrv","tombstone_interval", 6*24*60*60);
+
+       /* the default tombstone (extinction) timeout is 1 day */
+       service->config.tombstone_timeout = lp_parm_int(-1,"wreplsrv","tombstone_timeout", 1*24*60*60);
+
+       /* the default tombstone extra timeout is 3 days */
+       service->config.tombstone_extra_timeout = lp_parm_int(-1,"wreplsrv","tombstone_extra_timeout", 3*24*60*60);
+
+       /* the default verify interval is 24 days */
+       service->config.verify_interval   = lp_parm_int(-1,"wreplsrv","verify_interval", 24*24*60*60);
+
+       /* the default scavenging interval is 'renew_interval/2' */
+       service->config.scavenging_interval=lp_parm_int(-1,"wreplsrv","scavenging_interval",
+                                                       service->config.renew_interval/2);
+
+       /* the maximun interval to the next periodic processing event */
+       service->config.periodic_interval = lp_parm_int(-1,"wreplsrv","periodic_interval", 60);
+
        return NT_STATUS_OK;
 }
 
@@ -63,38 +97,37 @@ struct wreplsrv_partner *wreplsrv_find_partner(struct wreplsrv_service *service,
 */
 static NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service)
 {
-       struct ldb_message **res = NULL;
+       struct ldb_result *res = NULL;
        int ret;
        TALLOC_CTX *tmp_ctx = talloc_new(service);
        int i;
 
        /* find the record in the WINS database */
-       ret = ldb_search(service->wins_db, ldb_dn_explode(tmp_ctx, "CN=PARTNERS"), LDB_SCOPE_ONELEVEL,
+       ret = ldb_search(service->config.ldb, ldb_dn_explode(tmp_ctx, "CN=PARTNERS"), LDB_SCOPE_SUBTREE,
                         "(objectClass=wreplPartner)", NULL, &res);
-       if (res != NULL) {
-               talloc_steal(tmp_ctx, res);
-       }
-       if (ret < 0) goto failed;
-       if (ret == 0) goto done;
+       if (ret != LDB_SUCCESS) goto failed;
+       talloc_steal(tmp_ctx, res);
+       if (res->count == 0) goto done;
 
-       for (i=0; i < ret; i++) {
+       for (i=0; i < res->count; i++) {
                struct wreplsrv_partner *partner;
 
                partner = talloc_zero(service, struct wreplsrv_partner);
                if (partner == NULL) goto failed;
-               partner->service        = service;
 
-               partner->address                = ldb_msg_find_string(res[i], "address", NULL);
+               partner->service                = service;
+               partner->address                = ldb_msg_find_string(res->msgs[i], "address", NULL);
                if (!partner->address) goto failed;
-               partner->name                   = ldb_msg_find_string(res[i], "name", partner->address);
-               partner->type                   = ldb_msg_find_uint(res[i], "type", WINSREPL_PARTNER_BOTH);
-               partner->pull.interval          = ldb_msg_find_uint(res[i], "pullInterval",
+               partner->name                   = ldb_msg_find_string(res->msgs[i], "name", partner->address);
+               partner->type                   = ldb_msg_find_uint(res->msgs[i], "type", WINSREPL_PARTNER_BOTH);
+               partner->pull.interval          = ldb_msg_find_uint(res->msgs[i], "pullInterval",
                                                                    WINSREPL_DEFAULT_PULL_INTERVAL);
-               partner->pull.retry_interval    = ldb_msg_find_uint(res[i], "pullRetryInterval",
+               partner->pull.retry_interval    = ldb_msg_find_uint(res->msgs[i], "pullRetryInterval",
                                                                    WINSREPL_DEFAULT_PULL_RETRY_INTERVAL);
-               partner->our_address            = ldb_msg_find_string(res[i], "ourAddress", NULL);
-               partner->push.change_count      = ldb_msg_find_uint(res[i], "pushChangeCount",
+               partner->our_address            = ldb_msg_find_string(res->msgs[i], "ourAddress", NULL);
+               partner->push.change_count      = ldb_msg_find_uint(res->msgs[i], "pushChangeCount",
                                                                    WINSREPL_DEFAULT_PUSH_CHANGE_COUNT);
+               partner->push.use_inform        = ldb_msg_find_uint(res->msgs[i], "pushUseInform", False);
 
                talloc_steal(partner, partner->address);
                talloc_steal(partner, partner->name);
@@ -138,7 +171,7 @@ uint64_t wreplsrv_local_max_version(struct wreplsrv_service *service)
        int ret;
        struct ldb_context *ldb = service->wins_db;
        struct ldb_dn *dn;
-       struct ldb_message **res = NULL;
+       struct ldb_result *res = NULL;
        TALLOC_CTX *tmp_ctx = talloc_new(service);
        uint64_t maxVersion = 0;
 
@@ -148,14 +181,12 @@ uint64_t wreplsrv_local_max_version(struct wreplsrv_service *service)
        /* find the record in the WINS database */
        ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, 
                         NULL, NULL, &res);
-       if (res != NULL) {
-               talloc_steal(tmp_ctx, res);
-       }
-       if (ret < 0) goto failed;
-       if (ret > 1) goto failed;
+       if (ret != LDB_SUCCESS) goto failed;
+       talloc_steal(tmp_ctx, res);
+       if (res->count > 1) goto failed;
 
-       if (ret == 1) {
-               maxVersion = ldb_msg_find_uint64(res[0], "maxVersion", 0);
+       if (res->count == 1) {
+               maxVersion = ldb_msg_find_uint64(res->msgs[0], "maxVersion", 0);
        }
 
 failed:
@@ -268,7 +299,7 @@ NTSTATUS wreplsrv_add_table(struct wreplsrv_service *service,
 */
 static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service)
 {
-       struct ldb_message **res = NULL;
+       struct ldb_result *res = NULL;
        int ret;
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx = talloc_new(service);
@@ -284,16 +315,14 @@ static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service)
        /* find the record in the WINS database */
        ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE,
                         "(objectClass=winsRecord)", attrs, &res);
-       if (res != NULL) {
-               talloc_steal(tmp_ctx, res);
-       }
        status = NT_STATUS_INTERNAL_DB_CORRUPTION;
-       if (ret < 0) goto failed;
-       if (ret == 0) goto done;
+       if (ret != LDB_SUCCESS) goto failed;
+       talloc_steal(tmp_ctx, res);
+       if (res->count == 0) goto done;
 
-       for (i=0; i < ret; i++) {
-               wins_owner     = ldb_msg_find_string(res[i], "winsOwner", NULL);
-               version        = ldb_msg_find_uint64(res[i], "versionID", 0);
+       for (i=0; i < res->count; i++) {
+               wins_owner     = ldb_msg_find_string(res->msgs[i], "winsOwner", NULL);
+               version        = ldb_msg_find_uint64(res->msgs[i], "versionID", 0);
 
                if (wins_owner) { 
                        status = wreplsrv_add_table(service,
@@ -301,7 +330,7 @@ static NTSTATUS wreplsrv_load_table(struct wreplsrv_service *service)
                                                    wins_owner, version);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
-               talloc_free(res[i]);
+               talloc_free(res->msgs[i]);
 
                /* TODO: what's abut the per address owners? */
        }
@@ -326,9 +355,6 @@ static NTSTATUS wreplsrv_setup_partners(struct wreplsrv_service *service)
        status = wreplsrv_load_table(service);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       status = wreplsrv_setup_out_connections(service);
-       NT_STATUS_NOT_OK_RETURN(status);
-
        return NT_STATUS_OK;
 }
 
@@ -345,8 +371,9 @@ static void wreplsrv_task_init(struct task_server *task)
                task_server_terminate(task, "wreplsrv_task_init: out of memory");
                return;
        }
-       service->task = task;
-       task->private = service;
+       service->task           = task;
+       service->startup_time   = timeval_current();
+       task->private           = service;
 
        /*
         * setup up all partners, and open the winsdb
@@ -376,6 +403,12 @@ static void wreplsrv_task_init(struct task_server *task)
                return;
        }
 
+       status = wreplsrv_setup_periodic(service);
+       if (!NT_STATUS_IS_OK(status)) {
+               task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed");
+               return;
+       }
+
        irpc_add_name(task->msg_ctx, "wrepl_server");
 }