summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_out.c64
-rw-r--r--source4/dsdb/samdb/ldb_modules/wscript_build2
2 files changed, 63 insertions, 3 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
index 4f6033ccc2..3333a37644 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
@@ -144,8 +144,6 @@ static bool add_attrs(void *mem_ctx, char ***attrs, const char *attr)
cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com
*/
-
-
static int fix_dn(struct ldb_context *ldb, struct ldb_dn *dn)
{
int i, ret;
@@ -170,6 +168,7 @@ static int fix_dn(struct ldb_context *ldb, struct ldb_dn *dn)
return LDB_SUCCESS;
}
+
/* Inject the extended DN components, so the DN cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
<GUID=541203ae-f7d6-47ef-8390-bfcf019f9583>;<SID=S-1-5-21-4177067393-1453636373-93818737-500>;cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com */
@@ -349,6 +348,54 @@ struct extended_search_context {
int extended_type;
};
+
+/*
+ fix one-way links to have the right string DN, to cope with
+ renames of the target
+*/
+static int fix_one_way_link(struct extended_search_context *ac, struct ldb_dn *dn)
+{
+ struct GUID guid;
+ NTSTATUS status;
+ int ret;
+ struct ldb_dn *real_dn;
+
+ status = dsdb_get_extended_dn_guid(dn, &guid, "GUID");
+ if (!NT_STATUS_IS_OK(status)) {
+ /* this is a strange DN that doesn't have a GUID! just
+ return the current DN string?? */
+ return LDB_SUCCESS;
+ }
+
+ ret = dsdb_module_dn_by_guid(ac->module, dn, &guid, &real_dn, ac->req);
+ if (ret != LDB_SUCCESS) {
+ /* it could be on another server, we need to leave the
+ string DN alone */
+ return LDB_SUCCESS;
+ }
+
+ if (strcmp(ldb_dn_get_linearized(dn), ldb_dn_get_linearized(real_dn)) == 0) {
+ /* its already correct */
+ talloc_free(real_dn);
+ return LDB_SUCCESS;
+ }
+
+ /* fix the DN by replacing its components with those from the
+ * real DN
+ */
+ if (!ldb_dn_replace_components(dn, real_dn)) {
+ talloc_free(real_dn);
+ return ldb_operr(ldb_module_get_ctx(ac->module));
+ }
+ talloc_free(real_dn);
+
+ return LDB_SUCCESS;
+}
+
+
+/*
+ this is called to post-process the results from the search
+ */
static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
int (*handle_dereference)(struct ldb_dn *dn,
struct dsdb_openldap_dereference_result **dereference_attrs,
@@ -438,6 +485,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
for (i = 0; ac->schema && i < msg->num_elements; i++) {
bool make_extended_dn;
const struct dsdb_attribute *attribute;
+
attribute = dsdb_attribute_by_lDAPDisplayName(ac->schema, msg->elements[i].name);
if (!attribute) {
continue;
@@ -544,6 +592,18 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
return ldb_module_done(ac->req, NULL, NULL, ret);
}
}
+
+ /* note that we don't fixup objectCategory as
+ it should not be possible to move
+ objectCategory elements in the schema */
+ if (attribute->one_way_link &&
+ strcasecmp(attribute->lDAPDisplayName, "objectCategory") != 0) {
+ ret = fix_one_way_link(ac, dn);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(dsdb_dn);
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
if (make_extended_dn) {
dn_str = dsdb_dn_get_extended_linearized(msg->elements[i].values,
diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build b/source4/dsdb/samdb/ldb_modules/wscript_build
index 56c2d12650..26d3019f04 100644
--- a/source4/dsdb/samdb/ldb_modules/wscript_build
+++ b/source4/dsdb/samdb/ldb_modules/wscript_build
@@ -188,7 +188,7 @@ bld.SAMBA_MODULE('ldb_extended_dn_out',
init_function='ldb_extended_dn_out_module_init',
module_init_name='ldb_init_module',
subsystem='ldb',
- deps='talloc ndr samba-util samdb',
+ deps='talloc ndr samba-util samdb DSDB_MODULE_HELPERS',
internal_module=False,
)