diff options
-rw-r--r-- | source4/dsdb/common/util.h | 10 | ||||
-rw-r--r-- | source4/dsdb/kcc/garbage_collect_tombstones.c | 59 | ||||
-rw-r--r-- | source4/dsdb/kcc/garbage_collect_tombstones.h | 31 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_periodic.c | 21 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_service.c | 5 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_service.h | 15 | ||||
-rwxr-xr-x | source4/dsdb/wscript_build | 2 |
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' ) |