2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2017 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Howard Chu for inclusion
17 * in OpenLDAP Software.
24 #include "ac/stdlib.h"
25 #include "ac/unistd.h"
26 #include "ac/string.h"
33 #include "slapd-common.h"
39 static char progname[ BUFSIZ ];
43 * ignore_count[] is indexed by result code:
44 * negative for OpenLDAP client-side errors, positive for protocol codes.
46 #define TESTER_CLIENT_FIRST LDAP_REFERRAL_LIMIT_EXCEEDED /* negative */
47 #define TESTER_SERVER_LAST LDAP_OTHER
48 static int ignore_base [ -TESTER_CLIENT_FIRST + TESTER_SERVER_LAST + 1 ];
49 #define ignore_count (ignore_base - TESTER_CLIENT_FIRST)
54 } ignore_str2err[] = {
55 { "OPERATIONS_ERROR", LDAP_OPERATIONS_ERROR },
56 { "PROTOCOL_ERROR", LDAP_PROTOCOL_ERROR },
57 { "TIMELIMIT_EXCEEDED", LDAP_TIMELIMIT_EXCEEDED },
58 { "SIZELIMIT_EXCEEDED", LDAP_SIZELIMIT_EXCEEDED },
59 { "COMPARE_FALSE", LDAP_COMPARE_FALSE },
60 { "COMPARE_TRUE", LDAP_COMPARE_TRUE },
61 { "AUTH_METHOD_NOT_SUPPORTED", LDAP_AUTH_METHOD_NOT_SUPPORTED },
62 { "STRONG_AUTH_NOT_SUPPORTED", LDAP_STRONG_AUTH_NOT_SUPPORTED },
63 { "STRONG_AUTH_REQUIRED", LDAP_STRONG_AUTH_REQUIRED },
64 { "STRONGER_AUTH_REQUIRED", LDAP_STRONGER_AUTH_REQUIRED },
65 { "PARTIAL_RESULTS", LDAP_PARTIAL_RESULTS },
67 { "REFERRAL", LDAP_REFERRAL },
68 { "ADMINLIMIT_EXCEEDED", LDAP_ADMINLIMIT_EXCEEDED },
69 { "UNAVAILABLE_CRITICAL_EXTENSION", LDAP_UNAVAILABLE_CRITICAL_EXTENSION },
70 { "CONFIDENTIALITY_REQUIRED", LDAP_CONFIDENTIALITY_REQUIRED },
71 { "SASL_BIND_IN_PROGRESS", LDAP_SASL_BIND_IN_PROGRESS },
73 { "NO_SUCH_ATTRIBUTE", LDAP_NO_SUCH_ATTRIBUTE },
74 { "UNDEFINED_TYPE", LDAP_UNDEFINED_TYPE },
75 { "INAPPROPRIATE_MATCHING", LDAP_INAPPROPRIATE_MATCHING },
76 { "CONSTRAINT_VIOLATION", LDAP_CONSTRAINT_VIOLATION },
77 { "TYPE_OR_VALUE_EXISTS", LDAP_TYPE_OR_VALUE_EXISTS },
78 { "INVALID_SYNTAX", LDAP_INVALID_SYNTAX },
80 { "NO_SUCH_OBJECT", LDAP_NO_SUCH_OBJECT },
81 { "ALIAS_PROBLEM", LDAP_ALIAS_PROBLEM },
82 { "INVALID_DN_SYNTAX", LDAP_INVALID_DN_SYNTAX },
83 { "IS_LEAF", LDAP_IS_LEAF },
84 { "ALIAS_DEREF_PROBLEM", LDAP_ALIAS_DEREF_PROBLEM },
87 { "PROXY_AUTHZ_FAILURE", LDAP_X_PROXY_AUTHZ_FAILURE },
88 { "INAPPROPRIATE_AUTH", LDAP_INAPPROPRIATE_AUTH },
89 { "INVALID_CREDENTIALS", LDAP_INVALID_CREDENTIALS },
90 { "INSUFFICIENT_ACCESS", LDAP_INSUFFICIENT_ACCESS },
92 { "BUSY", LDAP_BUSY },
93 { "UNAVAILABLE", LDAP_UNAVAILABLE },
94 { "UNWILLING_TO_PERFORM", LDAP_UNWILLING_TO_PERFORM },
95 { "LOOP_DETECT", LDAP_LOOP_DETECT },
97 { "NAMING_VIOLATION", LDAP_NAMING_VIOLATION },
98 { "OBJECT_CLASS_VIOLATION", LDAP_OBJECT_CLASS_VIOLATION },
99 { "NOT_ALLOWED_ON_NONLEAF", LDAP_NOT_ALLOWED_ON_NONLEAF },
100 { "NOT_ALLOWED_ON_RDN", LDAP_NOT_ALLOWED_ON_RDN },
101 { "ALREADY_EXISTS", LDAP_ALREADY_EXISTS },
102 { "NO_OBJECT_CLASS_MODS", LDAP_NO_OBJECT_CLASS_MODS },
103 { "RESULTS_TOO_LARGE", LDAP_RESULTS_TOO_LARGE },
104 { "AFFECTS_MULTIPLE_DSAS", LDAP_AFFECTS_MULTIPLE_DSAS },
106 { "OTHER", LDAP_OTHER },
108 { "SERVER_DOWN", LDAP_SERVER_DOWN },
109 { "LOCAL_ERROR", LDAP_LOCAL_ERROR },
110 { "ENCODING_ERROR", LDAP_ENCODING_ERROR },
111 { "DECODING_ERROR", LDAP_DECODING_ERROR },
112 { "TIMEOUT", LDAP_TIMEOUT },
113 { "AUTH_UNKNOWN", LDAP_AUTH_UNKNOWN },
114 { "FILTER_ERROR", LDAP_FILTER_ERROR },
115 { "USER_CANCELLED", LDAP_USER_CANCELLED },
116 { "PARAM_ERROR", LDAP_PARAM_ERROR },
117 { "NO_MEMORY", LDAP_NO_MEMORY },
118 { "CONNECT_ERROR", LDAP_CONNECT_ERROR },
119 { "NOT_SUPPORTED", LDAP_NOT_SUPPORTED },
120 { "CONTROL_NOT_FOUND", LDAP_CONTROL_NOT_FOUND },
121 { "NO_RESULTS_RETURNED", LDAP_NO_RESULTS_RETURNED },
122 { "MORE_RESULTS_TO_RETURN", LDAP_MORE_RESULTS_TO_RETURN },
123 { "CLIENT_LOOP", LDAP_CLIENT_LOOP },
124 { "REFERRAL_LIMIT_EXCEEDED", LDAP_REFERRAL_LIMIT_EXCEEDED },
129 #define UNKNOWN_ERR (1234567890)
135 tester_ignore_str2err( const char *err )
139 if ( strcmp( err, "ALL" ) == 0 ) {
140 for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) {
141 ignore_count[ ignore_str2err[ i ].err ] = 1;
143 ignore_count[ LDAP_SUCCESS ] = 0;
148 if ( err[ 0 ] == '!' ) {
152 } else if ( err[ 0 ] == '*' ) {
157 for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) {
158 if ( strcmp( err, ignore_str2err[ i ].name ) == 0 ) {
159 int err = ignore_str2err[ i ].err;
161 if ( err != LDAP_SUCCESS ) {
162 ignore_count[ err ] = ignore;
173 tester_ignore_str2errlist( const char *err )
176 char **errs = ldap_str2charray( err, "," );
178 for ( i = 0; errs[ i ] != NULL; i++ ) {
179 /* TODO: allow <err>:<prog> to ignore <err> only when <prog> */
180 (void)tester_ignore_str2err( errs[ i ] );
183 ldap_charray_free( errs );
189 tester_ignore_err( int err )
193 if ( err && TESTER_CLIENT_FIRST <= err && err <= TESTER_SERVER_LAST ) {
194 rc = ignore_count[ err ];
196 ignore_count[ err ] = rc + (rc > 0 ? 1 : -1);
200 /* SUCCESS is always "ignored" */
204 struct tester_conn_args *
205 tester_init( const char *pname, tester_t ptype )
207 static struct tester_conn_args config = {
220 snprintf( progname, sizeof( progname ), "%s PID=%d", pname, pid );
227 tester_ldap_error( LDAP *ld, const char *fname, const char *msg )
231 LDAPControl **ctrls = NULL;
233 ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&err );
234 if ( err != LDAP_SUCCESS ) {
235 ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void *)&text );
238 fprintf( stderr, "%s: %s: %s (%d) %s %s\n",
239 progname, fname, ldap_err2string( err ), err,
240 text == NULL ? "" : text,
244 ldap_memfree( text );
248 ldap_get_option( ld, LDAP_OPT_MATCHED_DN, (void *)&text );
249 if ( text != NULL ) {
250 if ( text[ 0 ] != '\0' ) {
251 fprintf( stderr, "\tmatched: %s\n", text );
253 ldap_memfree( text );
257 ldap_get_option( ld, LDAP_OPT_SERVER_CONTROLS, (void *)&ctrls );
258 if ( ctrls != NULL ) {
261 fprintf( stderr, "\tcontrols:\n" );
262 for ( i = 0; ctrls[ i ] != NULL; i++ ) {
263 fprintf( stderr, "\t\t%s\n", ctrls[ i ]->ldctl_oid );
265 ldap_controls_free( ctrls );
269 if ( err == LDAP_REFERRAL ) {
272 ldap_get_option( ld, LDAP_OPT_REFERRAL_URLS, (void *)&refs );
277 fprintf( stderr, "\treferral:\n" );
278 for ( i = 0; refs[ i ] != NULL; i++ ) {
279 fprintf( stderr, "\t\t%s\n", refs[ i ] );
282 ber_memvfree( (void **)refs );
288 tester_perror( const char *fname, const char *msg )
290 int save_errno = errno;
293 fprintf( stderr, "%s: %s: (%d) %s %s\n",
294 progname, fname, save_errno,
295 AC_STRERROR_R( save_errno, buf, sizeof( buf ) ),
300 tester_config_opt( struct tester_conn_args *config, char opt, char *optarg )
308 config->binddn = strdup( optarg );
314 if ( lutil_atoi( &debug, optarg ) != 0 ) {
318 if ( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug )
319 != LBER_OPT_SUCCESS )
322 "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
325 if ( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
326 != LDAP_OPT_SUCCESS )
329 "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
335 config->uri = strdup( optarg );
339 config->host = strdup( optarg );
343 tester_ignore_str2errlist( optarg );
347 if ( lutil_atoi( &config->outerloops, optarg ) != 0 ) {
353 if ( lutil_atoi( &config->loops, optarg ) != 0 ) {
359 if ( lutil_atoi( &config->port, optarg ) != 0 ) {
365 if ( lutil_atoi( &config->retries, optarg ) != 0 ) {
371 if ( lutil_atoi( &config->delay, optarg ) != 0 ) {
377 config->pass.bv_val = strdup( optarg );
378 config->pass.bv_len = strlen( optarg );
379 memset( optarg, '*', config->pass.bv_len );
383 if ( config->authmethod != -1 && config->authmethod != LDAP_AUTH_SIMPLE ) {
386 config->authmethod = LDAP_AUTH_SIMPLE;
397 tester_config_finish( struct tester_conn_args *config )
399 if ( !config->uri ) {
400 static char uribuf[ BUFSIZ ];
402 config->uri = uribuf;
403 snprintf( uribuf, sizeof( uribuf ), "ldap://%s:%d",
404 config->host, config->port );
407 if ( config->authmethod == -1 ) {
408 config->authmethod = LDAP_AUTH_SIMPLE;
413 tester_init_ld( LDAP **ldp, struct tester_conn_args *config, int flags )
416 int rc, do_retry = config->retries;
417 int version = LDAP_VERSION3;
420 ldap_initialize( &ld, config->uri );
422 tester_perror( "ldap_initialize", NULL );
423 exit( EXIT_FAILURE );
426 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
427 (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
428 config->chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF );
430 if ( !( flags & TESTER_INIT_ONLY ) ) {
431 rc = ldap_sasl_bind_s( ld,
432 config->binddn, LDAP_SASL_SIMPLE,
433 &config->pass, NULL, NULL, NULL );
435 if ( rc != LDAP_SUCCESS ) {
436 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
439 case LDAP_UNAVAILABLE:
440 if ( do_retry > 0 ) {
442 if ( config->delay > 0 ) {
443 sleep( config->delay );
448 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
449 exit( EXIT_FAILURE );
457 tester_error( const char *msg )
459 fprintf( stderr, "%s: %s\n", progname, msg );