From: Matthieu Patou Date: Tue, 1 Nov 2011 22:12:47 +0000 (+0100) Subject: s4-ldb: Add isRecycled when recycle-bin is not activated and attribute is valid is... X-Git-Url: http://git.samba.org/?p=mat%2Fsamba.git;a=commitdiff_plain;h=a80863dbbc0c7978e1556c6e11b4337b6e993550 s4-ldb: Add isRecycled when recycle-bin is not activated and attribute is valid is the schema --- diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 194498e6dd..8424350bff 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -86,6 +86,8 @@ struct replmd_replicated_request { uint64_t seq_num; bool is_urgent; + bool is_recycled_in_schema; + bool is_recycled_tested; }; enum urgent_situation { @@ -2709,6 +2711,7 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req) { int ret = LDB_ERR_OTHER; bool retb, disallow_move_on_delete; + bool add_recycled = false; struct ldb_dn *old_dn, *new_dn; const char *rdn_name; const struct ldb_val *rdn_value, *new_rdn_value; @@ -2953,8 +2956,21 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req) case OBJECT_TOMBSTONE: /* we also mark it as recycled, meaning this object can't be - recovered (we are stripping its attributes) */ - if (functional_level >= DS_DOMAIN_FUNCTION_2008_R2) { + recovered (we are stripping its attributes). + This is done only if we have this schema object of course ... + This behavior is identical to the one of Windows 2008R2 which + always set the isRecycled attribute if the recycle-bin is + not activated and what ever the forest level is. + */ + if (functional_level < DS_DOMAIN_FUNCTION_2008_R2) { + if (dsdb_attribute_by_lDAPDisplayName(schema, "isRecycled") != NULL) { + add_recycled = true; + } + } else { + add_recycled = true; + } + + if (add_recycled) { ret = ldb_msg_add_string(msg, "isRecycled", "TRUE"); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to add isRecycled string to the msg\n")); @@ -3488,6 +3504,8 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) struct replPropertyMetaDataBlob *md; struct ldb_val md_value; unsigned int i; + bool is_deleted = false; + bool has_recycled = false; int ret; /* @@ -3528,10 +3546,25 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) return replmd_replicated_request_error(ar, ret); } + if (!ar->is_recycled_tested) { + if (dsdb_attribute_by_lDAPDisplayName(ar->schema, "isRecycled") != NULL) { + ar->is_recycled_in_schema = true; + } + ar->is_recycled_tested = true; + } + /* remove any message elements that have zero values */ for (i=0; inum_elements; i++) { struct ldb_message_element *el = &msg->elements[i]; + if (ldb_attr_cmp(el->name, "isDeleted") == 0) { + is_deleted = true; + } + + if (ldb_attr_cmp(el->name, "isRecycled") == 0) { + has_recycled = true; + } + if (el->num_values == 0) { DEBUG(4,(__location__ ": Removing attribute %s with num_values==0\n", el->name)); @@ -3542,6 +3575,60 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) } } + if (is_deleted && ar->is_recycled_in_schema && !has_recycled) { + /* + * The object is deleted and we have the isRecycled attribute in + * the schema but it is missing on thi object, so we always mark + * the object as deleted because it means that it comes from a + * pre windows 2008R2 server and so we do like Windows 2008R2.*/ + + const struct dsdb_attribute *sa; + time_t t = time(NULL); + NTTIME now; + struct replPropertyMetaData1 *m; + const struct GUID *our_invocation_id; + const struct ldb_val* v; + + v = ldb_dn_get_rdn_val(msg->dn); + if (!v || strcmp((char*)v->data, "Deleted Objects") == 0) { + goto noadd; + } + + our_invocation_id = samdb_ntds_invocation_id(ldb); + if (!our_invocation_id) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "replmd_add: unable to find invocationId\n"); + return replmd_replicated_request_error(ar, LDB_ERR_OPERATIONS_ERROR); + } + + unix_to_nt_time(&now, t); + + ret = ldb_msg_add_string(msg, "isRecycled", "TRUE"); + if (ret != LDB_SUCCESS) { + return replmd_replicated_request_error(ar, ret); + } + + md->ctr.ctr1.count++; + md->ctr.ctr1.array = talloc_realloc(ar, md->ctr.ctr1.array, + struct replPropertyMetaData1, + md->ctr.ctr1.count); + + /* rdn is at the end so shift it to end first */ + m = &md->ctr.ctr1.array[md->ctr.ctr1.count - 2]; + md->ctr.ctr1.array[md->ctr.ctr1.count - 1] = *m; + + /* Allocate a new entry in the replPropertyMetadata */ + sa = dsdb_attribute_by_lDAPDisplayName(ar->schema, "isRecycled"); + + m->attid = sa->attributeID_id; + m->version = 1; + m->originating_change_time = now; + m->originating_invocation_id = *our_invocation_id; + m->originating_usn = ar->seq_num; + m->local_usn = ar->seq_num; + } +noadd: + /* * the meta data array is already sorted by the caller */