]> git.sur5r.net Git - openldap/commitdiff
add support for "subtree-exclude"
authorPierangelo Masarati <ando@openldap.org>
Thu, 16 Feb 2006 01:26:39 +0000 (01:26 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 16 Feb 2006 01:26:39 +0000 (01:26 +0000)
doc/man/man5/slapd-meta.5
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c

index 3b07e0330f7e40dc8b464f638425829a262dbdf7..2bf1e8a0e83b1eda34e543577d498449ef400acc 100644 (file)
@@ -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 "<DN>"
+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 "<administrative DN for access control purposes>"
 DN which is used to query the target server for acl checking,
index 76e68f4af6875db28adb3be5a79070bb306a98a1..2cf8369c7ca5fc908fc17fd03958950849ec1563 100644 (file)
@@ -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 );
 
index e78b20602dc8ab5d4054a5467c32e4dcf1cda408..1986ab3bd6f45158343099039b1893463867fa8a 100644 (file)
@@ -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 ) {
index 248fe7e36e3a9d42894a11c47d8421393679ede4..a977de33e52505a497766a4e41eb4a5296348fb7 100644 (file)
@@ -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 <DN>\" line\n",
+                           fname, lineno, 0 );
+                       return 1;
+
+               case 2:
+                       break;
+
+               default:
+                       Debug( LDAP_DEBUG_ANY,
+       "%s: line %d: too many args in \"subtree-exclude <DN>\" 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 )
                {
index 640a7ca16c18f9d9a970ef190b7700b9583a6484..7af76de1993274b5549764b5384f95956bdd6874 100644 (file)
@@ -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 ) )
                        {