summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2016-07-18 13:10:23 +1200
committerGarming Sam <garming@samba.org>2016-09-01 05:49:14 +0200
commit4e0ac09ef6c6fadd67718f7b5aca7283fb8086b1 (patch)
tree948e65b0e59e3a8a53faf7a600e8876858764c81
parent9221ce3a3237a8ded78e371fef2b8e4f03722b63 (diff)
downloadsamba-4e0ac09ef6c6fadd67718f7b5aca7283fb8086b1.tar.gz
dsdb: Rework kcc_deleted() into dsdb_garbage_collect_tombstones()
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>
-rw-r--r--source4/dsdb/common/util.h10
-rw-r--r--source4/dsdb/kcc/garbage_collect_tombstones.c59
-rw-r--r--source4/dsdb/kcc/garbage_collect_tombstones.h31
-rw-r--r--source4/dsdb/kcc/kcc_periodic.c21
-rw-r--r--source4/dsdb/kcc/kcc_service.c5
-rw-r--r--source4/dsdb/kcc/kcc_service.h15
-rwxr-xr-xsource4/dsdb/wscript_build2
7 files changed, 90 insertions, 53 deletions
diff --git a/source4/dsdb/common/util.h b/source4/dsdb/common/util.h
index f2867a2e7d7..ede6d8b0763 100644
--- a/source4/dsdb/common/util.h
+++ b/source4/dsdb/common/util.h
@@ -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__ */
diff --git a/source4/dsdb/kcc/garbage_collect_tombstones.c b/source4/dsdb/kcc/garbage_collect_tombstones.c
index 8b9e9216e45..825cfe2d298 100644
--- a/source4/dsdb/kcc/garbage_collect_tombstones.c
+++ b/source4/dsdb/kcc/garbage_collect_tombstones.c
@@ -21,52 +21,47 @@
*/
#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
index 00000000000..b41bc9dc749
--- /dev/null
+++ b/source4/dsdb/kcc/garbage_collect_tombstones.h
@@ -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);
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c
index 7fdbea74e66..ef114fd13cb 100644
--- a/source4/dsdb/kcc/kcc_periodic.c
+++ b/source4/dsdb/kcc/kcc_periodic.c
@@ -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;
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index ccc252c510b..090cf1b9cc9 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -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);
diff --git a/source4/dsdb/kcc/kcc_service.h b/source4/dsdb/kcc/kcc_service.h
index 451347ec81f..b62fb12f1d0 100644
--- a/source4/dsdb/kcc/kcc_service.h
+++ b/source4/dsdb/kcc/kcc_service.h
@@ -25,15 +25,7 @@
#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_ */
diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build
index aea8fa43d71..7ea9e27353e 100755
--- a/source4/dsdb/wscript_build
+++ b/source4/dsdb/wscript_build
@@ -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'
)