diff options
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 161 |
1 files changed, 84 insertions, 77 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 245560f769..3390f80f13 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -133,78 +133,8 @@ struct la_backlink { }; /* - add a backlink to the list of backlinks to add/delete in the prepare - commit - */ -static int replmd_add_backlink(struct ldb_module *module, const struct dsdb_schema *schema, - struct GUID *forward_guid, struct GUID *target_guid, - bool active, const struct dsdb_attribute *schema_attr) -{ - const struct dsdb_attribute *target_attr; - struct la_backlink *bl; - struct replmd_private *replmd_private = - talloc_get_type_abort(ldb_module_get_private(module), struct replmd_private); - - target_attr = dsdb_attribute_by_linkID(schema, schema_attr->linkID + 1); - if (!target_attr) { - /* - * windows 2003 has a broken schema where the - * definition of msDS-IsDomainFor is missing (which is - * supposed to be the backlink of the - * msDS-HasDomainNCs attribute - */ - return LDB_SUCCESS; - } - - /* see if its already in the list */ - for (bl=replmd_private->la_backlinks; bl; bl=bl->next) { - if (GUID_equal(forward_guid, &bl->forward_guid) && - GUID_equal(target_guid, &bl->target_guid) && - (target_attr->lDAPDisplayName == bl->attr_name || - strcmp(target_attr->lDAPDisplayName, bl->attr_name) == 0)) { - break; - } - } - - if (bl) { - /* we found an existing one */ - if (bl->active == active) { - return LDB_SUCCESS; - } - DLIST_REMOVE(replmd_private->la_backlinks, bl); - talloc_free(bl); - return LDB_SUCCESS; - } - - if (replmd_private->bl_ctx == NULL) { - replmd_private->bl_ctx = talloc_new(replmd_private); - if (replmd_private->bl_ctx == NULL) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - /* its a new one */ - bl = talloc(replmd_private->bl_ctx, struct la_backlink); - if (bl == NULL) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - bl->attr_name = target_attr->lDAPDisplayName; - bl->forward_guid = *forward_guid; - bl->target_guid = *target_guid; - bl->active = active; - - DLIST_ADD(replmd_private->la_backlinks, bl); - - return LDB_SUCCESS; -} - -/* - process the list of backlinks we accumulated during - a transaction, adding and deleting the backlinks - from the target objects + process a backlinks we accumulated during a transaction, adding and + deleting the backlinks from the target objects */ static int replmd_process_backlink(struct ldb_module *module, struct la_backlink *bl) { @@ -273,6 +203,83 @@ static int replmd_process_backlink(struct ldb_module *module, struct la_backlink return ret; } +/* + add a backlink to the list of backlinks to add/delete in the prepare + commit + */ +static int replmd_add_backlink(struct ldb_module *module, const struct dsdb_schema *schema, + struct GUID *forward_guid, struct GUID *target_guid, + bool active, const struct dsdb_attribute *schema_attr, bool immediate) +{ + const struct dsdb_attribute *target_attr; + struct la_backlink *bl; + struct replmd_private *replmd_private = + talloc_get_type_abort(ldb_module_get_private(module), struct replmd_private); + + target_attr = dsdb_attribute_by_linkID(schema, schema_attr->linkID + 1); + if (!target_attr) { + /* + * windows 2003 has a broken schema where the + * definition of msDS-IsDomainFor is missing (which is + * supposed to be the backlink of the + * msDS-HasDomainNCs attribute + */ + return LDB_SUCCESS; + } + + /* see if its already in the list */ + for (bl=replmd_private->la_backlinks; bl; bl=bl->next) { + if (GUID_equal(forward_guid, &bl->forward_guid) && + GUID_equal(target_guid, &bl->target_guid) && + (target_attr->lDAPDisplayName == bl->attr_name || + strcmp(target_attr->lDAPDisplayName, bl->attr_name) == 0)) { + break; + } + } + + if (bl) { + /* we found an existing one */ + if (bl->active == active) { + return LDB_SUCCESS; + } + DLIST_REMOVE(replmd_private->la_backlinks, bl); + talloc_free(bl); + return LDB_SUCCESS; + } + + if (replmd_private->bl_ctx == NULL) { + replmd_private->bl_ctx = talloc_new(replmd_private); + if (replmd_private->bl_ctx == NULL) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + /* its a new one */ + bl = talloc(replmd_private->bl_ctx, struct la_backlink); + if (bl == NULL) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + bl->attr_name = target_attr->lDAPDisplayName; + bl->forward_guid = *forward_guid; + bl->target_guid = *target_guid; + bl->active = active; + + /* the caller may ask for this backlink to be processed + immediately */ + if (immediate) { + int ret = replmd_process_backlink(module, bl); + talloc_free(bl); + return ret; + } + + DLIST_ADD(replmd_private->la_backlinks, bl); + + return LDB_SUCCESS; +} + /* * Callback for most write operations in this module: @@ -610,7 +617,7 @@ static int replmd_add_fix_la(struct ldb_module *module, struct ldb_message_eleme return LDB_ERR_OPERATIONS_ERROR; } - ret = replmd_add_backlink(module, schema, guid, &target_guid, true, sa); + ret = replmd_add_backlink(module, schema, guid, &target_guid, true, sa, true); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -1402,7 +1409,7 @@ static int replmd_modify_la_add(struct ldb_module *module, } } - ret = replmd_add_backlink(module, schema, msg_guid, dns[i].guid, true, schema_attr); + ret = replmd_add_backlink(module, schema, msg_guid, dns[i].guid, true, schema_attr, true); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -1525,7 +1532,7 @@ static int replmd_modify_la_delete(struct ldb_module *module, return ret; } - ret = replmd_add_backlink(module, schema, msg_guid, old_dns[i].guid, false, schema_attr); + ret = replmd_add_backlink(module, schema, msg_guid, old_dns[i].guid, false, schema_attr, true); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -1599,7 +1606,7 @@ static int replmd_modify_la_replace(struct ldb_module *module, v = ldb_dn_get_extended_component(old_p->dsdb_dn->dn, "DELETED"); if (v) continue; - ret = replmd_add_backlink(module, schema, msg_guid, old_dns[i].guid, false, schema_attr); + ret = replmd_add_backlink(module, schema, msg_guid, old_dns[i].guid, false, schema_attr, false); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -1654,7 +1661,7 @@ static int replmd_modify_la_replace(struct ldb_module *module, num_new_values++; } - ret = replmd_add_backlink(module, schema, msg_guid, dns[i].guid, true, schema_attr); + ret = replmd_add_backlink(module, schema, msg_guid, dns[i].guid, true, schema_attr, false); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; |