From: Pierangelo Masarati Date: Thu, 16 Feb 2006 01:26:39 +0000 (+0000) Subject: add support for "subtree-exclude" X-Git-Tag: OPENLDAP_REL_ENG_2_4_BP~183 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=af0d2b1d2a34679d36facb22392d1a867ccada84;p=openldap add support for "subtree-exclude" --- diff --git a/doc/man/man5/slapd-meta.5 b/doc/man/man5/slapd-meta.5 index 3b07e0330f..2bf1e8a0e8 100644 --- a/doc/man/man5/slapd-meta.5 +++ b/doc/man/man5/slapd-meta.5 @@ -184,6 +184,15 @@ causes \fIl2.foo.com\fP to be contacted whenever \fIl1.foo.com\fP does not respond. .RE +.TP +.B subtree-exclude "" +This directive instructs back-meta to ignore the current target +for operations whose requestDN is subordinate to +.BR DN . +There may be multiple occurrences of the +.B subtree-exclude +directive for each of the targets. + .TP .B acl-authcDN "" DN which is used to query the target server for acl checking, diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 76e68f4af6..2cf8369c7c 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -207,6 +207,7 @@ typedef struct metaconn_t { typedef struct metatarget_t { char *mt_uri; + BerVarray mt_subtree_exclude; int mt_scope; struct berval mt_psuffix; /* pretty suffix */ @@ -387,6 +388,7 @@ extern int meta_back_is_candidate( struct berval *nsuffix, int suffixscope, + BerVarray subtree_exclude, struct berval *ndn, int scope ); diff --git a/servers/slapd/back-meta/candidates.c b/servers/slapd/back-meta/candidates.c index e78b20602d..1986ab3bd6 100644 --- a/servers/slapd/back-meta/candidates.c +++ b/servers/slapd/back-meta/candidates.c @@ -61,10 +61,21 @@ int meta_back_is_candidate( struct berval *nsuffix, int suffixscope, + BerVarray subtree_exclude, struct berval *ndn, int scope ) { if ( dnIsSuffix( ndn, nsuffix ) ) { + if ( subtree_exclude ) { + int i; + + for ( i = 0; !BER_BVISNULL( &subtree_exclude[ i ] ); i++ ) { + if ( dnIsSuffix( ndn, &subtree_exclude[ i ] ) ) { + return META_NOT_CANDIDATE; + } + } + } + switch ( suffixscope ) { case LDAP_SCOPE_SUBTREE: default: @@ -128,6 +139,7 @@ meta_back_select_unique_candidate( for ( i = 0; i < mi->mi_ntargets; ++i ) { if ( meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix, mi->mi_targets[ i ].mt_scope, + mi->mi_targets[ i ].mt_subtree_exclude, ndn, LDAP_SCOPE_BASE ) ) { if ( candidate == META_TARGET_NONE ) { diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 248fe7e36e..a977de33e5 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -280,6 +280,81 @@ meta_back_db_config( } #endif + /* subtree-exclude */ + } else if ( strcasecmp( argv[ 0 ], "subtree-exclude" ) == 0 ) { + int i = mi->mi_ntargets - 1; + struct berval dn, ndn; + + if ( i < 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: need \"uri\" directive first\n", + fname, lineno, 0 ); + return 1; + } + + switch ( argc ) { + case 1: + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing DN in \"subtree-exclude \" line\n", + fname, lineno, 0 ); + return 1; + + case 2: + break; + + default: + Debug( LDAP_DEBUG_ANY, + "%s: line %d: too many args in \"subtree-exclude \" line\n", + fname, lineno, 0 ); + return 1; + } + + ber_str2bv( argv[ 1 ], 0, 0, &dn ); + if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) + != LDAP_SUCCESS ) + { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "subtree-exclude DN=\"%s\" is invalid\n", + fname, lineno, argv[ 1 ] ); + return( 1 ); + } + + if ( !dnIsSuffix( &ndn, &mi->mi_targets[ i ].mt_nsuffix ) ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "subtree-exclude DN=\"%s\" " + "must be subtree of target\n", + fname, lineno, argv[ 1 ] ); + ber_memfree( ndn.bv_val ); + return( 1 ); + } + + if ( mi->mi_targets[ i ].mt_subtree_exclude != NULL ) { + int j; + + for ( j = 0; !BER_BVISNULL( &mi->mi_targets[ i ].mt_subtree_exclude[ j ] ); j++ ) + { + if ( dnIsSuffix( &mi->mi_targets[ i ].mt_subtree_exclude[ j ], &ndn ) ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "subtree-exclude DN=\"%s\" " + "is suffix of another subtree-exclude\n", + fname, lineno, argv[ 1 ] ); + ber_memfree( mi->mi_targets[ i ].mt_subtree_exclude[ j ].bv_val ); + mi->mi_targets[ i ].mt_subtree_exclude[ j ] = ndn; + return( 0 ); + + } else if ( dnIsSuffix( &ndn, &mi->mi_targets[ i ].mt_subtree_exclude[ j ] ) ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "another subtree-exclude is suffix of " + "subtree-exclude DN=\"%s\"\n", + fname, lineno, argv[ 1 ] ); + ber_memfree( ndn.bv_val ); + return( 0 ); + } + } + } + + ber_bvarray_add( &mi->mi_targets[ i ].mt_subtree_exclude, &ndn ); + /* default target directive */ } else if ( strcasecmp( argv[ 0 ], "default-target" ) == 0 ) { int i = mi->mi_ntargets - 1; @@ -495,8 +570,7 @@ meta_back_db_config( /* FIXME: some day we'll need to throw an error */ } - dn.bv_val = argv[ 1 ]; - dn.bv_len = strlen( argv[ 1 ] ); + ber_str2bv( argv[ 1 ], 0, 0, &dn ); if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn, NULL ) != LDAP_SUCCESS ) { diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 640a7ca16c..7af76de199 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -650,6 +650,7 @@ meta_back_get_candidate( if ( mi->mi_defaulttarget != META_DEFAULT_TARGET_NONE && meta_back_is_candidate( &mi->mi_targets[ mi->mi_defaulttarget ].mt_nsuffix, mi->mi_targets[ mi->mi_defaulttarget ].mt_scope, + mi->mi_targets[ mi->mi_defaulttarget ].mt_subtree_exclude, ndn, op->o_tag == LDAP_REQ_SEARCH ? op->ors_scope : LDAP_SCOPE_BASE ) ) { candidate = mi->mi_defaulttarget; @@ -1094,6 +1095,7 @@ retry_lock: if ( i == cached || meta_back_is_candidate( &mt->mt_nsuffix, mt->mt_scope, + mt->mt_subtree_exclude, &op->o_req_ndn, LDAP_SCOPE_SUBTREE ) ) {