implement support for selective iteration in slaptools (ITS#6442)

This commit is contained in:
Pierangelo Masarati 2010-01-18 15:00:40 +00:00
parent a4b109d034
commit 0cf528630f
19 changed files with 445 additions and 61 deletions

View 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:

View 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.

View 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.

View 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;

View 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;

View 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 );

View 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;

View 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;

View 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;

View 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 );
}

View 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 )

View File

@ -6803,10 +6803,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
@ -7053,6 +7073,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;

View 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[];
/*

View File

@ -1795,6 +1795,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
@ -2165,6 +2166,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,
@ -2264,7 +2266,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;

View 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 );
}

View 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;
}

View 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

View 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 ) {

View 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 ) {