Skip to content
Snippets Groups Projects
Commit 9a5ea28d authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#5293

parent f50a08df
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ OpenLDAP 2.4.8 Engineering ...@@ -11,6 +11,7 @@ OpenLDAP 2.4.8 Engineering
Fixed libldap paged results crash (ITS#5315) Fixed libldap paged results crash (ITS#5315)
Fixed libldap use of %n (ITS#5324) Fixed libldap use of %n (ITS#5324)
Fixed ldapdelete with sizelimit (ITS#5294) Fixed ldapdelete with sizelimit (ITS#5294)
Fixed ldapdelete with subentries control (ITS#5293)
Fixed slapd support for 2.1 CSN (ITS#5348) Fixed slapd support for 2.1 CSN (ITS#5348)
Fixed slapd idlcache on adds (ITS#5086) Fixed slapd idlcache on adds (ITS#5086)
Fixed slapd include handling (ITS#5276) Fixed slapd include handling (ITS#5276)
......
...@@ -60,7 +60,8 @@ static int dodelete LDAP_P(( ...@@ -60,7 +60,8 @@ static int dodelete LDAP_P((
static int deletechildren LDAP_P(( static int deletechildren LDAP_P((
LDAP *ld, LDAP *ld,
const char *dn )); const char *dn,
int subentries ));
void void
usage( void ) usage( void )
...@@ -238,6 +239,7 @@ static int dodelete( ...@@ -238,6 +239,7 @@ static int dodelete(
char *matcheddn = NULL, *text = NULL, **refs = NULL; char *matcheddn = NULL, *text = NULL, **refs = NULL;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
LDAPMessage *res; LDAPMessage *res;
int subentries = 0;
if ( verbose ) { if ( verbose ) {
printf( _("%sdeleting entry \"%s\"\n"), printf( _("%sdeleting entry \"%s\"\n"),
...@@ -251,7 +253,10 @@ static int dodelete( ...@@ -251,7 +253,10 @@ static int dodelete(
/* If prune is on, remove a whole subtree. Delete the children of the /* If prune is on, remove a whole subtree. Delete the children of the
* DN recursively, then the DN requested. * 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 ); rc = ldap_delete_ext( ld, dn, NULL, NULL, &id );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
...@@ -283,7 +288,18 @@ static int dodelete( ...@@ -283,7 +288,18 @@ static int dodelete(
rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 ); 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", fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
prog, ldap_err2string( rc ), rc ); prog, ldap_err2string( rc ), rc );
return rc; return rc;
...@@ -316,7 +332,7 @@ static int dodelete( ...@@ -316,7 +332,7 @@ static int dodelete(
if (ctrls) { if (ctrls) {
tool_print_ctrls( ld, ctrls ); tool_print_ctrls( ld, ctrls );
ldap_controls_free( ctrls ); ldap_controls_free( ctrls );
} }
ber_memfree( text ); ber_memfree( text );
ber_memfree( matcheddn ); ber_memfree( matcheddn );
...@@ -330,24 +346,48 @@ static int dodelete( ...@@ -330,24 +346,48 @@ static int dodelete(
*/ */
static int deletechildren( static int deletechildren(
LDAP *ld, LDAP *ld,
const char *base ) const char *base,
int subentries )
{ {
LDAPMessage *res, *e; LDAPMessage *res, *e;
int entries; int entries;
int rc, srch_rc; int rc = LDAP_SUCCESS, srch_rc;
static char *attrs[] = { LDAP_NO_ATTRS, NULL }; static char *attrs[] = { LDAP_NO_ATTRS, NULL };
LDAPControl c, *ctrls[2]; LDAPControl c, *ctrls[2], **ctrlsp = NULL;
BerElement *ber = NULL; BerElement *ber = NULL;
LDAPMessage *res_se;
if ( verbose ) printf ( _("deleting children of: %s\n"), base ); 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. * Do a one level search at base for children. For each, delete its children.
*/ */
more:; more:;
srch_rc = ldap_search_ext_s( ld, base, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1, 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 ) { switch ( srch_rc ) {
case LDAP_SUCCESS: case LDAP_SUCCESS:
case LDAP_SIZELIMIT_EXCEEDED: case LDAP_SIZELIMIT_EXCEEDED:
...@@ -374,8 +414,8 @@ more:; ...@@ -374,8 +414,8 @@ more:;
return rc; return rc;
} }
rc = deletechildren( ld, dn ); rc = deletechildren( ld, dn, 0 );
if ( rc == -1 ) { if ( rc != LDAP_SUCCESS ) {
tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL ); tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
ber_memfree( dn ); ber_memfree( dn );
return rc; return rc;
...@@ -386,7 +426,7 @@ more:; ...@@ -386,7 +426,7 @@ more:;
} }
rc = ldap_delete_ext_s( ld, dn, NULL, NULL ); 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 ); tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
ber_memfree( dn ); ber_memfree( dn );
return rc; return rc;
...@@ -407,82 +447,5 @@ more:; ...@@ -407,82 +447,5 @@ more:;
goto 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; return rc;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment