]> git.sur5r.net Git - openldap/commitdiff
ITS#6442
authorQuanah Gibson-Mount <quanah@openldap.org>
Thu, 15 Apr 2010 00:59:07 +0000 (00:59 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 15 Apr 2010 00:59:07 +0000 (00:59 +0000)
20 files changed:
CHANGES
doc/devel/toolargs
doc/man/man8/slapcat.8
doc/man/man8/slapschema.8
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c
servers/slapd/back-ldif/ldif.c
servers/slapd/back-monitor/init.c
servers/slapd/back-null/null.c
servers/slapd/backend.c
servers/slapd/backglue.c
servers/slapd/bconfig.c
servers/slapd/proto-slap.h
servers/slapd/slap.h
servers/slapd/slapcat.c
servers/slapd/slapcommon.c
servers/slapd/slapcommon.h
servers/slapd/slapindex.c
servers/slapd/slapschema.c

diff --git a/CHANGES b/CHANGES
index 317533e3fc83946d3a441ff3bdaa93b30e329e97..96047ce9dfd908aafad7204fa50c869db1015b73 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@ OpenLDAP 2.4 Change Log
 
 OpenLDAP 2.4.22 Engineering
        Added slapd SLAP_SCHEMA_EXPOSE flag for hidden schema elements (ITS#6435)
+       Added slapd tools selective iterations (ITS#6442)
        Added slapo-pbind
        Fixed libldap GnuTLS serial length (ITS#6460)
        Fixed slapd certificateListValidate (ITS#6466)
index 995e70c5e729c1f163cc9567bd1623b1c9bed605..eae05c953e58dad8618b336ac17974acdfd0664c 100644 (file)
@@ -2,11 +2,11 @@ Tools           ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
 slapacl            D F              U  X   b d f        o     uv
 slapadd              F            S        bcd fg  j l no q s uvw
 slapauth             F      M    R  U  X     d f        o      v
-slapcat              F                    abcd fg    l no   s  v
+slapcat              F H                  abcd fg    l no   s  v
 slapdn               F       N P             d f        o      v
 slapindex            F                     bcd fg      no q  t v
 slappasswd                         T        c    h          s uv
-slapschema          F                    abcd fg    l no   s  v
+slapschema          F H                  abcd fg    l no   s  v
 slaptest             F          Q            d f       no     uv
 
 * General flags:
index e6c81897537896c0380b60653250db8ab152260c..4673e49118529f42f6aced4d5655b1cf1774151c 100644 (file)
@@ -21,6 +21,8 @@ slapcat \- SLAPD database to LDIF utility
 [\c
 .BR \-g ]
 [\c
+.BI \-H URI\fR]
+[\c
 .BI \-l ldif-file\fR]
 [\c
 .BI \-n dbnum\fR]
@@ -69,6 +71,7 @@ slapcat \-a \\
 
 will dump all but the "ou=People,dc=example,dc=com" subtree
 of the "dc=example,dc=com" database.
+Deprecated; use \fB-H\fP \fIldap:///???(filter)\fP instead.
 .TP
 .BI \-b \ suffix 
 Use the specified \fIsuffix\fR to determine which database to
@@ -109,6 +112,9 @@ default config file is ignored.
 disable subordinate gluing.  Only the specified database will be
 processed, and not its glued subordinates (if any).
 .TP
+.B \-H \ URI
+use dn, scope and filter from URI to only handle matching entries.
+.TP
 .BI \-l \ ldif-file
 Write LDIF to specified file instead of standard output.
 .TP
@@ -147,6 +153,7 @@ Implies \fB\-b\fP \fIsubtree-dn\fP if no
 or
 .B \-n
 option is given.
+Deprecated; use \fB-H\fP \fIldap:///subtree-dn\fP instead.
 .TP
 .B \-v
 Enable verbose mode.
index 5d89919b4c1691834bcc64017f7357f1e4237e63..72a4624084896183c72efce5025edfe2b956d845 100644 (file)
@@ -21,6 +21,8 @@ slapschema \- SLAPD in-database schema checking utility
 [\c
 .BR \-g ]
 [\c
+.BI \-H URI\fR]
+[\c
 .BI \-l error-file\fR]
 [\c
 .BI \-n dbnum\fR]
@@ -72,6 +74,7 @@ slapschema \-a \\
 
 will check all but the "ou=People,dc=example,dc=com" subtree
 of the "dc=example,dc=com" database.
+Deprecated; use \fB-H\fP \fIldap:///???(filter)\fP instead.
 .TP
 .BI \-b \ suffix 
 Use the specified \fIsuffix\fR to determine which database to
@@ -112,6 +115,9 @@ default config file is ignored.
 disable subordinate gluing.  Only the specified database will be
 processed, and not its glued subordinates (if any).
 .TP
+.B \-H \ URI
+use dn, scope and filter from URI to only handle matching entries.
+.TP
 .BI \-l \ error-file
 Write errors to specified file instead of standard output.
 .TP
@@ -149,6 +155,7 @@ Implies \fB\-b\fP \fIsubtree-dn\fP if no
 nor
 .B \-n
 option is given.
+Deprecated; use \fB-H\fP \fIldap:///subtree-dn\fP instead.
 .TP
 .B \-v
 Enable verbose mode.
index e824caea5fdd458c86640445dc78bc76ffa67d0c..9bb102404fb92c3f08851f5dde3b064dc5aba276 100644 (file)
@@ -830,7 +830,8 @@ bdb_back_initialize(
         */
        bi->bi_tool_entry_open = bdb_tool_entry_open;
        bi->bi_tool_entry_close = bdb_tool_entry_close;
-       bi->bi_tool_entry_first = bdb_tool_entry_next;
+       bi->bi_tool_entry_first = backend_tool_entry_first;
+       bi->bi_tool_entry_first_x = bdb_tool_entry_first_x;
        bi->bi_tool_entry_next = bdb_tool_entry_next;
        bi->bi_tool_entry_get = bdb_tool_entry_get;
        bi->bi_tool_entry_put = bdb_tool_entry_put;
index 278d7503fd0cdabf932569f60665306122afe1d1..72d7f80336bc6b5ccbd1053c9252f5ef358f692f 100644 (file)
@@ -627,6 +627,7 @@ bdb_trans_backoff( int num_retries );
 #define bdb_hasSubordinates            BDB_SYMBOL(hasSubordinates)
 #define bdb_tool_entry_open            BDB_SYMBOL(tool_entry_open)
 #define bdb_tool_entry_close           BDB_SYMBOL(tool_entry_close)
+#define bdb_tool_entry_first_x         BDB_SYMBOL(tool_entry_first_x)
 #define bdb_tool_entry_next            BDB_SYMBOL(tool_entry_next)
 #define bdb_tool_entry_get             BDB_SYMBOL(tool_entry_get)
 #define bdb_tool_entry_put             BDB_SYMBOL(tool_entry_put)
@@ -657,6 +658,7 @@ extern BI_has_subordinates          bdb_hasSubordinates;
 /* tools.c */
 extern BI_tool_entry_open              bdb_tool_entry_open;
 extern BI_tool_entry_close             bdb_tool_entry_close;
+extern BI_tool_entry_first_x           bdb_tool_entry_first_x;
 extern BI_tool_entry_next              bdb_tool_entry_next;
 extern BI_tool_entry_get               bdb_tool_entry_get;
 extern BI_tool_entry_put               bdb_tool_entry_put;
index b6a30dbca8082acc03aaba842c946daf10f6eb3d..3bb4117c575e35f153c04b8c5dd0609618a26e97 100644 (file)
@@ -42,6 +42,11 @@ static unsigned nholes;
 
 static int index_nattrs;
 
+static struct berval   *tool_base;
+static int             tool_scope;
+static Filter          *tool_filter;
+static Entry           *tool_next_entry;
+
 #ifdef BDB_TOOL_IDL_CACHING
 #define bdb_tool_idl_cmp               BDB_SYMBOL(tool_idl_cmp)
 #define bdb_tool_idl_flush_one         BDB_SYMBOL(tool_idl_flush_one)
@@ -91,6 +96,9 @@ static void * bdb_tool_trickle_task( void *ctx, void *ptr );
 
 static void * bdb_tool_index_task( void *ctx, void *ptr );
 
+static int
+bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep );
+
 int bdb_tool_entry_open(
        BackendDB *be, int mode )
 {
@@ -187,6 +195,20 @@ int bdb_tool_entry_close(
        return 0;
 }
 
+ID
+bdb_tool_entry_first_x(
+       BackendDB *be,
+       struct berval *base,
+       int scope,
+       Filter *f )
+{
+       tool_base = base;
+       tool_scope = scope;
+       tool_filter = f;
+       
+       return bdb_tool_entry_next( be );
+}
+
 ID bdb_tool_entry_next(
        BackendDB *be )
 {
@@ -198,6 +220,7 @@ ID bdb_tool_entry_next(
        assert( slapMode & SLAP_TOOL_MODE );
        assert( bdb != NULL );
 
+next:;
        /* Get the header */
        data.ulen = data.dlen = sizeof( ehbuf );
        data.data = ehbuf;
@@ -224,6 +247,47 @@ ID bdb_tool_entry_next(
 
        BDB_DISK2ID( key.data, &id );
        previd = id;
+
+       if ( tool_filter || tool_base ) {
+               static Operation op = {0};
+               static Opheader ohdr = {0};
+
+               op.o_hdr = &ohdr;
+               op.o_bd = be;
+               op.o_tmpmemctx = NULL;
+               op.o_tmpmfuncs = &ch_mfuncs;
+
+               if ( tool_next_entry ) {
+                       bdb_entry_release( &op, tool_next_entry, 0 );
+                       tool_next_entry = NULL;
+               }
+
+               rc = bdb_tool_entry_get_int( be, id, &tool_next_entry );
+               if ( rc == LDAP_NO_SUCH_OBJECT ) {
+                       goto next;
+               }
+
+               assert( tool_next_entry != NULL );
+
+#ifdef BDB_HIER
+               /* TODO: needed until BDB_HIER is handled accordingly
+                * in bdb_tool_entry_get_int() */
+               if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) )
+               {
+                       bdb_entry_release( &op, tool_next_entry, 0 );
+                       tool_next_entry = NULL;
+                       goto next;
+               }
+#endif
+
+               if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE )
+               {
+                       bdb_entry_release( &op, tool_next_entry, 0 );
+                       tool_next_entry = NULL;
+                       goto next;
+               }
+       }
+
        return id;
 }
 
@@ -253,7 +317,8 @@ ID bdb_tool_dn2id_get(
        return ei->bei_id;
 }
 
-Entry* bdb_tool_entry_get( BackendDB *be, ID id )
+static int
+bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep )
 {
        Entry *e = NULL;
        char *dptr;
@@ -262,6 +327,12 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
        assert( be != NULL );
        assert( slapMode & SLAP_TOOL_MODE );
 
+       if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) {
+               *ep = tool_next_entry;
+               tool_next_entry = NULL;
+               return LDAP_SUCCESS;
+       }
+
        if ( id != previd ) {
                data.ulen = data.dlen = sizeof( ehbuf );
                data.data = ehbuf;
@@ -269,7 +340,10 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
 
                BDB_ID2DISK( id, &nid );
                rc = cursor->c_get( cursor, &key, &data, DB_SET );
-               if ( rc ) goto done;
+               if ( rc ) {
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
        }
 
        /* Get the header */
@@ -279,13 +353,19 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
        rc = entry_header( &eh );
        eoff = eh.data - eh.bv.bv_val;
        eh.bv.bv_val = dptr;
-       if ( rc ) goto done;
+       if ( rc ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
 
        /* Get the size */
        data.flags &= ~DB_DBT_PARTIAL;
        data.ulen = 0;
-    rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-       if ( rc != DB_BUFFER_SMALL ) goto done;
+       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+       if ( rc != DB_BUFFER_SMALL ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
 
        /* Allocate a block and retrieve the data */
        eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
@@ -297,8 +377,23 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
        /* Skip past already parsed nattr/nvals */
        eh.data += eoff;
 
-    rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-       if ( rc ) goto done;
+       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+       if ( rc ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
+
+#ifndef BDB_HIER
+       /* TODO: handle BDB_HIER accordingly */
+       if ( tool_base != NULL ) {
+               struct berval ndn;
+               entry_decode_dn( &eh, NULL, &ndn );
+
+               if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) {
+                       return LDAP_NO_SUCH_OBJECT;
+               }
+       }
+#endif
 
 #ifdef SLAP_ZONE_ALLOC
        /* FIXME: will add ctx later */
@@ -334,7 +429,23 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
 #endif
        }
 done:
-       return e;
+       if ( e != NULL ) {
+               *ep = e;
+       }
+
+       return rc;
+}
+
+Entry*
+bdb_tool_entry_get( BackendDB *be, ID id )
+{
+       Entry *e = NULL;
+       int rc;
+
+       rc = bdb_tool_entry_get_int( be, id, &e );
+       if ( rc == LDAP_SUCCESS ) {
+               return e;
+       }
 }
 
 static int bdb_tool_next_id(
@@ -610,6 +721,9 @@ int bdb_tool_entry_reindex(
        Operation op = {0};
        Opheader ohdr = {0};
 
+       assert( tool_base == NULL );
+       assert( tool_filter == NULL );
+
        Debug( LDAP_DEBUG_ARGS,
                "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
                (long) id, 0, 0 );
index f376e16387b0e01c0f5152becb532303495d9895..6d4cc61030b5210ac124fb0612a473b7efd73171 100644 (file)
@@ -37,6 +37,9 @@ struct ldif_tool {
        ID              ecount;                         /* number of entries */
        ID              ecurrent;                       /* bi_tool_entry_next() position */
 #      define  ENTRY_BUFF_INCREMENT 500 /* initial entries[] length */
+       struct berval   *tl_base;
+       int             tl_scope;
+       Filter          *tl_filter;
 };
 
 /* Per-database data */
@@ -1581,17 +1584,38 @@ ldif_tool_entry_next( BackendDB *be )
 {
        struct ldif_tool *tl = &((struct ldif_info *) be->be_private)->li_tool;
 
-       if ( tl->ecurrent >= tl->ecount )
-               return NOID;
-       else
-               return ++tl->ecurrent;
+       do {
+               Entry *e = tl->entries[ tl->ecurrent ];
+
+               if ( tl->ecurrent >= tl->ecount ) {
+                       return NOID;
+               }
+
+               ++tl->ecurrent;
+
+               if ( tl->tl_base && !dnIsSuffixScope( &e->e_nname, tl->tl_base, tl->tl_scope ) ) {
+                       continue;
+               }
+
+               if ( tl->tl_filter && test_filter( NULL, e, tl->tl_filter  ) != LDAP_COMPARE_TRUE ) {
+                       continue;
+               }
+
+               break;
+       } while ( 1 );
+
+       return tl->ecurrent;
 }
 
 static ID
-ldif_tool_entry_first( BackendDB *be )
+ldif_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
 {
        struct ldif_tool *tl = &((struct ldif_info *) be->be_private)->li_tool;
 
+       tl->tl_base = base;
+       tl->tl_scope = scope;
+       tl->tl_filter = f;
+
        if ( tl->entries == NULL ) {
                Operation op = {0};
 
@@ -1740,7 +1764,8 @@ ldif_back_initialize( BackendInfo *bi )
 
        bi->bi_tool_entry_open = ldif_tool_entry_open;
        bi->bi_tool_entry_close = ldif_tool_entry_close;
-       bi->bi_tool_entry_first = ldif_tool_entry_first;
+       bi->bi_tool_entry_first = backend_tool_entry_first;
+       bi->bi_tool_entry_first_x = ldif_tool_entry_first_x;
        bi->bi_tool_entry_next = ldif_tool_entry_next;
        bi->bi_tool_entry_get = ldif_tool_entry_get;
        bi->bi_tool_entry_put = ldif_tool_entry_put;
index 33e680e90d001d9c6360074deeeae049d06a9db7..8dc5a429ada8506030b7afc7b94768bca6298b16 100644 (file)
@@ -2061,6 +2061,7 @@ monitor_back_initialize(
        bi->bi_tool_entry_open = 0;
        bi->bi_tool_entry_close = 0;
        bi->bi_tool_entry_first = 0;
+       bi->bi_tool_entry_first_x = 0;
        bi->bi_tool_entry_next = 0;
        bi->bi_tool_entry_get = 0;
        bi->bi_tool_entry_put = 0;
index 7df6cf907d6211e3356adfdd1efd42428d4449be..dca92ac2494de1bb92fedbd4f1e159654c922407 100644 (file)
@@ -254,6 +254,12 @@ null_tool_entry_close( BackendDB *be )
        return 0;
 }
 
+static ID
+null_tool_entry_first_x( BackendDB *be, struct berval *base, int scope, Filter *f )
+{
+       return NOID;
+}
+
 static ID
 null_tool_entry_next( BackendDB *be )
 {
@@ -392,7 +398,8 @@ null_back_initialize( BackendInfo *bi )
 
        bi->bi_tool_entry_open = null_tool_entry_open;
        bi->bi_tool_entry_close = null_tool_entry_close;
-       bi->bi_tool_entry_first = null_tool_entry_next;
+       bi->bi_tool_entry_first = backend_tool_entry_first;
+       bi->bi_tool_entry_first_x = null_tool_entry_first_x;
        bi->bi_tool_entry_next = null_tool_entry_next;
        bi->bi_tool_entry_get = null_tool_entry_get;
        bi->bi_tool_entry_put = null_tool_entry_put;
index fd03b845c08d2ecd6582eb05dbe32a3e100150fa..6c197c09544c2cf4685192ca71050a3fc15d4edf 100644 (file)
@@ -1965,3 +1965,12 @@ int backend_operational( Operation *op, SlapReply *rs )
        return rc;
 }
 
+/* helper that calls the bi_tool_entry_first_x() variant with default args;
+ * use to initialize a backend's bi_tool_entry_first() when appropriate
+ */
+ID
+backend_tool_entry_first( BackendDB *be )
+{
+       return be->bd_info->bi_tool_entry_first_x( be,
+               NULL, LDAP_SCOPE_DEFAULT, NULL );
+}
index cc104ce3ca762eefc9d8e34462a78b879a13ecb1..e37176f5ad4fc7a44e2309dd827716d814a8e139 100644 (file)
@@ -735,6 +735,10 @@ glue_entry_release_rw (
        return rc;
 }
 
+static struct berval *glue_base;
+static int glue_scope;
+static Filter *glue_filter;
+
 static ID
 glue_tool_entry_first (
        BackendDB *b0
@@ -785,6 +789,66 @@ glue_tool_entry_first (
        return rc;
 }
 
+static ID
+glue_tool_entry_first_x (
+       BackendDB *b0,
+       struct berval *base,
+       int scope,
+       Filter *f
+)
+{
+       slap_overinst   *on = glue_tool_inst( b0->bd_info );
+       glueinfo                *gi = on->on_bi.bi_private;
+       int i;
+       ID rc;
+
+       glue_base = base;
+       glue_scope = scope;
+       glue_filter = f;
+
+       /* If we're starting from scratch, start at the most general */
+       if (!glueBack) {
+               if ( toolDB.be_entry_open && toolDB.be_entry_first_x ) {
+                       glueBack = &toolDB;
+               } else {
+                       for (i = gi->gi_nodes-1; i >= 0; i--) {
+                               if (gi->gi_n[i].gn_be->be_entry_open &&
+                                       gi->gi_n[i].gn_be->be_entry_first_x)
+                               {
+                                       glueBack = gi->gi_n[i].gn_be;
+                                       break;
+                               }
+                       }
+               }
+       }
+       if (!glueBack || !glueBack->be_entry_open || !glueBack->be_entry_first_x ||
+               glueBack->be_entry_open (glueBack, glueMode) != 0)
+               return NOID;
+
+       rc = glueBack->be_entry_first_x (glueBack,
+               glue_base, glue_scope, glue_filter);
+       while ( rc == NOID ) {
+               if ( glueBack && glueBack->be_entry_close )
+                       glueBack->be_entry_close (glueBack);
+               for (i=0; i<gi->gi_nodes; i++) {
+                       if (gi->gi_n[i].gn_be == glueBack)
+                               break;
+               }
+               if (i == 0) {
+                       glueBack = GLUEBACK_DONE;
+                       break;
+               } else {
+                       glueBack = gi->gi_n[i-1].gn_be;
+                       rc = glue_tool_entry_first_x (b0,
+                               glue_base, glue_scope, glue_filter);
+                       if ( glueBack == GLUEBACK_DONE ) {
+                               break;
+                       }
+               }
+       }
+       return rc;
+}
+
 static ID
 glue_tool_entry_next (
        BackendDB *b0
@@ -813,7 +877,15 @@ glue_tool_entry_next (
                        break;
                } else {
                        glueBack = gi->gi_n[i-1].gn_be;
-                       rc = glue_tool_entry_first (b0);
+                       if ( glue_base || glue_filter ) {
+                               /* using entry_first_x() */
+                               rc = glue_tool_entry_first_x (b0,
+                                       glue_base, glue_scope, glue_filter);
+
+                       } else {
+                               /* using entry_first() */
+                               rc = glue_tool_entry_first (b0);
+                       }
                        if ( glueBack == GLUEBACK_DONE ) {
                                break;
                        }
@@ -1012,6 +1084,9 @@ glue_db_init(
                oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
        if ( bi->bi_tool_entry_first )
                oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
+       /* FIXME: check whether all support bi_tool_entry_first_x() ? */
+       if ( bi->bi_tool_entry_first_x )
+               oi->oi_bi.bi_tool_entry_first_x = glue_tool_entry_first_x;
        if ( bi->bi_tool_entry_next )
                oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
        if ( bi->bi_tool_entry_get )
index 027cc2a6448d94c1273e56c13c5c68f10fe52680..8626f2170377329d1a4e3c9c1323a2e774412922 100644 (file)
@@ -6789,10 +6789,30 @@ config_tool_entry_first( BackendDB *be )
        CfBackInfo *cfb = be->be_private;
        BackendInfo *bi = cfb->cb_db.bd_info;
 
-       if ( bi && bi->bi_tool_entry_first )
+       if ( bi && bi->bi_tool_entry_first ) {
                return bi->bi_tool_entry_first( &cfb->cb_db );
-       else
-               return NOID;
+       }
+       if ( bi && bi->bi_tool_entry_first_x ) {
+               return bi->bi_tool_entry_first_x( &cfb->cb_db,
+                       NULL, LDAP_SCOPE_DEFAULT, NULL );
+       }
+       return NOID;
+}
+
+static ID
+config_tool_entry_first_x(
+       BackendDB *be,
+       struct berval *base,
+       int scope,
+       Filter *f )
+{
+       CfBackInfo *cfb = be->be_private;
+       BackendInfo *bi = cfb->cb_db.bd_info;
+
+       if ( bi && bi->bi_tool_entry_first_x ) {
+               return bi->bi_tool_entry_first_x( &cfb->cb_db, base, scope, f );
+       }
+       return NOID;
 }
 
 static ID
@@ -7039,6 +7059,7 @@ config_back_initialize( BackendInfo *bi )
        bi->bi_tool_entry_open = config_tool_entry_open;
        bi->bi_tool_entry_close = config_tool_entry_close;
        bi->bi_tool_entry_first = config_tool_entry_first;
+       bi->bi_tool_entry_first_x = config_tool_entry_first_x;
        bi->bi_tool_entry_next = config_tool_entry_next;
        bi->bi_tool_entry_get = config_tool_entry_get;
        bi->bi_tool_entry_put = config_tool_entry_put;
index 8bf3580084afdc7febf55f54602804c65276f6d3..e27c119c67b3c3fee7956dbe3459df3a01c8a222 100644 (file)
@@ -428,6 +428,8 @@ LDAP_SLAPD_F (int) backend_operational LDAP_P((
        SlapReply *rs 
 ));
 
+LDAP_SLAPD_F (ID) backend_tool_entry_first LDAP_P(( BackendDB *be ));
+
 LDAP_SLAPD_V(BackendInfo) slap_binfo[]; 
 
 /*
index a02991cd419b33de40998a8582a5e2d4c54ef9b2..b8147826091f9aca6b555614c25e590d7644aa26 100644 (file)
@@ -1788,6 +1788,7 @@ struct BackendDB {
 #define                be_entry_open bd_info->bi_tool_entry_open
 #define                be_entry_close bd_info->bi_tool_entry_close
 #define                be_entry_first bd_info->bi_tool_entry_first
+#define                be_entry_first_x bd_info->bi_tool_entry_first_x
 #define                be_entry_next bd_info->bi_tool_entry_next
 #define                be_entry_reindex bd_info->bi_tool_entry_reindex
 #define                be_entry_get bd_info->bi_tool_entry_get
@@ -2158,6 +2159,7 @@ typedef BI_conn_func BI_connection_destroy;
 typedef int (BI_tool_entry_open) LDAP_P(( BackendDB *be, int mode ));
 typedef int (BI_tool_entry_close) LDAP_P(( BackendDB *be ));
 typedef ID (BI_tool_entry_first) LDAP_P(( BackendDB *be ));
+typedef ID (BI_tool_entry_first_x) LDAP_P(( BackendDB *be, struct berval *base, int scope, Filter *f ));
 typedef ID (BI_tool_entry_next) LDAP_P(( BackendDB *be ));
 typedef Entry* (BI_tool_entry_get) LDAP_P(( BackendDB *be, ID id ));
 typedef ID (BI_tool_entry_put) LDAP_P(( BackendDB *be, Entry *e, 
@@ -2257,7 +2259,8 @@ struct BackendInfo {
        /* hooks for slap tools */
        BI_tool_entry_open      *bi_tool_entry_open;
        BI_tool_entry_close     *bi_tool_entry_close;
-       BI_tool_entry_first     *bi_tool_entry_first;
+       BI_tool_entry_first     *bi_tool_entry_first;   /* deprecated */
+       BI_tool_entry_first_x   *bi_tool_entry_first_x;
        BI_tool_entry_next      *bi_tool_entry_next;
        BI_tool_entry_get       *bi_tool_entry_get;
        BI_tool_entry_put       *bi_tool_entry_put;
index 98364969f6c7695258908c2fe4e36dfeefa66d2c..af1cae4993e4f17c6d4703ffc382c0659ceaea56 100644 (file)
@@ -47,9 +47,13 @@ slapcat( int argc, char **argv )
        int rc = EXIT_SUCCESS;
        Operation op = {0};
        const char *progname = "slapcat";
+       int requestBSF;
+       int doBSF = 0;
 
        slap_tool_init( progname, SLAPCAT, argc, argv );
 
+       requestBSF = ( sub_ndn.bv_len || filter );
+
 #ifdef SIGPIPE
        (void) SIGNAL( SIGPIPE, slapcat_sig );
 #endif
@@ -61,7 +65,7 @@ slapcat( int argc, char **argv )
 
        if( !be->be_entry_open ||
                !be->be_entry_close ||
-               !be->be_entry_first ||
+               !( be->be_entry_first_x || be->be_entry_first ) ||
                !be->be_entry_next ||
                !be->be_entry_get )
        {
@@ -77,9 +81,22 @@ slapcat( int argc, char **argv )
        }
 
        op.o_bd = be;
-       for ( id = be->be_entry_first( be );
-               id != NOID;
-               id = be->be_entry_next( be ) )
+       if ( !requestBSF && be->be_entry_first ) {
+               id = be->be_entry_first( be );
+
+       } else {
+               if ( be->be_entry_first_x ) {
+                       id = be->be_entry_first_x( be,
+                               sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );
+
+               } else {
+                       assert( be->be_entry_first != NULL );
+                       doBSF = 1;
+                       id = be->be_entry_first( be );
+               }
+       }
+
+       for ( ; id != NOID; id = be->be_entry_next( be ) )
        {
                char *data;
                int len;
@@ -96,20 +113,24 @@ slapcat( int argc, char **argv )
                        break;
                }
 
-               if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
-                       be_entry_release_r( &op, e );
-                       continue;
-               }
-
-               if( filter != NULL ) {
-                       int rc = test_filter( NULL, e, filter );
-                       if( rc != LDAP_COMPARE_TRUE ) {
+               if ( doBSF ) {
+                       if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
+                       {
                                be_entry_release_r( &op, e );
                                continue;
                        }
+
+
+                       if ( filter != NULL ) {
+                               int rc = test_filter( NULL, e, filter );
+                               if ( rc != LDAP_COMPARE_TRUE ) {
+                                       be_entry_release_r( &op, e );
+                                       continue;
+                               }
+                       }
                }
 
-               if( verbose ) {
+               if ( verbose ) {
                        printf( "# id=%08lx\n", (long) id );
                }
 
index 71870e745c068a098c9ca2ef9c889c9da0998edb..f4e2eff51ce28df37aca66df7eabc84d63771f38 100644 (file)
@@ -80,7 +80,7 @@ usage( int tool, const char *progname )
 
        case SLAPCAT:
                options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
-                       " [-l ldiffile] [-a filter] [-s subtree]\n";
+                       " [-l ldiffile] [-a filter] [-s subtree] [-H url]\n";
                break;
 
        case SLAPDN:
@@ -97,7 +97,7 @@ usage( int tool, const char *progname )
 
        case SLAPSCHEMA:
                options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
-                       " [-l errorfile] [-a filter] [-s subtree]\n";
+                       " [-l errorfile] [-a filter] [-s subtree] [-H url]\n";
                break;
        }
 
@@ -247,13 +247,15 @@ slap_tool_init(
        leakfilename = NULL;
 #endif
 
+       scope = LDAP_SCOPE_DEFAULT;
+
        switch( tool ) {
        case SLAPADD:
                options = "b:cd:f:F:gj:l:n:o:qsS:uvw";
                break;
 
        case SLAPCAT:
-               options = "a:b:cd:f:F:gl:n:o:s:v";
+               options = "a:b:cd:f:F:gH:l:n:o:s:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
@@ -263,7 +265,7 @@ slap_tool_init(
                break;
 
        case SLAPSCHEMA:
-               options = "a:b:cd:f:F:gl:n:o:s:v";
+               options = "a:b:cd:f:F:gH:l:n:o:s:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
@@ -344,6 +346,52 @@ slap_tool_init(
                        use_glue = 0;
                        break;
 
+               case 'H': {
+                       LDAPURLDesc *ludp;
+                       int rc;
+
+                       rc = ldap_url_parse_ext( optarg, &ludp,
+                               LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_NOEMPTY_DN );
+                       if ( rc != LDAP_URL_SUCCESS ) {
+                               usage( tool, progname );
+                       }
+
+                       /* don't accept host, port, attrs, extensions */
+                       if ( ldap_pvt_url_scheme2proto( ludp->lud_scheme ) != LDAP_PROTO_TCP ) {
+                               usage( tool, progname );
+                       }
+
+                       if ( ludp->lud_host != NULL ) {
+                               usage( tool, progname );
+                       }
+
+                       if ( ludp->lud_port != 0 ) {
+                               usage( tool, progname );
+                       }
+
+                       if ( ludp->lud_attrs != NULL ) {
+                               usage( tool, progname );
+                       }
+
+                       if ( ludp->lud_exts != NULL ) {
+                               usage( tool, progname );
+                       }
+
+                       if ( ludp->lud_dn != NULL && ludp->lud_dn[0] != '\0' ) {
+                               subtree = ludp->lud_dn;
+                               ludp->lud_dn = NULL;
+                       }
+
+                       if ( ludp->lud_filter != NULL && ludp->lud_filter[0] != '\0' ) {
+                               filterstr = ludp->lud_filter;
+                               ludp->lud_filter = NULL;
+                       }
+
+                       scope = ludp->lud_scope;
+
+                       ldap_free_urldesc( ludp );
+                       } break;
+
                case 'j':       /* jump to linenumber */
                        if ( lutil_atoi( &jumpline, optarg ) ) {
                                usage( tool, progname );
@@ -743,6 +791,17 @@ get_db:
                }
        }
 
+       if ( scope != LDAP_SCOPE_DEFAULT && BER_BVISNULL( &sub_ndn ) ) {
+               if ( be && be->be_nsuffix ) {
+                       ber_dupbv( &sub_ndn, be->be_nsuffix );
+
+               } else {
+                       fprintf( stderr,
+                               "<scope> needs a DN or a valid database\n" );
+                       exit( EXIT_FAILURE );
+               }
+       }
+
 startup:;
        if ( be ) {
                BackendDB *bdtmp;
@@ -833,3 +892,5 @@ int slap_tool_destroy( void )
        }
        return rc;
 }
+
+
index d354652e26fad6d14da34829cad63342652ff95a..dae63cd012c0cac2c078bcb19b9f2034366a49df 100644 (file)
@@ -43,8 +43,9 @@ typedef struct tool_vars {
        int tv_nosubordinates;
        int tv_dryrun;
        int tv_jumpline;
-       Filter *tv_filter;
        struct berval tv_sub_ndn;
+       int tv_scope;
+       Filter *tv_filter;
        struct LDIFFP   *tv_ldiffp;
        struct berval tv_baseDN;
        struct berval tv_authcDN;
@@ -76,8 +77,9 @@ extern tool_vars tool_globals;
 #define continuemode tool_globals.tv_continuemode
 #define nosubordinates tool_globals.tv_nosubordinates
 #define dryrun tool_globals.tv_dryrun
-#define filter tool_globals.tv_filter
 #define sub_ndn tool_globals.tv_sub_ndn
+#define scope tool_globals.tv_scope
+#define filter tool_globals.tv_filter
 #define ldiffp tool_globals.tv_ldiffp
 #define baseDN tool_globals.tv_baseDN
 #define authcDN tool_globals.tv_authcDN
index 2696c6b8e0422e8c28c2d111e2eeb2b11afe4f4f..3698ed0bb513234a52ef665309ad92486ea9d962 100644 (file)
@@ -43,7 +43,7 @@ slapindex( int argc, char **argv )
 
        if( !be->be_entry_open ||
                !be->be_entry_close ||
-               !be->be_entry_first ||
+               !( be->be_entry_first || be->be_entry_first_x ) ||
                !be->be_entry_next  ||
                !be->be_entry_reindex )
        {
@@ -77,11 +77,16 @@ slapindex( int argc, char **argv )
                        progname );
                exit( EXIT_FAILURE );
        }
-       
-       for ( id = be->be_entry_first( be );
-               id != NOID;
-               id = be->be_entry_next( be ) )
-       {
+
+       if ( be->be_entry_first ) {
+               id = be->be_entry_first( be );
+
+       } else {
+               assert( be->be_entry_first_x != NULL );
+               id = be->be_entry_first_x( be, NULL, LDAP_SCOPE_DEFAULT, NULL );
+       }
+
+       for ( ; id != NOID; id = be->be_entry_next( be ) ) {
                int rtn;
 
                if( verbose ) {
index a7aa035b6c1975725bb7a9517aec2284253ba82b..8ed4204a16ce8bba5463db9903a1495b85673670 100644 (file)
@@ -50,9 +50,13 @@ slapschema( int argc, char **argv )
        OperationBuffer opbuf;
        Operation *op = NULL;
        void *thrctx;
+       int requestBSF = 0;
+       int doBSF = 0;
 
        slap_tool_init( progname, SLAPCAT, argc, argv );
 
+       requestBSF = ( sub_ndn.bv_len || filter );
+
 #ifdef SIGPIPE
        (void) SIGNAL( SIGPIPE, slapcat_sig );
 #endif
@@ -64,7 +68,7 @@ slapschema( int argc, char **argv )
 
        if( !be->be_entry_open ||
                !be->be_entry_close ||
-               !be->be_entry_first ||
+               !( be->be_entry_first || be->be_entry_first_x ) ||
                !be->be_entry_next ||
                !be->be_entry_get )
        {
@@ -85,10 +89,23 @@ slapschema( int argc, char **argv )
        op->o_tmpmemctx = NULL;
        op->o_bd = be;
 
-       for ( id = be->be_entry_first( be );
-               id != NOID;
-               id = be->be_entry_next( be ) )
-       {
+
+       if ( !requestBSF && be->be_entry_first ) {
+               id = be->be_entry_first( be );
+
+       } else {
+               if ( be->be_entry_first_x ) {
+                       id = be->be_entry_first_x( be,
+                               sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );
+
+               } else {
+                       assert( be->be_entry_first != NULL );
+                       doBSF = 1;
+                       id = be->be_entry_first( be );
+               }
+       }
+
+       for ( ; id != NOID; id = be->be_entry_next( be ) ) {
                Entry* e;
                char textbuf[SLAP_TEXT_BUFLEN];
                size_t textlen = sizeof(textbuf);
@@ -105,17 +122,21 @@ slapschema( int argc, char **argv )
                        break;
                }
 
-               if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
-                       be_entry_release_r( op, e );
-                       continue;
-               }
-
-               if( filter != NULL ) {
-                       int rc = test_filter( NULL, e, filter );
-                       if( rc != LDAP_COMPARE_TRUE ) {
+               if ( doBSF ) {
+                       if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
+                       {
                                be_entry_release_r( op, e );
                                continue;
                        }
+
+
+                       if ( filter != NULL ) {
+                               int rc = test_filter( NULL, e, filter );
+                               if ( rc != LDAP_COMPARE_TRUE ) {
+                                       be_entry_release_r( op, e );
+                                       continue;
+                               }
+                       }
                }
 
                if( verbose ) {