summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2011-08-01 13:55:58 +1000
committerAndrew Tridgell <tridge@samba.org>2011-08-04 16:17:24 +1000
commitd669e83857600ec59afc5b11c0286f28fceb0d0a (patch)
tree5f7b47e6ac97ca53a381866b5a35f6a5c5bf7e7d /source4/dsdb/samdb/ldb_modules/extended_dn_out.c
parenta74f4673eda682bbca4adfed8a924b16114a0dcd (diff)
downloadsamba-d669e83857600ec59afc5b11c0286f28fceb0d0a.tar.gz
samba-d669e83857600ec59afc5b11c0286f28fceb0d0a.tar.bz2
samba-d669e83857600ec59afc5b11c0286f28fceb0d0a.zip
s4-dsdb: fixed outgoing one way link DNs
when we return a DN which is a one way link, fix the string DN component by searching for the GUID and replacing the DN components Pair-Programmed-With: Amitay Isaacs <amitay@gmail.com> Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/extended_dn_out.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_out.c64
1 files changed, 62 insertions, 2 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,