dsdb: Rework kcc_deleted() into dsdb_garbage_collect_tombstones()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 18 Jul 2016 01:10:23 +0000 (13:10 +1200)
committerGarming Sam <garming@samba.org>
Thu, 1 Sep 2016 03:49:14 +0000 (05:49 +0200)
This is so that in a future commit, we can wrap this in python and allow it to be called
from outside the samba server processs.

This requires that we rework the callers and internals to avoid reference to
private data structures of the KCC service.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
source4/dsdb/common/util.h
source4/dsdb/kcc/garbage_collect_tombstones.c
source4/dsdb/kcc/garbage_collect_tombstones.h [new file with mode: 0644]
source4/dsdb/kcc/kcc_periodic.c
source4/dsdb/kcc/kcc_service.c
source4/dsdb/kcc/kcc_service.h
source4/dsdb/wscript_build

index f2867a2e7d76bac9fe00e6cd1d4fc13a19ee40bc..ede6d8b0763569b3f8c3791c7c6bcbd36dd2d155 100644 (file)
@@ -80,4 +80,14 @@ int dsdb_werror_at(struct ldb_context *ldb, int ldb_ecode, WERROR werr,
        dsdb_werror_at(ldb_module_get_ctx(module), ldb_ecode, werr, \
                       __location__, __func__, reason)
 
+
+struct dsdb_ldb_dn_list_node {
+       struct dsdb_ldb_dn_list_node *prev, *next;
+
+       /* the dn of the partition */
+       struct ldb_dn *dn;
+};
+
+
+
 #endif /* __DSDB_COMMON_UTIL_H__ */
index 8b9e9216e4501404c544bc67961fdec6eb46c084..825cfe2d2985131d65e5001ac8293ec35cad2b92 100644 (file)
 */
 
 #include "includes.h"
-#include "lib/events/events.h"
-#include "dsdb/samdb/samdb.h"
-#include "auth/auth.h"
-#include "smbd/service.h"
-#include "lib/messaging/irpc.h"
-#include "dsdb/kcc/kcc_connection.h"
-#include "dsdb/kcc/kcc_service.h"
 #include <ldb_errors.h>
 #include "../lib/util/dlinklist.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "param/param.h"
-#include "dsdb/common/util.h"
+#include "lib/util/dlinklist.h"
+#include "ldb.h"
+#include "dsdb/kcc/garbage_collect_tombstones.h"
 
-/*
-  check to see if any deleted objects need scavenging
- */
-NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
+
+NTSTATUS dsdb_garbage_collect_tombstones(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+                                        struct ldb_context *samdb,
+                                        struct dsdb_ldb_dn_list_node *part,
+                                        time_t current_time, time_t *last_deleted_check,
+                                        time_t *last_full_scan_deleted_check)
 {
-       struct kccsrv_partition *part;
        int ret;
        uint32_t tombstoneLifetime;
        bool do_fs = false;
 
-       time_t interval = lpcfg_parm_int(s->task->lp_ctx, NULL, "kccsrv",
-                                                   "check_deleted_full_scan_interval", 86400);
-       time_t t = time(NULL);
+       time_t interval = lpcfg_parm_int(lp_ctx, NULL, "kccsrv",
+                                        "check_deleted_full_scan_interval", 86400);
 
-       if (t - s->last_deleted_check < lpcfg_parm_int(s->task->lp_ctx, NULL, "kccsrv",
-                                                   "check_deleted_interval", 600)) {
+       if (current_time - *last_deleted_check < lpcfg_parm_int(lp_ctx, NULL, "kccsrv",
+                                                                 "check_deleted_interval", 600)) {
                return NT_STATUS_OK;
        }
-       s->last_deleted_check = t;
+       *last_deleted_check = current_time;
 
-       ret = dsdb_tombstone_lifetime(s->samdb, &tombstoneLifetime);
+       ret = dsdb_tombstone_lifetime(samdb, &tombstoneLifetime);
        if (ret != LDB_SUCCESS) {
                DEBUG(1,(__location__ ": Failed to get tombstone lifetime\n"));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
-       if (s->last_full_scan_deleted_check > 0 && ((t - s->last_full_scan_deleted_check) > interval )) {
+       if (*last_full_scan_deleted_check > 0 && ((current_time - *last_full_scan_deleted_check) > interval )) {
                do_fs = true;
-               s->last_full_scan_deleted_check = t;
+               *last_full_scan_deleted_check = current_time;
        }
 
-       if (s->last_full_scan_deleted_check == 0) {
+       if (*last_full_scan_deleted_check == 0) {
                /*
                 * If we never made a full scan set the last full scan event to be in the past
                 * and that 9/10 of the full scan interval has already passed.
@@ -75,10 +70,10 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
                 * With this "setup" and default values of interval, the full scan will fire
                 * 2.4 hours after the start of samba
                 */
-               s->last_full_scan_deleted_check = t - ((9 * interval) / 10);
+               *last_full_scan_deleted_check = current_time - ((9 * interval) / 10);
        }
 
-       for (part=s->partitions; part; part=part->next) {
+       for (; part != NULL; part = part->next) {
                struct ldb_dn *do_dn;
                struct ldb_result *res;
                const char *attrs[] = { "whenChanged", NULL };
@@ -88,7 +83,7 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
                        return NT_STATUS_NO_MEMORY;
                }
 
-               ret = dsdb_get_deleted_objects_dn(s->samdb, tmp_ctx, part->dn, &do_dn);
+               ret = dsdb_get_deleted_objects_dn(samdb, tmp_ctx, part->dn, &do_dn);
                if (ret != LDB_SUCCESS) {
                        TALLOC_FREE(tmp_ctx);
                        /* some partitions have no Deleted Objects
@@ -96,16 +91,16 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
                        continue;
                }
 
-               if (!do_fs && ldb_dn_compare(ldb_get_config_basedn(s->samdb), part->dn)) {
-                       ret = dsdb_search(s->samdb, tmp_ctx, &res, do_dn, LDB_SCOPE_ONELEVEL, attrs,
+               if (!do_fs && ldb_dn_compare(ldb_get_config_basedn(samdb), part->dn)) {
+                       ret = dsdb_search(samdb, tmp_ctx, &res, do_dn, LDB_SCOPE_ONELEVEL, attrs,
                                        DSDB_SEARCH_SHOW_RECYCLED, NULL);
                } else {
                        if (do_fs) {
                                DEBUG(1, ("Doing a full scan on %s and looking for deleted object\n",
                                                ldb_dn_get_linearized(part->dn)));
                        }
-                       ret = dsdb_search(s->samdb, tmp_ctx, &res, part->dn, LDB_SCOPE_SUBTREE, attrs,
-                                       DSDB_SEARCH_SHOW_RECYCLED, "(isDeleted=TRUE)");
+                       ret = dsdb_search(samdb, tmp_ctx, &res, part->dn, LDB_SCOPE_SUBTREE, attrs,
+                                       DSDB_SEARCH_SHOW_RECYCLED, "(|(isDeleted=TRUE))");
                }
 
                if (ret != LDB_SUCCESS) {
@@ -127,8 +122,8 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
                        if (tstring) {
                                whenChanged = ldb_string_to_time(tstring);
                        }
-                       if (t - whenChanged > tombstoneLifetime*60*60*24) {
-                               ret = dsdb_delete(s->samdb, res->msgs[i]->dn, DSDB_SEARCH_SHOW_RECYCLED|DSDB_MODIFY_RELAX);
+                       if (current_time - whenChanged > tombstoneLifetime*60*60*24) {
+                               ret = dsdb_delete(samdb, res->msgs[i]->dn, DSDB_SEARCH_SHOW_RECYCLED|DSDB_MODIFY_RELAX);
                                if (ret != LDB_SUCCESS) {
                                        DEBUG(1,(__location__ ": Failed to remove deleted object %s\n",
                                                 ldb_dn_get_linearized(res->msgs[i]->dn)));
diff --git a/source4/dsdb/kcc/garbage_collect_tombstones.h b/source4/dsdb/kcc/garbage_collect_tombstones.h
new file mode 100644 (file)
index 0000000..b41bc9d
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   handle removal of deleted objects
+
+   Copyright (C) 2009 Andrew Tridgell
+
+   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 "param/param.h"
+#include "dsdb/samdb/samdb.h"
+#include "dsdb/common/util.h"
+
+
+NTSTATUS dsdb_garbage_collect_tombstones(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+                                        struct ldb_context *samdb,
+                                        struct dsdb_ldb_dn_list_node *part,
+                                        time_t current_time, time_t *last_deleted_check,
+                                        time_t *last_full_scan_deleted_check);
index 7fdbea74e66349dd399342fa238ee0e998c7f68a..ef114fd13cbdda54a149eff5f40983bc579c5a72 100644 (file)
@@ -64,7 +64,7 @@ static bool reps_in_list(struct repsFromToBlob *r, struct repsFromToBlob *reps,
   make sure we only add repsFrom entries for DCs who are masters for
   the partition
  */
-static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r,
+static bool check_MasterNC(struct kccsrv_service *service, struct dsdb_ldb_dn_list_node *p, struct repsFromToBlob *r,
                           struct ldb_result *res)
 {
        struct repsFromTo1 *r1 = &r->ctr.ctr1;
@@ -99,7 +99,7 @@ static bool check_MasterNC(struct kccsrv_partition *p, struct repsFromToBlob *r,
                        }
                }
                for (j=0; j<el->num_values; j++) {
-                       dn = ldb_dn_from_ldb_val(tmp_ctx, p->service->samdb, &el->values[j]);
+                       dn = ldb_dn_from_ldb_val(tmp_ctx, service->samdb, &el->values[j]);
                        if (!ldb_dn_validate(dn)) {
                                talloc_free(dn);
                                continue;
@@ -194,7 +194,7 @@ NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx,
                            struct repsFromToBlob *reps, uint32_t count,
                            struct ldb_result *res)
 {
-       struct kccsrv_partition *p;
+       struct dsdb_ldb_dn_list_node *p;
        bool notify_dreplsrv = false;
        uint32_t replica_flags = kccsrv_replica_flags(s);
 
@@ -233,7 +233,7 @@ NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx,
                                /* we don't have the new one - add it
                                 * if it is a master
                                 */
-                               if (res && !check_MasterNC(p, &reps[i], res)) {
+                               if (res && !check_MasterNC(s, p, &reps[i], res)) {
                                        /* its not a master, we don't
                                           want to pull from it */
                                        continue;
@@ -253,7 +253,7 @@ NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx,
                /* remove any stale ones */
                for (i=0; i<our_count; i++) {
                        if (!reps_in_list(&our_reps[i], reps, count) ||
-                           (res && !check_MasterNC(p, &our_reps[i], res))) {
+                           (res && !check_MasterNC(s, p, &our_reps[i], res))) {
                                DEBUG(4,(__location__ ": Removed repsFrom for %s\n",
                                         our_reps[i].ctr.ctr1.other_info->dns_name));
                                memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0]));
@@ -596,6 +596,17 @@ WERROR kccsrv_periodic_schedule(struct kccsrv_service *service, uint32_t next_in
        return WERR_OK;
 }
 
+/*
+  check to see if any deleted objects need scavenging
+ */
+static NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx)
+{
+       time_t current = time(NULL);
+       return dsdb_garbage_collect_tombstones(mem_ctx, s->task->lp_ctx, s->samdb,
+                                              s->partitions, current, &s->last_deleted_check,
+                                              &s->last_full_scan_deleted_check);
+}
+
 static void kccsrv_periodic_run(struct kccsrv_service *service)
 {
        TALLOC_CTX *mem_ctx;
index ccc252c510b7a28e44ca50496f9b28b3cfe4c395..090cf1b9cc9af7b662505a23471985e22586dc82 100644 (file)
@@ -110,18 +110,17 @@ static WERROR kccsrv_load_partitions(struct kccsrv_service *s)
        for (i=0; i < el->num_values; i++) {
                const char *v = (const char *)el->values[i].data;
                struct ldb_dn *pdn;
-               struct kccsrv_partition *p;
+               struct dsdb_ldb_dn_list_node *p;
 
                pdn = ldb_dn_new(s, s->samdb, v);
                if (!ldb_dn_validate(pdn)) {
                        return WERR_FOOBAR;
                }
 
-               p = talloc_zero(s, struct kccsrv_partition);
+               p = talloc_zero(s, struct dsdb_ldb_dn_list_node);
                W_ERROR_HAVE_NO_MEMORY(p);
 
                p->dn = talloc_steal(p, pdn);
-               p->service = s;
 
                DLIST_ADD(s->partitions, p);
 
index 451347ec81f5595b0d49fa62fd2458e14299d36d..b62fb12f1d044fa6630e68c8c56bcc1bcd29a9ad 100644 (file)
 #define _DSDB_REPL_KCC_SERVICE_H_
 
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
-
-struct kccsrv_partition {
-       struct kccsrv_partition *prev, *next;
-       struct kccsrv_service *service;
-
-       /* the dn of the partition */
-       struct ldb_dn *dn;
-};
-
+#include "dsdb/common/util.h"
 
 struct kccsrv_service {
        /* the whole kcc service is in one task */
@@ -52,7 +44,7 @@ struct kccsrv_service {
        struct auth_session_info *system_session_info;
 
        /* list of local partitions */
-       struct kccsrv_partition *partitions;
+       struct dsdb_ldb_dn_list_node *partitions;
 
        /*
         * a connection to the local samdb
@@ -98,8 +90,7 @@ struct kccsrv_service {
 
 struct kcc_connection_list;
 
-NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx);
-
+#include "dsdb/kcc/garbage_collect_tombstones.h"
 #include "dsdb/kcc/kcc_service_proto.h"
 
 #endif /* _DSDB_REPL_KCC_SERVICE_H_ */
index aea8fa43d71387c207908f321a9ddbc1c7ea24ba..7ea9e27353e79b128656c9e0fbe683dc0a77807a 100755 (executable)
@@ -67,6 +67,6 @@ bld.SAMBA_PYTHON('python_dsdb',
        # the dependency on dcerpc here is because gensec
        # depends on dcerpc but the waf circular dependency finder
        # removes it so we end up with unresolved symbols.
-       deps='samdb pyldb-util dcerpc com_err pyrpc_util',
+       deps='samdb pyldb-util dcerpc com_err pyrpc_util pyparam_util',
        realname='samba/dsdb.so'
        )