summaryrefslogtreecommitdiffstats
path: root/daemons
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:31:54 +0100
commitc29211671cfd7d7734b932c8d6d70c94c849b5d1 (patch)
treede4475eb91bfee31a02b101cdcc659dcc352ba6f /daemons
parent622f9ab11f12187c4453f9b7c748a6c9865591ed (diff)
downloadfreeipa-c29211671cfd7d7734b932c8d6d70c94c849b5d1.tar.gz
freeipa-c29211671cfd7d7734b932c8d6d70c94c849b5d1.tar.xz
freeipa-c29211671cfd7d7734b932c8d6d70c94c849b5d1.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
Diffstat (limited to 'daemons')
-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 674085d2a..1ca504db4 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;