From: Matthieu Patou Date: Thu, 3 Nov 2011 14:03:11 +0000 (+0100) Subject: s4-kcc: Sets the isRecyled attributes on deleted entries when needed X-Git-Url: http://git.samba.org/?p=mat%2Fsamba.git;a=commitdiff_plain;h=12deb70820bc7d364a5672fbab9f343ab3ece575 s4-kcc: Sets the isRecyled attributes on deleted entries when needed The check-deleted task now checks if the object should have the isRecyled=TRUE attribute and do have it. --- diff --git a/source4/dsdb/kcc/kcc_deleted.c b/source4/dsdb/kcc/kcc_deleted.c index 5d2585d60b..2017ac91e1 100644 --- a/source4/dsdb/kcc/kcc_deleted.c +++ b/source4/dsdb/kcc/kcc_deleted.c @@ -44,6 +44,9 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) struct kccsrv_partition *part; int ret; uint32_t tombstoneLifetime; + const struct dsdb_schema *schema; + bool add_recycled = false; + bool rcbin_enabled = false; time_t t = time(NULL); if (t - s->last_deleted_check < lpcfg_parm_int(s->task->lp_ctx, NULL, "kccsrv", @@ -51,6 +54,7 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) return NT_STATUS_OK; } s->last_deleted_check = t; + DEBUG(11, ("Check deleted has kicked in !\n")); ret = dsdb_tombstone_lifetime(s->samdb, &tombstoneLifetime); if (ret != LDB_SUCCESS) { @@ -58,10 +62,26 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) return NT_STATUS_INTERNAL_DB_CORRUPTION; } + schema = dsdb_get_schema(s->samdb, mem_ctx); + if (!schema) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + if (dsdb_attribute_by_lDAPDisplayName(schema, "isRecycled") != NULL) { + add_recycled = true; + } + + if (dsdb_functional_level(s->samdb) >= DS_DOMAIN_FUNCTION_2008_R2) { + ret = samdb_recyclebin_enabled(s->samdb , &rcbin_enabled); + if (ret != LDB_SUCCESS) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + for (part=s->partitions; part; part=part->next) { struct ldb_dn *do_dn; struct ldb_result *res; - const char *attrs[] = { "whenChanged", NULL }; + const char *attrs[] = { "whenChanged", "isRecycled", NULL }; unsigned int i; ret = dsdb_get_deleted_objects_dn(s->samdb, mem_ctx, part->dn, &do_dn); @@ -84,6 +104,10 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) const char *tstring; time_t whenChanged = 0; + if (ldb_dn_compare(do_dn, res->msgs[i]->dn) == 0) { + /* Skip the Deleted Object Container */ + continue; + } tstring = ldb_msg_find_attr_as_string(res->msgs[i], "whenChanged", NULL); if (tstring) { whenChanged = ldb_string_to_time(tstring); @@ -97,6 +121,33 @@ NTSTATUS kccsrv_check_deleted(struct kccsrv_service *s, TALLOC_CTX *mem_ctx) DEBUG(4,("Removed deleted object %s\n", ldb_dn_get_linearized(res->msgs[i]->dn))); } + } else if (add_recycled & !ldb_msg_find_ldb_val(res->msgs[i], "isRecycled") && !rcbin_enabled) { + /* There is no isRecycled attribute and the recycle-bin + * is not enabled so set isRecycled to TRUE. + * We used to not set this attribute before + * let's set it + */ + + DEBUG(1, ("Adding isRecycled\n")); + struct ldb_message *msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + talloc_free(do_dn); + return NT_STATUS_NO_MEMORY; + } + + msg->dn = res->msgs[i]->dn; + ret = ldb_msg_add_string(msg, "isRecycled", "TRUE"); + if (ret != LDB_SUCCESS) { + talloc_free(do_dn); + return NT_STATUS_NO_MEMORY; + } + msg->elements[msg->num_elements - 1].flags = LDB_FLAG_MOD_ADD; + + ret = dsdb_modify(s->samdb, msg, DSDB_SEARCH_SHOW_DELETED); + if (ret != LDB_SUCCESS) { + talloc_free(do_dn); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } } }