mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-09 02:52:04 +08:00
implement support for selective iteration in slaptools (ITS#6442)
This commit is contained in:
parent
a4b109d034
commit
0cf528630f
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
|
@ -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[];
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ) {
|
||||
|
@ -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 ) {
|
||||
|
Loading…
Reference in New Issue
Block a user