]> git.sur5r.net Git - openldap/commitdiff
add support for extra ops after bind; allow to skip bind for slapd-search/read
authorPierangelo Masarati <ando@openldap.org>
Sat, 18 Nov 2006 18:25:46 +0000 (18:25 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 18 Nov 2006 18:25:46 +0000 (18:25 +0000)
tests/progs/slapd-addel.c
tests/progs/slapd-bind.c
tests/progs/slapd-common.c
tests/progs/slapd-common.h
tests/progs/slapd-modify.c
tests/progs/slapd-modrdn.c
tests/progs/slapd-read.c
tests/progs/slapd-search.c
tests/progs/slapd-tester.c

index 5e9fd13e31e1d094443de83eb623314748a3b1d9..242e320b0527d92a31e60f2b7b9bb3529e32ec0d 100644 (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;
 
index 11db20b1b50cc4606455222b3a44f1d38d410004..0a892e0a9989584c6340db5fe01cdd37f936b240 100644 (file)
@@ -35,6 +35,7 @@
 #include <ldap.h>
 #include <lutil.h>
 #include <lber_pvt.h>
+#include <ldap_pvt.h>
 
 #include "slapd-common.h"
 
 
 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;
                }
index b68b3062280fd8d5fb1873b24a25c6a850a219b1..ace4eb6fd8be6523837dc7b921d2da84bf59eb25 100644 (file)
 #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;
 }
 
index e42e8080a655ebe6d7f64c1e451f95bec6b0db51..1a8ad77c16760d36854a215503b06c0da87f353c 100644 (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 */
index cb416d861180984e3df3edaac42d4dcb98a21454..95bf19a6b32deea88e4286c4281b120644a22eff 100644 (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;
index f2e7ad82f3f53f4671138836d214ce8a5e86350d..894a501a7d72d021122c44b6fa7b9ddcfb19100e 100644 (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 );
 
index 0bc00d20a9d37e76a32e137a5f125561cc2a0e73..eb292503e044f2bb4166de7b933112b04620a059 100644 (file)
 
 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 );
                }
        }
 
index 5709c7be48ca59264c23aaa0e47c8e4a30827287..01da5753e9c88051483a54c4d3b1b4cae2958419 100644 (file)
 
 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 );
                }
        }
 
index fdca62f2044f0cfae33ff3dbea2001e0c157858b..f57bded5cc0ee51db4d7f22c1e493801c2d39903 100644 (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,17 +768,17 @@ main( int argc, char **argv )
                        fork_child( rcmd, rargs );
                }
 
+               if ( j < nnum ) {
+                       nargs[nanum - 2] = nreqs[j];
+                       fork_child( ncmd, nargs );
+               }
+
                if ( j < mnum ) {
+                       margs[manum - 4] = mdn[j];
                        margs[manum - 2] = mreqs[j];
                        fork_child( mcmd, margs );
                }
 
-               if ( j < modnum ) {
-                       modargs[modanum - 4] = moddn[j];
-                       modargs[modanum - 2] = modreqs[j];
-                       fork_child( modcmd, modargs );
-               }
-
                if ( j < anum ) {
                        aargs[aanum - 2] = afiles[j];
                        fork_child( acmd, aargs );
@@ -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 );