allow selective handling of errors

This commit is contained in:
Pierangelo Masarati 2006-06-09 09:30:36 +00:00
parent 019dcb7589
commit 0f2601d0da
9 changed files with 319 additions and 78 deletions

View File

@ -55,6 +55,7 @@ usage( char *name )
"-D <manager> "
"-w <passwd> "
"-f <addfile> "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-r <maxretries>] "
@ -84,7 +85,7 @@ main( int argc, char **argv )
int chaserefs = 0;
LDAPMod **attrs = NULL;
tester_init( "slapd-modify" );
tester_init( "slapd-addel", TESTER_ADDEL );
while ( (i = getopt( argc, argv, "CFH:h:p:D:w:f:l:L:r:t:" )) != EOF ) {
switch( i ) {
@ -104,6 +105,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
/* ignored (!) by now */
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );

View File

@ -67,6 +67,7 @@ usage( char *name )
"[-F] "
"[-C] "
"[-I] "
"[-i <ignore>] "
"[-t delay]\n",
name );
exit( EXIT_FAILURE );
@ -92,9 +93,12 @@ main( int argc, char **argv )
int noinit = 0;
int delay = 0;
tester_init( "slapd-bind" );
tester_init( "slapd-bind", TESTER_BIND );
while ( (i = getopt( argc, argv, "a:b:H:h:p:D:w:l:L:f:FIt:" )) != EOF ) {
/* 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 ) {
switch( i ) {
case 'a':
pwattr = optarg;
@ -116,6 +120,10 @@ main( int argc, char **argv )
host = optarg;
break;
case 'i':
tester_ignore_str2errlist( optarg );
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
@ -193,7 +201,7 @@ do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
int force, int chaserefs, int noinit, LDAP **ldp )
{
LDAP *ld = ldp ? *ldp : NULL;
int i, first = 1, rc = -1;
int i, rc = -1;
pid_t pid = getpid();
if ( maxloop > 1 )
@ -217,29 +225,28 @@ do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
}
rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL );
switch ( rc ) {
case LDAP_SUCCESS:
break;
if ( rc ) {
unsigned first = tester_ignore_err( rc );
case LDAP_INVALID_CREDENTIALS:
/* don't log: it's intended */
if ( force >= 2 ) {
if ( !first ) {
break;
/* if ignore.. */
if ( first ) {
/* only log if first occurrence */
if ( force < 2 || first == 1 ) {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
}
first = 0;
rc = LDAP_SUCCESS;
} else {
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
}
/* fallthru */
default:
tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
}
if ( !noinit ) {
ldap_unbind_ext( ld, NULL, NULL );
ld = NULL;
}
if ( rc != LDAP_SUCCESS && !force ) {
if ( rc != LDAP_SUCCESS ) {
break;
}
}

View File

@ -28,12 +28,187 @@
#include <ldap.h>
#include "ldap_pvt.h"
#include "slapd-common.h"
static char progname[ BUFSIZ ];
tester_t progtype;
#define TESTER_SERVER_LAST (LDAP_OTHER + 1)
#define TESTER_CLIENT_LAST (- LDAP_REFERRAL_LIMIT_EXCEEDED + 1)
static unsigned ignore_server[ TESTER_SERVER_LAST ];
static unsigned ignore_client[ TESTER_CLIENT_LAST ];
static struct {
char *name;
int err;
} ignore_str2err[] = {
{ "OPERATIONS_ERROR", LDAP_OPERATIONS_ERROR },
{ "PROTOCOL_ERROR", LDAP_PROTOCOL_ERROR },
{ "TIMELIMIT_EXCEEDED", LDAP_TIMELIMIT_EXCEEDED },
{ "SIZELIMIT_EXCEEDED", LDAP_SIZELIMIT_EXCEEDED },
{ "COMPARE_FALSE", LDAP_COMPARE_FALSE },
{ "COMPARE_TRUE", LDAP_COMPARE_TRUE },
{ "AUTH_METHOD_NOT_SUPPORTED", LDAP_AUTH_METHOD_NOT_SUPPORTED },
{ "STRONG_AUTH_NOT_SUPPORTED", LDAP_STRONG_AUTH_NOT_SUPPORTED },
{ "STRONG_AUTH_REQUIRED", LDAP_STRONG_AUTH_REQUIRED },
{ "STRONGER_AUTH_REQUIRED", LDAP_STRONGER_AUTH_REQUIRED },
{ "PARTIAL_RESULTS", LDAP_PARTIAL_RESULTS },
{ "REFERRAL", LDAP_REFERRAL },
{ "ADMINLIMIT_EXCEEDED", LDAP_ADMINLIMIT_EXCEEDED },
{ "UNAVAILABLE_CRITICAL_EXTENSION", LDAP_UNAVAILABLE_CRITICAL_EXTENSION },
{ "CONFIDENTIALITY_REQUIRED", LDAP_CONFIDENTIALITY_REQUIRED },
{ "SASL_BIND_IN_PROGRESS", LDAP_SASL_BIND_IN_PROGRESS },
{ "NO_SUCH_ATTRIBUTE", LDAP_NO_SUCH_ATTRIBUTE },
{ "UNDEFINED_TYPE", LDAP_UNDEFINED_TYPE },
{ "INAPPROPRIATE_MATCHING", LDAP_INAPPROPRIATE_MATCHING },
{ "CONSTRAINT_VIOLATION", LDAP_CONSTRAINT_VIOLATION },
{ "TYPE_OR_VALUE_EXISTS", LDAP_TYPE_OR_VALUE_EXISTS },
{ "INVALID_SYNTAX", LDAP_INVALID_SYNTAX },
{ "NO_SUCH_OBJECT", LDAP_NO_SUCH_OBJECT },
{ "ALIAS_PROBLEM", LDAP_ALIAS_PROBLEM },
{ "INVALID_DN_SYNTAX", LDAP_INVALID_DN_SYNTAX },
{ "IS_LEAF", LDAP_IS_LEAF },
{ "ALIAS_DEREF_PROBLEM", LDAP_ALIAS_DEREF_PROBLEM },
{ "PROXY_AUTHZ_FAILURE", LDAP_PROXY_AUTHZ_FAILURE },
{ "INAPPROPRIATE_AUTH", LDAP_INAPPROPRIATE_AUTH },
{ "INVALID_CREDENTIALS", LDAP_INVALID_CREDENTIALS },
{ "INSUFFICIENT_ACCESS", LDAP_INSUFFICIENT_ACCESS },
{ "BUSY", LDAP_BUSY },
{ "UNAVAILABLE", LDAP_UNAVAILABLE },
{ "UNWILLING_TO_PERFORM", LDAP_UNWILLING_TO_PERFORM },
{ "LOOP_DETECT", LDAP_LOOP_DETECT },
{ "NAMING_VIOLATION", LDAP_NAMING_VIOLATION },
{ "OBJECT_CLASS_VIOLATION", LDAP_OBJECT_CLASS_VIOLATION },
{ "NOT_ALLOWED_ON_NONLEAF", LDAP_NOT_ALLOWED_ON_NONLEAF },
{ "NOT_ALLOWED_ON_RDN", LDAP_NOT_ALLOWED_ON_RDN },
{ "ALREADY_EXISTS", LDAP_ALREADY_EXISTS },
{ "NO_OBJECT_CLASS_MODS", LDAP_NO_OBJECT_CLASS_MODS },
{ "RESULTS_TOO_LARGE", LDAP_RESULTS_TOO_LARGE },
{ "AFFECTS_MULTIPLE_DSAS", LDAP_AFFECTS_MULTIPLE_DSAS },
{ "OTHER", LDAP_OTHER },
{ "SERVER_DOWN", LDAP_SERVER_DOWN },
{ "LOCAL_ERROR", LDAP_LOCAL_ERROR },
{ "ENCODING_ERROR", LDAP_ENCODING_ERROR },
{ "DECODING_ERROR", LDAP_DECODING_ERROR },
{ "TIMEOUT", LDAP_TIMEOUT },
{ "AUTH_UNKNOWN", LDAP_AUTH_UNKNOWN },
{ "FILTER_ERROR", LDAP_FILTER_ERROR },
{ "USER_CANCELLED", LDAP_USER_CANCELLED },
{ "PARAM_ERROR", LDAP_PARAM_ERROR },
{ "NO_MEMORY", LDAP_NO_MEMORY },
{ "CONNECT_ERROR", LDAP_CONNECT_ERROR },
{ "NOT_SUPPORTED", LDAP_NOT_SUPPORTED },
{ "CONTROL_NOT_FOUND", LDAP_CONTROL_NOT_FOUND },
{ "NO_RESULTS_RETURNED", LDAP_NO_RESULTS_RETURNED },
{ "MORE_RESULTS_TO_RETURN", LDAP_MORE_RESULTS_TO_RETURN },
{ "CLIENT_LOOP", LDAP_CLIENT_LOOP },
{ "REFERRAL_LIMIT_EXCEEDED", LDAP_REFERRAL_LIMIT_EXCEEDED },
{ NULL }
};
#define UNKNOWN_ERR (1234567890)
static int
tester_ignore_str2err( const char *err )
{
int i;
unsigned ignore = 1;
if ( strcmp( err, "ALL" ) == 0 ) {
for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) {
int err = ignore_str2err[ i ].err;
if ( err > 0 ) {
ignore_server[ err ] = 1;
} else if ( err < 0 ) {
ignore_client[ -err ] = 1;
}
}
return 0;
}
if ( err[ 0 ] == '!' ) {
ignore = 0;
err++;
}
for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) {
if ( strcmp( err, ignore_str2err[ i ].name ) == 0 ) {
int err = ignore_str2err[ i ].err;
if ( err > 0 ) {
ignore_server[ err ] = ignore;
} else if ( err < 0 ) {
ignore_client[ -err ] = ignore;
}
return err;
}
}
return UNKNOWN_ERR;
}
int
tester_ignore_str2errlist( const char *err )
{
int i;
char **errs = ldap_str2charray( err, "," );
for ( i = 0; errs[ i ] != NULL; i++ ) {
/* TODO: allow <err>:<prog> to ignore <err> only when <prog> */
(void)tester_ignore_str2err( errs[ i ] );
}
ldap_charray_free( errs );
return 0;
}
unsigned
tester_ignore_err( int err )
{
unsigned rc = 1;
if ( err > 0 ) {
if ( err < TESTER_SERVER_LAST ) {
rc = ignore_server[ err ];
if ( rc ) {
ignore_server[ err ]++;
}
}
} else if ( err < 0 ) {
if ( -err < TESTER_CLIENT_LAST ) {
rc = ignore_client[ -err ];
if ( rc ) {
ignore_client[ -err ]++;
}
}
}
/* SUCCESS is always "ignored" */
return rc;
}
void
tester_init( const char *pname )
tester_init( const char *pname, tester_t ptype )
{
snprintf( progname, sizeof( progname ), "%s PID=%d", pname, getpid() );
progtype = ptype;
}
char *

View File

@ -20,10 +20,22 @@
#ifndef SLAPD_COMMON_H
#define SLAPD_COMMON_H
extern void tester_init( const char *pname );
typedef enum {
TESTER_TESTER,
TESTER_ADDEL,
TESTER_BIND,
TESTER_MODIFY,
TESTER_MODRDN,
TESTER_READ,
TESTER_SEARCH
} tester_t;
extern void tester_init( const char *pname, tester_t ptype );
extern char * tester_uri( char *uri, char *host, int port );
extern void tester_error( const char *msg );
extern void tester_perror( const char *fname, const char *msg );
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 );
#endif /* SLAPD_COMMON_H */

View File

@ -49,6 +49,7 @@ usage( char *name )
"-D <manager> "
"-w <passwd> "
"-e <entry> "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-r <maxretries>] "
@ -78,9 +79,9 @@ main( int argc, char **argv )
int friendly = 0;
int chaserefs = 0;
tester_init( "slapd-modify" );
tester_init( "slapd-modify", TESTER_MODIFY );
while ( (i = getopt( argc, argv, "CFH:h:p:D:w:e:a:l:L:r:t:" )) != EOF ) {
while ( (i = getopt( argc, argv, "CFH:h:i:p:D:w:e:a:l:L:r:t:" )) != EOF ) {
switch ( i ) {
case 'C':
chaserefs++;
@ -98,6 +99,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
/* ignored (!) by now */
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );

View File

@ -52,6 +52,7 @@ usage( char *name )
"-D <manager> "
"-w <passwd> "
"-e <entry> "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-r <maxretries>] "
@ -79,9 +80,9 @@ main( int argc, char **argv )
int friendly = 0;
int chaserefs = 0;
tester_init( "slapd-modrdn" );
tester_init( "slapd-modrdn", TESTER_MODRDN );
while ( (i = getopt( argc, argv, "CFH:h:p:D:w:e:l:L:r:t:" )) != EOF ) {
while ( (i = getopt( argc, argv, "CFH:h:i:p:D:w:e:l:L:r:t:" )) != EOF ) {
switch( i ) {
case 'C':
chaserefs++;
@ -99,6 +100,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
/* ignored (!) by now */
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );

View File

@ -61,6 +61,7 @@ usage( char *name )
"[-C] "
"[-F] "
"[-f filter] "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-r <maxretries>] "
@ -88,9 +89,12 @@ main( int argc, char **argv )
int chaserefs = 0;
int noattrs = 0;
tester_init( "slapd-read" );
tester_init( "slapd-read", TESTER_READ );
while ( (i = getopt( argc, argv, "ACD:H:h:p:e:Ff:l:L:r:t:w:" )) != EOF ) {
/* by default, tolerate referrals and no such object */
tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
while ( (i = getopt( argc, argv, "ACD:H:h:i:p:e:Ff:l:L:r:t:w:" )) != EOF ) {
switch( i ) {
case 'A':
noattrs++;
@ -108,6 +112,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
tester_ignore_str2errlist( optarg );
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
@ -294,7 +302,6 @@ do_read( char *uri, char *manager, struct berval *passwd, char *entry,
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
int first = 1;
retry:;
if ( ld == NULL ) {
@ -341,39 +348,33 @@ retry:;
rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
NULL, attrs, noattrs, NULL, NULL, NULL,
LDAP_NO_LIMIT, &res );
switch ( rc ) {
case LDAP_REFERRAL:
/* don't log: it's intended */
if ( force >= 2 ) {
if ( !first ) {
break;
}
first = 0;
}
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
/* fallthru */
case LDAP_SUCCESS:
break;
default:
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
}
if ( rc != LDAP_NO_SUCH_OBJECT ) {
goto done;
}
break;
}
if ( res != NULL ) {
ldap_msgfree( res );
}
if ( rc ) {
unsigned first = tester_ignore_err( rc );
/* if ignore.. */
if ( first ) {
/* only log if first occurrence */
if ( force < 2 || first == 1 ) {
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
}
continue;
}
/* busy needs special handling */
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
ld = NULL;
do_retry--;
goto retry;
}
break;
}
}
done:;
if ( ldp != NULL ) {
*ldp = ld;

View File

@ -62,6 +62,7 @@ usage( char *name )
"[-A] "
"[-C] "
"[-F] "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
"[-r <maxretries>] "
@ -90,9 +91,12 @@ main( int argc, char **argv )
int chaserefs = 0;
int noattrs = 0;
tester_init( "slapd-search" );
tester_init( "slapd-search", TESTER_SEARCH );
while ( (i = getopt( argc, argv, "Aa:b:CD:f:FH:h:l:L:p:w:r:t:" )) != EOF ) {
/* 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 ) {
switch( i ) {
case 'A':
noattrs++;
@ -110,6 +114,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
tester_ignore_str2errlist( optarg );
break;
case 'p': /* the servers port */
if ( lutil_atoi( &port, optarg ) != 0 ) {
usage( argv[0] );
@ -316,7 +324,6 @@ do_search( char *uri, char *manager, struct berval *passwd,
pid_t pid = getpid();
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
int first = 1;
char buf[ BUFSIZ ];
@ -371,39 +378,32 @@ retry:;
ldap_msgfree( res );
}
switch ( rc ) {
case LDAP_REFERRAL:
/* don't log: it's intended */
if ( force >= 2 ) {
if ( !first ) {
break;
if ( rc ) {
unsigned first = tester_ignore_err( rc );
/* if ignore.. */
if ( first ) {
/* only log if first occurrence */
if ( force < 2 || first == 1 ) {
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
}
first = 0;
continue;
}
tester_ldap_error( ld, "ldap_search_ext_s", NULL );
/* fallthru */
case LDAP_SUCCESS:
break;
default:
/* busy needs special handling */
snprintf( buf, sizeof( buf ),
"base=\"%s\" filter=\"%s\"\n",
sbase, filter );
tester_ldap_error( ld, "ldap_search_ext_s", buf );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
ldap_unbind_ext( ld, NULL, NULL );
ld = NULL;
do_retry--;
goto retry;
}
if ( rc != LDAP_NO_SUCH_OBJECT ) {
goto done;
}
break;
}
}
done:;
if ( ldp != NULL ) {
*ldp = ld;

View File

@ -83,6 +83,7 @@ usage( char *name )
"-D <manager> "
"-w <passwd> "
"-d <datadir> "
"[-i <ignore>] "
"[-j <maxchild>] "
"[-l <loops>] "
"[-L <outerloops>] "
@ -115,6 +116,7 @@ main( int argc, char **argv )
int friendly = 0;
int chaserefs = 0;
int noattrs = 0;
char *ignore = NULL;
/* search */
char *sfile = NULL;
char *sreqs[MAXREQS];
@ -171,9 +173,9 @@ main( int argc, char **argv )
char *friendlyOpt = NULL;
tester_init( "slapd-tester" );
tester_init( "slapd-tester", TESTER_TESTER );
while ( (i = getopt( argc, argv, "ACD:d:FH:h:j:l:L:P:p:r:t:w:" )) != EOF ) {
while ( (i = getopt( argc, argv, "ACD:d:FH:h:i:j:l:L:P:p:r:t:w:" )) != EOF ) {
switch( i ) {
case 'A':
noattrs++;
@ -203,6 +205,10 @@ main( int argc, char **argv )
host = strdup( optarg );
break;
case 'i':
ignore = optarg;
break;
case 'j': /* the number of parallel clients */
if ( lutil_atoi( &maxkids, optarg ) != 0 ) {
usage( argv[0] );
@ -375,6 +381,10 @@ main( int argc, char **argv )
if ( noattrs ) {
sargs[sanum++] = "-A";
}
if ( ignore ) {
sargs[sanum++] = "-i";
sargs[sanum++] = ignore;
}
sargs[sanum++] = "-b";
sargs[sanum++] = NULL; /* will hold the search base */
sargs[sanum++] = "-f";
@ -423,6 +433,10 @@ main( int argc, char **argv )
if ( noattrs ) {
rargs[ranum++] = "-A";
}
if ( ignore ) {
rargs[ranum++] = "-i";
rargs[ranum++] = ignore;
}
rargs[ranum++] = "-e";
rargs[ranum++] = NULL; /* will hold the read entry */
@ -466,6 +480,10 @@ main( int argc, char **argv )
if ( chaserefs ) {
margs[manum++] = "-C";
}
if ( ignore ) {
margs[manum++] = "-i";
margs[manum++] = ignore;
}
margs[manum++] = "-e";
margs[manum++] = NULL; /* will hold the modrdn entry */
margs[manum++] = NULL;
@ -505,6 +523,10 @@ main( int argc, char **argv )
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";;
@ -546,6 +568,10 @@ main( int argc, char **argv )
if ( chaserefs ) {
aargs[aanum++] = "-C";
}
if ( ignore ) {
aargs[aanum++] = "-i";
aargs[aanum++] = ignore;
}
aargs[aanum++] = "-f";
aargs[aanum++] = NULL; /* will hold the add data file */
aargs[aanum++] = NULL;
@ -584,6 +610,10 @@ main( int argc, char **argv )
if ( chaserefs ) {
bargs[banum++] = "-C";
}
if ( ignore ) {
bargs[banum++] = "-i";
bargs[banum++] = ignore;
}
bargs[banum++] = "-D";
bargs[banum++] = NULL;
bargs[banum++] = "-w";
@ -649,6 +679,7 @@ main( int argc, char **argv )
bargs[banum - 1] = "-a";
bargs[banum] = battrs[jj];
}
fork_child( bcmd, bargs );
bargs[banum - 5] = "-D";
}