]> git.sur5r.net Git - openldap/commitdiff
ITS#5293
authorQuanah Gibson-Mount <quanah@openldap.org>
Tue, 12 Feb 2008 01:32:01 +0000 (01:32 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 12 Feb 2008 01:32:01 +0000 (01:32 +0000)
CHANGES
clients/tools/ldapdelete.c

diff --git a/CHANGES b/CHANGES
index dc4027a8f82335a931a64f31dd7387dffd6d9bc5..733b0bc57b4af71960435f96b53d79982eae28cf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,7 @@ OpenLDAP 2.4.8 Engineering
        Fixed libldap paged results crash (ITS#5315)
        Fixed libldap use of %n (ITS#5324)
        Fixed ldapdelete with sizelimit (ITS#5294)
+       Fixed ldapdelete with subentries control (ITS#5293)
        Fixed slapd support for 2.1 CSN (ITS#5348)
        Fixed slapd idlcache on adds (ITS#5086)
        Fixed slapd include handling (ITS#5276)
index 327cd1fa523cf00141f39ac406a097c2042cce0f..754d96aae421b732c63a9d9ea62753fadf369992 100644 (file)
@@ -60,7 +60,8 @@ static int dodelete LDAP_P((
 
 static int deletechildren LDAP_P((
        LDAP *ld,
-       const char *dn ));
+       const char *dn,
+       int subentries ));
 
 void
 usage( void )
@@ -238,6 +239,7 @@ static int dodelete(
        char *matcheddn = NULL, *text = NULL, **refs = NULL;
        LDAPControl **ctrls = NULL;
        LDAPMessage *res;
+       int subentries = 0;
 
        if ( verbose ) {
                printf( _("%sdeleting entry \"%s\"\n"),
@@ -251,7 +253,10 @@ static int dodelete(
        /* If prune is on, remove a whole subtree.  Delete the children of the
         * DN recursively, then the DN requested.
         */
-       if ( prune ) deletechildren( ld, dn );
+       if ( prune ) {
+retry:;
+               deletechildren( ld, dn, subentries );
+       }
 
        rc = ldap_delete_ext( ld, dn, NULL, NULL, &id );
        if ( rc != LDAP_SUCCESS ) {
@@ -283,7 +288,18 @@ static int dodelete(
 
        rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 );
 
-       if( rc != LDAP_SUCCESS ) {
+       switch ( rc ) {
+       case LDAP_SUCCESS:
+               break;
+
+       case LDAP_NOT_ALLOWED_ON_NONLEAF:
+               if ( prune && !subentries ) {
+                       subentries = 1;
+                       goto retry;
+               }
+               /* fallthru */
+
+       default:
                fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
                        prog, ldap_err2string( rc ), rc );
                return rc;
@@ -316,7 +332,7 @@ static int dodelete(
        if (ctrls) {
                tool_print_ctrls( ld, ctrls );
                ldap_controls_free( ctrls );
-    }
+       }
 
        ber_memfree( text );
        ber_memfree( matcheddn );
@@ -330,24 +346,48 @@ static int dodelete(
  */
 static int deletechildren(
        LDAP *ld,
-       const char *base )
+       const char *base,
+       int subentries )
 {
        LDAPMessage *res, *e;
        int entries;
-       int rc, srch_rc;
+       int rc = LDAP_SUCCESS, srch_rc;
        static char *attrs[] = { LDAP_NO_ATTRS, NULL };
-       LDAPControl c, *ctrls[2];
+       LDAPControl c, *ctrls[2], **ctrlsp = NULL;
        BerElement *ber = NULL;
-       LDAPMessage *res_se;
 
        if ( verbose ) printf ( _("deleting children of: %s\n"), base );
 
+       if ( subentries ) {
+               /*
+                * Do a one level search at base for subentry children.
+                */
+
+               if ((ber = ber_alloc_t(LBER_USE_DER)) == NULL) {
+                       return EXIT_FAILURE;
+               }
+               rc = ber_printf( ber, "b", 1 );
+               if ( rc == -1 ) {
+                       ber_free( ber, 1 );
+                       fprintf( stderr, _("Subentries control encoding error!\n"));
+                       return EXIT_FAILURE;
+               }
+               if ( ber_flatten2( ber, &c.ldctl_value, 0 ) == -1 ) {
+                       return EXIT_FAILURE;
+               }
+               c.ldctl_oid = LDAP_CONTROL_SUBENTRIES;
+               c.ldctl_iscritical = 1;
+               ctrls[0] = &c;
+               ctrls[1] = NULL;
+               ctrlsp = ctrls;
+       }
+
        /*
         * Do a one level search at base for children.  For each, delete its children.
         */
 more:;
        srch_rc = ldap_search_ext_s( ld, base, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1,
-               NULL, NULL, NULL, sizelimit, &res );
+               ctrlsp, NULL, NULL, sizelimit, &res );
        switch ( srch_rc ) {
        case LDAP_SUCCESS:
        case LDAP_SIZELIMIT_EXCEEDED:
@@ -374,8 +414,8 @@ more:;
                                return rc;
                        }
 
-                       rc = deletechildren( ld, dn );
-                       if ( rc == -1 ) {
+                       rc = deletechildren( ld, dn, 0 );
+                       if ( rc != LDAP_SUCCESS ) {
                                tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
                                ber_memfree( dn );
                                return rc;
@@ -386,7 +426,7 @@ more:;
                        }
 
                        rc = ldap_delete_ext_s( ld, dn, NULL, NULL );
-                       if ( rc == -1 ) {
+                       if ( rc != LDAP_SUCCESS ) {
                                tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
                                ber_memfree( dn );
                                return rc;
@@ -407,82 +447,5 @@ more:;
                goto more;
        }
 
-       /*
-        * Do a one level search at base for subentry children.
-        */
-
-       if ((ber = ber_alloc_t(LBER_USE_DER)) == NULL) {
-               return EXIT_FAILURE;
-       }
-       rc = ber_printf( ber, "b", 1 );
-       if ( rc == -1 ) {
-               ber_free( ber, 1 );
-               fprintf( stderr, _("Subentries control encoding error!\n"));
-               return EXIT_FAILURE;
-       }
-       if ( ber_flatten2( ber, &c.ldctl_value, 0 ) == -1 ) {
-               return EXIT_FAILURE;
-       }
-       c.ldctl_oid = LDAP_CONTROL_SUBENTRIES;
-       c.ldctl_iscritical = 1;
-       ctrls[0] = &c;
-       ctrls[1] = NULL;
-
-more2:;
-       srch_rc = ldap_search_ext_s( ld, base, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1,
-               ctrls, NULL, NULL, sizelimit, &res_se );
-       switch ( srch_rc ) {
-       case LDAP_SUCCESS:
-       case LDAP_SIZELIMIT_EXCEEDED:
-               break;
-       default:
-               tool_perror( "ldap_search", srch_rc, NULL, NULL, NULL, NULL );
-               return( srch_rc );
-       }
-       ber_free( ber, 1 );
-
-       entries = ldap_count_entries( ld, res_se );
-
-       if ( entries > 0 ) {
-               int i;
-
-               for (e = ldap_first_entry( ld, res_se ), i = 0; e != NULL;
-                       e = ldap_next_entry( ld, e ), i++ )
-               {
-                       char *dn = ldap_get_dn( ld, e );
-
-                       if( dn == NULL ) {
-                               ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
-                               tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
-                               ber_memfree( dn );
-                               return rc;
-                       }
-
-                       if ( verbose ) {
-                               printf( _("\tremoving %s\n"), dn );
-                       }
-
-                       rc = ldap_delete_ext_s( ld, dn, NULL, NULL );
-                       if ( rc == -1 ) {
-                               tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
-                               ber_memfree( dn );
-                               return rc;
-
-                       }
-                       
-                       if ( verbose ) {
-                               printf( _("\t%s removed\n"), dn );
-                       }
-
-                       ber_memfree( dn );
-               }
-       }
-
-       ldap_msgfree( res_se );
-
-       if ( srch_rc == LDAP_SIZELIMIT_EXCEEDED ) {
-               goto more2;
-       }
-
        return rc;
 }