On Tue, 21 Jan 2014, Alexander Bokovoy wrote:
On Tue, 21 Jan 2014, Sumit Bose wrote:
On Mon, Jan 20, 2014 at 04:49:21PM +0200, Alexander Bokovoy wrote:
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

Patch is working as expected. But I would suggest to remove the 'const'
from the declaration of dn (also in the caller) to avoid compiler
warnings. As an alternative you can take a different talloc context, but
using dn here makes sense.
I've removed 'const'. Btw, gcc in F20 is smarter than yours gcc in F18,
it does not issue any warnings in C99 mode for ipa_sam.c :)
.. and one more removal of 'const' in the caller to suit gcc < 4.8.2.

--
/ Alexander Bokovoy
>From 4c58609f8e0e18f9fb4af82e176bad7cad2d20b4 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <aboko...@redhat.com>
Date: Mon, 20 Jan 2014 16:42:48 +0200
Subject: [PATCH 1/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 | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index 674085d..1ca504d 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, 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)
 {
@@ -2444,7 +2482,7 @@ static NTSTATUS ipasam_del_trusted_domain(struct 
pdb_methods *methods,
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
        LDAPMessage *entry = NULL;
-       const char *dn;
+       char *dn;
        const char *domain_name;
        TALLOC_CTX *tmp_ctx;
        NTSTATUS status;
@@ -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