summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2014-01-20 16:42:48 +0200
committerMartin Kosek <mkosek@redhat.com>2014-01-21 12:32:02 +0100
commit897e1415ce1b711cd7179fa973569969236984ed (patch)
tree4fa8aba22fe42f3bd726523c88386becf1424e47
parentbf440ba479442d8fb5b06983bfe20146cc4ddbac (diff)
downloadfreeipa.git-897e1415ce1b711cd7179fa973569969236984ed.tar.gz
freeipa.git-897e1415ce1b711cd7179fa973569969236984ed.tar.xz
freeipa.git-897e1415ce1b711cd7179fa973569969236984ed.zip
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
-rw-r--r--daemons/ipa-sam/ipa_sam.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index 674085d2..1ca504db 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;