Hi!

Make sure we delete child domains before removing the trust itself as
LDAP protocol does not allow removing non-leaf objects.

This has non-obvious effect -- old code did remove cross-realm
principals and then removed trust object. However, for trusts with child
domains the trust domain object was not removed as LDAP server prevents
removing non-leaf objects. It resulted in the object still existing but
cross-realm principals missing. The trust is thus non-functioning. This
situation can be triggered with a second 'ipa trust-add' call.

Fix the code by removing child domains first and then remove the forest
root trusted domain object.

https://fedorahosted.org/freeipa/ticket/4126
--
/ Alexander Bokovoy
>From 320ac44326dfd48b7639f0b3637f974b96189cd7 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <aboko...@redhat.com>
Date: Mon, 20 Jan 2014 16:42:48 +0200
Subject: [PATCH 2/2] ipasam: delete trusted child domains before removing the
 trust

LDAP protocol doesn't allow deleting non-leaf entries. One needs to
remove all leaves first before removing the tree node.

https://fedorahosted.org/freeipa/ticket/4126
---
 daemons/ipa-sam/ipa_sam.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index 674085d..beca629 100644
--- a/daemons/ipa-sam/ipa_sam.c
+++ b/daemons/ipa-sam/ipa_sam.c
@@ -2437,6 +2437,44 @@ done:
        return status;
 }
 
+static int delete_subtree(struct ldapsam_privates *ldap_state, const char* dn)
+{
+       LDAP *state = priv2ld(ldap_state);
+       int rc;
+       char *filter = NULL;
+       int scope = LDAP_SCOPE_SUBTREE;
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
+       char *entry_dn = NULL;
+
+       /* use 'dn' for a temporary talloc context */
+       filter = talloc_asprintf(dn, "(objectClass=*)");
+       if (filter == NULL) {
+               return LDAP_NO_MEMORY;
+       }
+
+       rc = smbldap_search(ldap_state->smbldap_state, dn, scope, filter, NULL, 
0, &result);
+       TALLOC_FREE(filter);
+
+       if (result != NULL) {
+               smbldap_talloc_autofree_ldapmsg(dn, result);
+       }
+
+       for (entry = ldap_first_entry(state, result);
+            entry != NULL;
+            entry = ldap_next_entry(state, entry)) {
+               entry_dn = get_dn(dn, state, entry);
+               /* remove child entries */
+               if ((entry_dn != NULL) && (strcmp(entry_dn, dn) != 0)) {
+                       rc = smbldap_delete(ldap_state->smbldap_state, 
entry_dn);
+               }
+       }
+       rc = smbldap_delete(ldap_state->smbldap_state, dn);
+
+       /* caller will destroy dn */
+       return rc;
+}
+
 static NTSTATUS ipasam_del_trusted_domain(struct pdb_methods *methods,
                                           const char *domain)
 {
@@ -2490,6 +2528,11 @@ static NTSTATUS ipasam_del_trusted_domain(struct 
pdb_methods *methods,
        }
 
        ret = smbldap_delete(ldap_state->smbldap_state, dn);
+       if (ret == LDAP_NOT_ALLOWED_ON_NONLEAF) {
+               /* delete_subtree will use 'dn' as temporary context too */
+               ret = delete_subtree(ldap_state, dn);
+       }
+
        if (ret != LDAP_SUCCESS) {
                status = NT_STATUS_UNSUCCESSFUL;
                goto done;
-- 
1.8.4.2

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to