mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-18 11:05:48 +08:00
don't use subentries control unless needed (ITS#5293)
This commit is contained in:
parent
1dad691588
commit
648fc5aabb
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user