add support for extra ops after bind; allow to skip bind for slapd-search/read

This commit is contained in:
Pierangelo Masarati 2006-11-18 18:25:46 +00:00
parent 14e1feed1f
commit 17296f11e7
9 changed files with 450 additions and 193 deletions

View file

@ -320,7 +320,6 @@ do_addel(
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;

View file

@ -35,6 +35,7 @@
#include <ldap.h>
#include <lutil.h>
#include <lber_pvt.h>
#include <ldap_pvt.h>
#include "slapd-common.h"
@ -42,11 +43,13 @@
static int
do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
int force, int chaserefs, int noinit, LDAP **ldp );
int force, int chaserefs, int noinit, LDAP **ldp,
int action_type, void *action );
static int
do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
int maxloop, int force, int chaserefs, int noinit, int delay );
int maxloop, int force, int chaserefs, int noinit, int delay,
int action_type, void *action );
/* This program can be invoked two ways: if -D is used to specify a Bind DN,
* that DN will be used repeatedly for all of the Binds. If instead -b is used
@ -56,14 +59,20 @@ do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, cha
* assumed that the users are all onelevel children of the base.
*/
static void
usage( char *name )
usage( char *name, char opt )
{
if ( opt ) {
fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
name, opt );
}
fprintf( stderr, "usage: %s "
"[-H uri | -h <host> [-p port]] "
"[-D <dn> [-w <passwd>]] "
"[-b <baseDN> [-f <searchfilter>] [-a pwattr]] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-B <extra>[,...]] "
"[-F] "
"[-C] "
"[-I] "
@ -92,12 +101,26 @@ main( int argc, char **argv )
int noinit = 0;
int delay = 0;
/* extra action to do after bind... */
struct berval type[] = {
BER_BVC( "tester=" ),
BER_BVC( "add=" ),
BER_BVC( "bind=" ),
BER_BVC( "modify=" ),
BER_BVC( "modrdn=" ),
BER_BVC( "read=" ),
BER_BVC( "search=" ),
BER_BVNULL
};
LDAPURLDesc *extra_ludp = NULL;
tester_init( "slapd-bind", TESTER_BIND );
/* by default, tolerate invalid credentials */
tester_ignore_str2errlist( "INVALID_CREDENTIALS" );
while ( (i = getopt( argc, argv, "a:b:H:h:i:p:D:w:l:L:f:FIt:" )) != EOF ) {
while ( (i = getopt( argc, argv, "a:b:B:H:h:i:p:D:w:l:L:f:FIt:" )) != EOF ) {
switch( i ) {
case 'a':
pwattr = optarg;
@ -107,6 +130,48 @@ main( int argc, char **argv )
base = optarg;
break;
case 'B':
{
int c;
for ( c = 0; type[c].bv_val; c++ ) {
if ( strncasecmp( optarg, type[c].bv_val, type[c].bv_len ) == 0 )
{
break;
}
}
if ( type[c].bv_val == NULL ) {
usage( argv[0], 'B' );
}
switch ( c ) {
case TESTER_TESTER:
case TESTER_BIND:
/* invalid */
usage( argv[0], 'B' );
case TESTER_SEARCH:
{
if ( ldap_url_parse( &optarg[type[c].bv_len], &extra_ludp ) != LDAP_URL_SUCCESS )
{
usage( argv[0], 'B' );
}
} break;
case TESTER_ADDEL:
case TESTER_MODIFY:
case TESTER_MODRDN:
case TESTER_READ:
/* nothing to do */
break;
default:
assert( 0 );
}
} break;
case 'C':
chaserefs++;
break;
@ -125,7 +190,7 @@ main( int argc, char **argv )
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
usage( argv[0], 'p' );
}
break;
@ -140,13 +205,13 @@ main( int argc, char **argv )
case 'l': /* the number of loops */
if ( lutil_atoi( &loops, optarg ) != 0 ) {
usage( argv[0] );
usage( argv[0], 'l' );
}
break;
case 'L': /* the number of outerloops */
if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
usage( argv[0] );
usage( argv[0], 'L' );
}
break;
@ -166,18 +231,18 @@ main( int argc, char **argv )
case 't':
/* sleep between binds */
if ( lutil_atoi( &delay, optarg ) != 0 ) {
usage( argv[0] );
usage( argv[0], 't' );
}
break;
default:
usage( argv[0] );
usage( argv[0], i );
break;
}
}
if ( port == -1 && uri == NULL ) {
usage( argv[0] );
usage( argv[0], '\0' );
}
uri = tester_uri( uri, host, port );
@ -185,10 +250,10 @@ main( int argc, char **argv )
for ( i = 0; i < outerloops; i++ ) {
if ( base != NULL ) {
do_base( uri, dn, &pass, base, filter, pwattr, loops,
force, chaserefs, noinit, delay );
force, chaserefs, noinit, delay, -1, NULL );
} else {
do_bind( uri, dn, &pass, loops,
force, chaserefs, noinit, NULL );
force, chaserefs, noinit, NULL, -1, NULL );
}
}
@ -198,15 +263,62 @@ main( int argc, char **argv )
static int
do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
int force, int chaserefs, int noinit, LDAP **ldp )
int force, int chaserefs, int noinit, LDAP **ldp,
int action_type, void *action )
{
LDAP *ld = ldp ? *ldp : NULL;
int i, rc = -1;
pid_t pid = getpid();
if ( maxloop > 1 )
/* for internal search */
int timelimit = 0;
int sizelimit = 0;
switch ( action_type ) {
case -1:
break;
case TESTER_SEARCH:
{
LDAPURLDesc *ludp = (LDAPURLDesc *)action;
assert( action != NULL );
if ( ludp->lud_exts != NULL ) {
for ( i = 0; ludp->lud_exts[ i ] != NULL; i++ ) {
char *ext = ludp->lud_exts[ i ];
int crit = 0;
if (ext[0] == '!') {
crit++;
ext++;
}
if ( strncasecmp( ext, "x-timelimit=", STRLENOF( "x-timelimit=" ) ) == 0 ) {
if ( lutil_atoi( &timelimit, &ext[ STRLENOF( "x-timelimit=" ) ] ) && crit ) {
tester_error( "unable to parse critical extension x-timelimit" );
}
} else if ( strncasecmp( ext, "x-sizelimit=", STRLENOF( "x-sizelimit=" ) ) == 0 ) {
if ( lutil_atoi( &sizelimit, &ext[ STRLENOF( "x-sizelimit=" ) ] ) && crit ) {
tester_error( "unable to parse critical extension x-sizelimit" );
}
} else if ( crit ) {
tester_error( "unknown critical extension" );
}
}
}
} break;
default:
/* nothing to do yet */
break;
}
if ( maxloop > 1 ) {
fprintf( stderr, "PID=%ld - Bind(%d): dn=\"%s\".\n",
(long) pid, maxloop, dn );
}
for ( i = 0; i < maxloop; i++ ) {
if ( !noinit || ld == NULL ) {
@ -240,6 +352,35 @@ do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
}
}
switch ( action_type ) {
case -1:
break;
case TESTER_SEARCH:
{
LDAPURLDesc *ludp = (LDAPURLDesc *)action;
LDAPMessage *res = NULL;
struct timeval tv = { 0 }, *tvp = NULL;
if ( timelimit ) {
tv.tv_sec = timelimit;
tvp = &tv;
}
assert( action != NULL );
rc = ldap_search_ext_s( ld,
ludp->lud_dn, ludp->lud_scope,
ludp->lud_filter, ludp->lud_attrs, 0,
NULL, NULL, tvp, sizelimit, &res );
ldap_msgfree( res );
} break;
default:
/* nothing to do yet */
break;
}
if ( !noinit ) {
ldap_unbind_ext( ld, NULL, NULL );
@ -268,11 +409,11 @@ do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
static int
do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
int maxloop, int force, int chaserefs, int noinit, int delay )
int maxloop, int force, int chaserefs, int noinit, int delay,
int action_type, void *action )
{
LDAP *ld = NULL;
int i = 0;
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
ber_int_t msgid;
LDAPMessage *res, *msg;
@ -288,8 +429,6 @@ do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, cha
int version = LDAP_VERSION3;
char *nullstr = "";
srand( pid );
ldap_initialize( &ld, uri );
if ( ld == NULL ) {
tester_perror( "ldap_initialize", NULL );
@ -410,8 +549,8 @@ novals:;
cred = creds[j];
}
if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld )
&& !force )
if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld,
action_type, action ) && !force )
{
break;
}

View file

@ -31,6 +31,10 @@
#include "ldap_pvt.h"
#include "slapd-common.h"
/* global vars */
pid_t pid;
/* static vars */
static char progname[ BUFSIZ ];
tester_t progtype;
@ -208,7 +212,9 @@ tester_ignore_err( int err )
void
tester_init( const char *pname, tester_t ptype )
{
snprintf( progname, sizeof( progname ), "%s PID=%d", pname, getpid() );
pid = getpid();
srand( pid );
snprintf( progname, sizeof( progname ), "%s PID=%d", pname, pid );
progtype = ptype;
}

View file

@ -27,7 +27,8 @@ typedef enum {
TESTER_MODIFY,
TESTER_MODRDN,
TESTER_READ,
TESTER_SEARCH
TESTER_SEARCH,
TESTER_LAST
} tester_t;
extern void tester_init( const char *pname, tester_t ptype );
@ -38,4 +39,6 @@ extern void tester_ldap_error( LDAP *ld, const char *fname, const char *msg );
extern int tester_ignore_str2errlist( const char *err );
extern unsigned tester_ignore_err( int err );
extern pid_t pid;
#endif /* SLAPD_COMMON_H */

View file

@ -200,7 +200,6 @@ do_modify( char *uri, char *manager,
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
pid_t pid;
int rc = LDAP_SUCCESS;
struct ldapmod mod;
@ -208,8 +207,6 @@ do_modify( char *uri, char *manager,
char *values[2];
int version = LDAP_VERSION3;
pid = getpid();
values[0] = value;
values[1] = NULL;
mod.mod_op = LDAP_MOD_ADD;

View file

@ -183,14 +183,12 @@ do_modrdn( char *uri, char *manager,
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
pid_t pid;
char *DNs[2];
char *rdns[2];
int rc = LDAP_SUCCESS;
char *p1, *p2;
int version = LDAP_VERSION3;
pid = getpid();
DNs[0] = entry;
DNs[1] = strdup( entry );

View file

@ -40,12 +40,12 @@
static void
do_read( char *uri, char *manager, struct berval *passwd,
char *entry, LDAP **ld, int noattrs, int maxloop,
char *entry, LDAP **ld, int noattrs, int nobind, int maxloop,
int maxretries, int delay, int force, int chaserefs );
static void
do_random( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, int noattrs,
char *sbase, char *filter, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs );
static void
@ -60,6 +60,7 @@ usage( char *name )
"[-A] "
"[-C] "
"[-F] "
"[-N] "
"[-f filter] "
"[-i <ignore>] "
"[-l <loops>] "
@ -88,6 +89,7 @@ main( int argc, char **argv )
int force = 0;
int chaserefs = 0;
int noattrs = 0;
int nobind = 0;
tester_init( "slapd-read", TESTER_READ );
@ -116,6 +118,10 @@ main( int argc, char **argv )
tester_ignore_str2errlist( optarg );
break;
case 'N':
nobind++;
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
@ -188,11 +194,11 @@ main( int argc, char **argv )
for ( i = 0; i < outerloops; i++ ) {
if ( filter != NULL ) {
do_random( uri, manager, &passwd, entry, filter,
noattrs, loops, retries, delay, force,
noattrs, nobind, loops, retries, delay, force,
chaserefs );
} else {
do_read( uri, manager, &passwd, entry, NULL, noattrs,
do_read( uri, manager, &passwd, entry, NULL, noattrs, nobind,
loops, retries, delay, force, chaserefs );
}
}
@ -202,21 +208,18 @@ main( int argc, char **argv )
static void
do_random( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, int noattrs,
char *sbase, char *filter, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
char *attrs[ 2 ];
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
int nvalues = 0;
char **values = NULL;
LDAPMessage *res = NULL, *e = NULL;
srand( pid );
attrs[ 0 ] = LDAP_NO_ATTRS;
attrs[ 1 ] = NULL;
@ -235,17 +238,19 @@ do_random( char *uri, char *manager, struct berval *passwd,
(long) pid, innerloop, sbase, filter );
}
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
/* fallthru */
default:
break;
if ( nobind == 0 ) {
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}
exit( EXIT_FAILURE );
}
rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
@ -283,7 +288,7 @@ do_random( char *uri, char *manager, struct berval *passwd,
int r = ((double)nvalues)*rand()/(RAND_MAX + 1.0);
do_read( uri, manager, passwd, values[ r ], &ld,
noattrs, 1, maxretries, delay, force,
noattrs, nobind, 1, maxretries, delay, force,
chaserefs );
}
break;
@ -302,13 +307,12 @@ do_random( char *uri, char *manager, struct berval *passwd,
static void
do_read( char *uri, char *manager, struct berval *passwd, char *entry,
LDAP **ldp, int noattrs, int maxloop,
LDAP **ldp, int noattrs, int nobind, int maxloop,
int maxretries, int delay, int force, int chaserefs )
{
LDAP *ld = ldp ? *ldp : NULL;
int i = 0, do_retry = maxretries;
char *attrs[] = { "1.1", NULL };
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
@ -329,25 +333,27 @@ retry:;
(long) pid, maxloop, entry );
}
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
do_retry--;
if ( delay != 0 ) {
sleep( delay );
if ( nobind == 0 ) {
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
do_retry--;
if ( delay != 0 ) {
sleep( delay );
}
goto retry;
}
goto retry;
/* fallthru */
default:
break;
}
/* fallthru */
default:
break;
exit( EXIT_FAILURE );
}
exit( EXIT_FAILURE );
}
}

View file

@ -40,13 +40,13 @@
static void
do_search( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, LDAP **ldp, int noattrs,
char *sbase, char *filter, LDAP **ldp, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs );
static void
do_random( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, char *attr, int noattrs, int innerloop,
int maxretries, int delay, int force, int chaserefs );
char *sbase, char *filter, char *attr, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs );
static void
usage( char *name )
@ -62,6 +62,7 @@ usage( char *name )
"[-A] "
"[-C] "
"[-F] "
"[-N] "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
@ -90,13 +91,14 @@ main( int argc, char **argv )
int force = 0;
int chaserefs = 0;
int noattrs = 0;
int nobind = 0;
tester_init( "slapd-search", TESTER_SEARCH );
/* by default, tolerate referrals and no such object */
tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
while ( (i = getopt( argc, argv, "Aa:b:CD:f:FH:h:i:l:L:p:w:r:t:" )) != EOF ) {
while ( ( i = getopt( argc, argv, "Aa:b:CD:f:FH:h:i:l:L:Np:w:r:t:" ) ) != EOF ) {
switch( i ) {
case 'A':
noattrs++;
@ -118,6 +120,10 @@ main( int argc, char **argv )
tester_ignore_str2errlist( optarg );
break;
case 'N':
nobind++;
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
@ -196,11 +202,11 @@ main( int argc, char **argv )
for ( i = 0; i < outerloops; i++ ) {
if ( attr != NULL ) {
do_random( uri, manager, &passwd, sbase, filter, attr,
noattrs, loops, retries, delay, force, chaserefs );
noattrs, nobind, loops, retries, delay, force, chaserefs );
} else {
do_search( uri, manager, &passwd, sbase, filter, NULL,
noattrs, loops, retries, delay, force, chaserefs );
noattrs, nobind, loops, retries, delay, force, chaserefs );
}
}
@ -210,21 +216,18 @@ main( int argc, char **argv )
static void
do_random( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, char *attr, int noattrs,
char *sbase, char *filter, char *attr, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
char *attrs[ 2 ];
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
int nvalues = 0;
char **values = NULL;
LDAPMessage *res = NULL, *e = NULL;
srand( pid );
attrs[ 0 ] = attr;
attrs[ 1 ] = NULL;
@ -243,17 +246,19 @@ do_random( char *uri, char *manager, struct berval *passwd,
(long) pid, innerloop, sbase, filter, attr );
}
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
/* fallthru */
default:
break;
if ( nobind == 0 ) {
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}
exit( EXIT_FAILURE );
}
rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
@ -303,7 +308,7 @@ do_random( char *uri, char *manager, struct berval *passwd,
snprintf( buf, sizeof( buf ), "(%s=%s)", attr, values[ r ] );
do_search( uri, manager, passwd, sbase, buf, &ld, noattrs,
do_search( uri, manager, passwd, sbase, buf, &ld, noattrs, nobind,
1, maxretries, delay, force, chaserefs );
}
break;
@ -322,14 +327,12 @@ do_random( char *uri, char *manager, struct berval *passwd,
static void
do_search( char *uri, char *manager, struct berval *passwd,
char *sbase, char *filter, LDAP **ldp,
int noattrs, int innerloop, int maxretries, int delay,
int force, int chaserefs )
char *sbase, char *filter, LDAP **ldp, int noattrs, int nobind,
int innerloop, int maxretries, int delay, int force, int chaserefs )
{
LDAP *ld = ldp ? *ldp : NULL;
int i = 0, do_retry = maxretries;
char *attrs[] = { "cn", "sn", NULL };
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
char buf[ BUFSIZ ];
@ -352,27 +355,29 @@ retry:;
(long) pid, innerloop, sbase, filter );
}
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
snprintf( buf, sizeof( buf ),
"bindDN=\"%s\"", manager );
tester_ldap_error( ld, "ldap_sasl_bind_s", buf );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
do_retry--;
if ( delay != 0 ) {
sleep( delay );
if ( nobind == 0 ) {
rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
snprintf( buf, sizeof( buf ),
"bindDN=\"%s\"", manager );
tester_ldap_error( ld, "ldap_sasl_bind_s", buf );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
do_retry--;
if ( delay != 0 ) {
sleep( delay );
}
goto retry;
}
goto retry;
/* fallthru */
default:
break;
}
/* fallthru */
default:
break;
exit( EXIT_FAILURE );
}
exit( EXIT_FAILURE );
}
}

View file

@ -36,6 +36,8 @@
#include "lutil.h"
#include "ldap.h"
#include "ldap_pvt.h"
#include "lber_pvt.h"
#include "slapd-common.h"
#define SEARCHCMD "slapd-search"
@ -75,8 +77,13 @@ static char argbuf[BUFSIZ];
#endif
static void
usage( char *name )
usage( char *name, char opt )
{
if ( opt ) {
fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
name, opt );
}
fprintf( stderr,
"usage: %s "
"-H <uri> | ([-h <host>] -p <port>) "
@ -85,13 +92,14 @@ usage( char *name )
"-d <datadir> "
"[-i <ignore>] "
"[-j <maxchild>] "
"[-l <loops>] "
"[-l {<loops>|<type>=<loops>[,...]}] "
"[-L <outerloops>] "
"-P <progdir> "
"[-r <maxretries>] "
"[-t <delay>] "
"[-C] "
"[-F] "
"[-C]\n",
"[-N]\n",
name );
exit( EXIT_FAILURE );
}
@ -116,6 +124,7 @@ main( int argc, char **argv )
int friendly = 0;
int chaserefs = 0;
int noattrs = 0;
int nobind = 0;
char *ignore = NULL;
/* search */
char *sfile = NULL;
@ -144,22 +153,22 @@ main( int argc, char **argv )
char acmd[MAXPATHLEN];
char aloops[] = "18446744073709551615UL";
/* modrdn */
char *nfile = NULL;
char *nreqs[MAXREQS];
int nnum = 0;
char *nargs[MAXARGS];
int nanum;
char ncmd[MAXPATHLEN];
char nloops[] = "18446744073709551615UL";
/* modify */
char *mfile = NULL;
char *mreqs[MAXREQS];
char *mdn[MAXREQS];
int mnum = 0;
char *margs[MAXARGS];
int manum;
char mcmd[MAXPATHLEN];
char mloops[] = "18446744073709551615UL";
/* modify */
char *modfile = NULL;
char *modreqs[MAXREQS];
char *moddn[MAXREQS];
int modnum = 0;
char *modargs[MAXARGS];
int modanum;
char modcmd[MAXPATHLEN];
char modloops[] = "18446744073709551615UL";
/* bind */
char *bfile = NULL;
char *breqs[MAXREQS];
@ -170,19 +179,55 @@ main( int argc, char **argv )
int banum;
char bcmd[MAXPATHLEN];
char bloops[] = "18446744073709551615UL";
char **bargs_extra = NULL;
char *friendlyOpt = NULL;
int pw_ask = 0;
char *pw_file = NULL;
/* extra action to do after bind... */
typedef struct extra_t {
char *action;
struct extra_t *next;
} extra_t;
extra_t *extra = NULL;
int nextra = 0;
tester_init( "slapd-tester", TESTER_TESTER );
while ( (i = getopt( argc, argv, "ACD:d:FH:h:i:j:l:L:P:p:r:t:w:Wy:" )) != EOF ) {
sloops[0] = '\0';
rloops[0] = '\0';
aloops[0] = '\0';
nloops[0] = '\0';
mloops[0] = '\0';
bloops[0] = '\0';
while ( (i = getopt( argc, argv, "AB:CD:d:FH:h:i:j:l:L:NP:p:r:t:w:Wy:" )) != EOF ) {
switch( i ) {
case 'A':
noattrs++;
break;
case 'B':
{
char **p,
**b = ldap_str2charray( optarg, "," );
extra_t **epp;
for ( epp = &extra; *epp; epp = &(*epp)->next )
;
for ( p = b; p[0]; p++ ) {
*epp = calloc( 1, sizeof( extra_t ) );
(*epp)->action = p[0];
epp = &(*epp)->next;
nextra++;
}
ldap_memfree( b );
} break;
case 'C':
chaserefs++;
break;
@ -213,13 +258,51 @@ main( int argc, char **argv )
case 'j': /* the number of parallel clients */
if ( lutil_atoi( &maxkids, optarg ) != 0 ) {
usage( argv[0] );
usage( argv[0], 'j' );
}
break;
case 'l': /* the number of loops per client */
if ( lutil_atoi( &loops, optarg ) != 0 ) {
usage( argv[0] );
if ( !isdigit( optarg[0] ) ) {
char **p,
**l = ldap_str2charray( optarg, "," );
for ( p = l; p[0]; p++) {
struct {
struct berval type;
char *buf;
} types[] = {
{ BER_BVC( "add=" ), aloops },
{ BER_BVC( "bind=" ), bloops },
{ BER_BVC( "modify=" ), mloops },
{ BER_BVC( "modrdn=" ), nloops },
{ BER_BVC( "read=" ), rloops },
{ BER_BVC( "search=" ), sloops },
{ BER_BVNULL, NULL }
};
int c, n;
for ( c = 0; types[c].type.bv_val; c++ ) {
if ( strncasecmp( p[0], types[c].type.bv_val, types[c].type.bv_len ) == 0 ) {
break;
}
}
if ( types[c].type.bv_val == NULL ) {
usage( argv[0], 'l' );
}
if ( lutil_atoi( &n, &p[0][types[c].type.bv_len] ) != 0 ) {
usage( argv[0], 'l' );
}
snprintf( types[c].buf, sizeof( aloops ), "%d", n );
}
ldap_charray_free( l );
} else if ( lutil_atoi( &loops, optarg ) != 0 ) {
usage( argv[0], 'l' );
}
break;
@ -227,6 +310,10 @@ main( int argc, char **argv )
outerloops = strdup( optarg );
break;
case 'N':
nobind++;
break;
case 'P': /* prog directory */
progdir = strdup( optarg );
break;
@ -257,14 +344,14 @@ main( int argc, char **argv )
break;
default:
usage( argv[0] );
usage( argv[0], '\0' );
break;
}
}
if (( dirname == NULL ) || ( port == NULL && uri == NULL ) ||
( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
usage( argv[0] );
usage( argv[0], '\0' );
#ifdef HAVE_WINSOCK
children = malloc( maxkids * sizeof(HANDLE) );
@ -286,10 +373,10 @@ main( int argc, char **argv )
rfile = get_file_name( dirname, file->d_name );
continue;
} else if ( !strcasecmp( file->d_name, TMODRDNFILE )) {
mfile = get_file_name( dirname, file->d_name );
nfile = get_file_name( dirname, file->d_name );
continue;
} else if ( !strcasecmp( file->d_name, TMODIFYFILE )) {
modfile = get_file_name( dirname, file->d_name );
mfile = get_file_name( dirname, file->d_name );
continue;
} else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
&& ( anum < MAXREQS )) {
@ -327,13 +414,13 @@ main( int argc, char **argv )
}
/* look for modrdn requests */
if ( mfile ) {
mnum = get_read_entries( mfile, mreqs, NULL );
if ( nfile ) {
nnum = get_read_entries( nfile, nreqs, NULL );
}
/* look for modify requests */
if ( modfile ) {
modnum = get_search_filters( modfile, modreqs, NULL, moddn );
if ( mfile ) {
mnum = get_search_filters( mfile, mreqs, NULL, mdn );
}
/* look for bind requests */
@ -358,12 +445,12 @@ main( int argc, char **argv )
break;
}
snprintf( sloops, sizeof( sloops ), "%d", 10 * loops );
snprintf( rloops, sizeof( rloops ), "%d", 20 * loops );
snprintf( aloops, sizeof( aloops ), "%d", loops );
snprintf( mloops, sizeof( mloops ), "%d", loops );
snprintf( modloops, sizeof( modloops ), "%d", loops );
snprintf( bloops, sizeof( bloops ), "%d", 20 * loops );
if ( sloops[0] == '\0' ) snprintf( sloops, sizeof( sloops ), "%d", 10 * loops );
if ( rloops[0] == '\0' ) snprintf( rloops, sizeof( rloops ), "%d", 20 * loops );
if ( aloops[0] == '\0' ) snprintf( aloops, sizeof( aloops ), "%d", loops );
if ( nloops[0] == '\0' ) snprintf( nloops, sizeof( nloops ), "%d", loops );
if ( mloops[0] == '\0' ) snprintf( mloops, sizeof( mloops ), "%d", loops );
if ( bloops[0] == '\0' ) snprintf( bloops, sizeof( bloops ), "%d", 20 * loops );
/*
* generate the search clients
@ -403,6 +490,9 @@ main( int argc, char **argv )
if ( noattrs ) {
sargs[sanum++] = "-A";
}
if ( nobind ) {
sargs[sanum++] = "-N";
}
if ( ignore ) {
sargs[sanum++] = "-i";
sargs[sanum++] = ignore;
@ -471,8 +561,51 @@ main( int argc, char **argv )
* generate the modrdn clients
*/
nanum = 0;
snprintf( ncmd, sizeof ncmd, "%s" LDAP_DIRSEP MODRDNCMD,
progdir );
nargs[nanum++] = ncmd;
if ( uri ) {
nargs[nanum++] = "-H";
nargs[nanum++] = uri;
} else {
nargs[nanum++] = "-h";
nargs[nanum++] = host;
nargs[nanum++] = "-p";
nargs[nanum++] = port;
}
nargs[nanum++] = "-D";
nargs[nanum++] = manager;
nargs[nanum++] = "-w";
nargs[nanum++] = passwd;
nargs[nanum++] = "-l";
nargs[nanum++] = nloops;
nargs[nanum++] = "-L";
nargs[nanum++] = outerloops;
nargs[nanum++] = "-r";
nargs[nanum++] = retries;
nargs[nanum++] = "-t";
nargs[nanum++] = delay;
if ( friendly ) {
nargs[nanum++] = friendlyOpt;
}
if ( chaserefs ) {
nargs[nanum++] = "-C";
}
if ( ignore ) {
nargs[nanum++] = "-i";
nargs[nanum++] = ignore;
}
nargs[nanum++] = "-e";
nargs[nanum++] = NULL; /* will hold the modrdn entry */
nargs[nanum++] = NULL;
/*
* generate the modify clients
*/
manum = 0;
snprintf( mcmd, sizeof mcmd, "%s" LDAP_DIRSEP MODRDNCMD,
snprintf( mcmd, sizeof mcmd, "%s" LDAP_DIRSEP MODIFYCMD,
progdir );
margs[manum++] = mcmd;
if ( uri ) {
@ -507,53 +640,10 @@ main( int argc, char **argv )
margs[manum++] = ignore;
}
margs[manum++] = "-e";
margs[manum++] = NULL; /* will hold the modrdn entry */
margs[manum++] = NULL; /* will hold the modify entry */
margs[manum++] = "-a";;
margs[manum++] = NULL; /* will hold the ava */
margs[manum++] = NULL;
/*
* generate the modify clients
*/
modanum = 0;
snprintf( modcmd, sizeof modcmd, "%s" LDAP_DIRSEP MODIFYCMD,
progdir );
modargs[modanum++] = modcmd;
if ( uri ) {
modargs[modanum++] = "-H";
modargs[modanum++] = uri;
} else {
modargs[modanum++] = "-h";
modargs[modanum++] = host;
modargs[modanum++] = "-p";
modargs[modanum++] = port;
}
modargs[modanum++] = "-D";
modargs[modanum++] = manager;
modargs[modanum++] = "-w";
modargs[modanum++] = passwd;
modargs[modanum++] = "-l";
modargs[modanum++] = modloops;
modargs[modanum++] = "-L";
modargs[modanum++] = outerloops;
modargs[modanum++] = "-r";
modargs[modanum++] = retries;
modargs[modanum++] = "-t";
modargs[modanum++] = delay;
if ( friendly ) {
modargs[modanum++] = friendlyOpt;
}
if ( chaserefs ) {
modargs[modanum++] = "-C";
}
if ( ignore ) {
modargs[modanum++] = "-i";
modargs[modanum++] = ignore;
}
modargs[modanum++] = "-e";
modargs[modanum++] = NULL; /* will hold the modify entry */
modargs[modanum++] = "-a";;
modargs[modanum++] = NULL; /* will hold the ava */
modargs[modanum++] = NULL;
/*
* generate the add/delete clients
@ -636,6 +726,10 @@ main( int argc, char **argv )
bargs[banum++] = "-i";
bargs[banum++] = ignore;
}
if ( nextra ) {
bargs[banum++] = "-B";
bargs_extra = &bargs[banum++];
}
bargs[banum++] = "-D";
bargs[banum++] = NULL;
bargs[banum++] = "-w";
@ -674,15 +768,15 @@ main( int argc, char **argv )
fork_child( rcmd, rargs );
}
if ( j < mnum ) {
margs[manum - 2] = mreqs[j];
fork_child( mcmd, margs );
if ( j < nnum ) {
nargs[nanum - 2] = nreqs[j];
fork_child( ncmd, nargs );
}
if ( j < modnum ) {
modargs[modanum - 4] = moddn[j];
modargs[modanum - 2] = modreqs[j];
fork_child( modcmd, modargs );
if ( j < mnum ) {
margs[manum - 4] = mdn[j];
margs[manum - 2] = mreqs[j];
fork_child( mcmd, margs );
}
if ( j < anum ) {
@ -693,6 +787,15 @@ main( int argc, char **argv )
if ( DOREQ( bnum, j ) ) {
int jj = j % bnum;
if ( nextra ) {
int n = ((double)nextra)*rand()/(RAND_MAX + 1.0);
extra_t *e;
for ( e = extra; n-- > 0; e = e->next )
;
*bargs_extra = e->action;
}
if ( battrs[jj] != NULL ) {
bargs[banum - 4] = manager ? manager : "";
bargs[banum - 2] = passwd ? passwd : "";
@ -830,6 +933,7 @@ get_read_entries( char *filename, char *entries[], char *filters[] )
static void
fork_child( char *prog, char **args )
{
/* note: obscures global pid var; intended */
pid_t pid;
wait4kids( maxkids );