1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1999-2011 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 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>. 14 */ 15/* ACKNOWLEDGEMENTS: 16 * This work was initially developed by Howard Chu for inclusion 17 * in OpenLDAP Software. 18 */ 19 20#include "portable.h" 21 22#include <stdio.h> 23 24#include "ac/stdlib.h" 25#include "ac/unistd.h" 26#include "ac/string.h" 27#include "ac/errno.h" 28 29#include "ldap.h" 30 31#include "ldap_pvt.h" 32#include "slapd-common.h" 33 34/* global vars */ 35pid_t pid; 36 37/* static vars */ 38static char progname[ BUFSIZ ]; 39tester_t progtype; 40 41/* 42 * ignore_count[] is indexed by result code: 43 * negative for OpenLDAP client-side errors, positive for protocol codes. 44 */ 45#define TESTER_CLIENT_FIRST LDAP_REFERRAL_LIMIT_EXCEEDED /* negative */ 46#define TESTER_SERVER_LAST LDAP_OTHER 47static int ignore_base [ -TESTER_CLIENT_FIRST + TESTER_SERVER_LAST + 1 ]; 48#define ignore_count (ignore_base - TESTER_CLIENT_FIRST) 49 50static const struct { 51 const char *name; 52 int err; 53} ignore_str2err[] = { 54 { "OPERATIONS_ERROR", LDAP_OPERATIONS_ERROR }, 55 { "PROTOCOL_ERROR", LDAP_PROTOCOL_ERROR }, 56 { "TIMELIMIT_EXCEEDED", LDAP_TIMELIMIT_EXCEEDED }, 57 { "SIZELIMIT_EXCEEDED", LDAP_SIZELIMIT_EXCEEDED }, 58 { "COMPARE_FALSE", LDAP_COMPARE_FALSE }, 59 { "COMPARE_TRUE", LDAP_COMPARE_TRUE }, 60 { "AUTH_METHOD_NOT_SUPPORTED", LDAP_AUTH_METHOD_NOT_SUPPORTED }, 61 { "STRONG_AUTH_NOT_SUPPORTED", LDAP_STRONG_AUTH_NOT_SUPPORTED }, 62 { "STRONG_AUTH_REQUIRED", LDAP_STRONG_AUTH_REQUIRED }, 63 { "STRONGER_AUTH_REQUIRED", LDAP_STRONGER_AUTH_REQUIRED }, 64 { "PARTIAL_RESULTS", LDAP_PARTIAL_RESULTS }, 65 66 { "REFERRAL", LDAP_REFERRAL }, 67 { "ADMINLIMIT_EXCEEDED", LDAP_ADMINLIMIT_EXCEEDED }, 68 { "UNAVAILABLE_CRITICAL_EXTENSION", LDAP_UNAVAILABLE_CRITICAL_EXTENSION }, 69 { "CONFIDENTIALITY_REQUIRED", LDAP_CONFIDENTIALITY_REQUIRED }, 70 { "SASL_BIND_IN_PROGRESS", LDAP_SASL_BIND_IN_PROGRESS }, 71 72 { "NO_SUCH_ATTRIBUTE", LDAP_NO_SUCH_ATTRIBUTE }, 73 { "UNDEFINED_TYPE", LDAP_UNDEFINED_TYPE }, 74 { "INAPPROPRIATE_MATCHING", LDAP_INAPPROPRIATE_MATCHING }, 75 { "CONSTRAINT_VIOLATION", LDAP_CONSTRAINT_VIOLATION }, 76 { "TYPE_OR_VALUE_EXISTS", LDAP_TYPE_OR_VALUE_EXISTS }, 77 { "INVALID_SYNTAX", LDAP_INVALID_SYNTAX }, 78 79 { "NO_SUCH_OBJECT", LDAP_NO_SUCH_OBJECT }, 80 { "ALIAS_PROBLEM", LDAP_ALIAS_PROBLEM }, 81 { "INVALID_DN_SYNTAX", LDAP_INVALID_DN_SYNTAX }, 82 { "IS_LEAF", LDAP_IS_LEAF }, 83 { "ALIAS_DEREF_PROBLEM", LDAP_ALIAS_DEREF_PROBLEM }, 84 85 /* obsolete */ 86 { "PROXY_AUTHZ_FAILURE", LDAP_X_PROXY_AUTHZ_FAILURE }, 87 { "INAPPROPRIATE_AUTH", LDAP_INAPPROPRIATE_AUTH }, 88 { "INVALID_CREDENTIALS", LDAP_INVALID_CREDENTIALS }, 89 { "INSUFFICIENT_ACCESS", LDAP_INSUFFICIENT_ACCESS }, 90 91 { "BUSY", LDAP_BUSY }, 92 { "UNAVAILABLE", LDAP_UNAVAILABLE }, 93 { "UNWILLING_TO_PERFORM", LDAP_UNWILLING_TO_PERFORM }, 94 { "LOOP_DETECT", LDAP_LOOP_DETECT }, 95 96 { "NAMING_VIOLATION", LDAP_NAMING_VIOLATION }, 97 { "OBJECT_CLASS_VIOLATION", LDAP_OBJECT_CLASS_VIOLATION }, 98 { "NOT_ALLOWED_ON_NONLEAF", LDAP_NOT_ALLOWED_ON_NONLEAF }, 99 { "NOT_ALLOWED_ON_RDN", LDAP_NOT_ALLOWED_ON_RDN }, 100 { "ALREADY_EXISTS", LDAP_ALREADY_EXISTS }, 101 { "NO_OBJECT_CLASS_MODS", LDAP_NO_OBJECT_CLASS_MODS }, 102 { "RESULTS_TOO_LARGE", LDAP_RESULTS_TOO_LARGE }, 103 { "AFFECTS_MULTIPLE_DSAS", LDAP_AFFECTS_MULTIPLE_DSAS }, 104 105 { "OTHER", LDAP_OTHER }, 106 107 { "SERVER_DOWN", LDAP_SERVER_DOWN }, 108 { "LOCAL_ERROR", LDAP_LOCAL_ERROR }, 109 { "ENCODING_ERROR", LDAP_ENCODING_ERROR }, 110 { "DECODING_ERROR", LDAP_DECODING_ERROR }, 111 { "TIMEOUT", LDAP_TIMEOUT }, 112 { "AUTH_UNKNOWN", LDAP_AUTH_UNKNOWN }, 113 { "FILTER_ERROR", LDAP_FILTER_ERROR }, 114 { "USER_CANCELLED", LDAP_USER_CANCELLED }, 115 { "PARAM_ERROR", LDAP_PARAM_ERROR }, 116 { "NO_MEMORY", LDAP_NO_MEMORY }, 117 { "CONNECT_ERROR", LDAP_CONNECT_ERROR }, 118 { "NOT_SUPPORTED", LDAP_NOT_SUPPORTED }, 119 { "CONTROL_NOT_FOUND", LDAP_CONTROL_NOT_FOUND }, 120 { "NO_RESULTS_RETURNED", LDAP_NO_RESULTS_RETURNED }, 121 { "MORE_RESULTS_TO_RETURN", LDAP_MORE_RESULTS_TO_RETURN }, 122 { "CLIENT_LOOP", LDAP_CLIENT_LOOP }, 123 { "REFERRAL_LIMIT_EXCEEDED", LDAP_REFERRAL_LIMIT_EXCEEDED }, 124 125 { NULL } 126}; 127 128#define UNKNOWN_ERR (1234567890) 129 130static int 131tester_ignore_str2err( const char *err ) 132{ 133 int i, ignore = 1; 134 135 if ( strcmp( err, "ALL" ) == 0 ) { 136 for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) { 137 ignore_count[ ignore_str2err[ i ].err ] = 1; 138 } 139 ignore_count[ LDAP_SUCCESS ] = 0; 140 141 return 0; 142 } 143 144 if ( err[ 0 ] == '!' ) { 145 ignore = 0; 146 err++; 147 148 } else if ( err[ 0 ] == '*' ) { 149 ignore = -1; 150 err++; 151 } 152 153 for ( i = 0; ignore_str2err[ i ].name != NULL; i++ ) { 154 if ( strcmp( err, ignore_str2err[ i ].name ) == 0 ) { 155 int err = ignore_str2err[ i ].err; 156 157 if ( err != LDAP_SUCCESS ) { 158 ignore_count[ err ] = ignore; 159 } 160 161 return err; 162 } 163 } 164 165 return UNKNOWN_ERR; 166} 167 168int 169tester_ignore_str2errlist( const char *err ) 170{ 171 int i; 172 char **errs = ldap_str2charray( err, "," ); 173 174 for ( i = 0; errs[ i ] != NULL; i++ ) { 175 /* TODO: allow <err>:<prog> to ignore <err> only when <prog> */ 176 (void)tester_ignore_str2err( errs[ i ] ); 177 } 178 179 ldap_charray_free( errs ); 180 181 return 0; 182} 183 184int 185tester_ignore_err( int err ) 186{ 187 int rc = 1; 188 189 if ( err && TESTER_CLIENT_FIRST <= err && err <= TESTER_SERVER_LAST ) { 190 rc = ignore_count[ err ]; 191 if ( rc != 0 ) { 192 ignore_count[ err ] = rc + (rc > 0 ? 1 : -1); 193 } 194 } 195 196 /* SUCCESS is always "ignored" */ 197 return rc; 198} 199 200void 201tester_init( const char *pname, tester_t ptype ) 202{ 203 pid = getpid(); 204 srand( pid ); 205 snprintf( progname, sizeof( progname ), "%s PID=%d", pname, pid ); 206 progtype = ptype; 207} 208 209char * 210tester_uri( char *uri, char *host, int port ) 211{ 212 static char uribuf[ BUFSIZ ]; 213 214 if ( uri != NULL ) { 215 return uri; 216 } 217 218 snprintf( uribuf, sizeof( uribuf ), "ldap://%s:%d", host, port ); 219 220 return uribuf; 221} 222 223void 224tester_ldap_error( LDAP *ld, const char *fname, const char *msg ) 225{ 226 int err; 227 char *text = NULL; 228 LDAPControl **ctrls = NULL; 229 230 ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&err ); 231 if ( err != LDAP_SUCCESS ) { 232 ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void *)&text ); 233 } 234 235 fprintf( stderr, "%s: %s: %s (%d) %s %s\n", 236 progname, fname, ldap_err2string( err ), err, 237 text == NULL ? "" : text, 238 msg ? msg : "" ); 239 240 if ( text ) { 241 ldap_memfree( text ); 242 text = NULL; 243 } 244 245 ldap_get_option( ld, LDAP_OPT_MATCHED_DN, (void *)&text ); 246 if ( text != NULL ) { 247 if ( text[ 0 ] != '\0' ) { 248 fprintf( stderr, "\tmatched: %s\n", text ); 249 } 250 ldap_memfree( text ); 251 text = NULL; 252 } 253 254 ldap_get_option( ld, LDAP_OPT_SERVER_CONTROLS, (void *)&ctrls ); 255 if ( ctrls != NULL ) { 256 int i; 257 258 fprintf( stderr, "\tcontrols:\n" ); 259 for ( i = 0; ctrls[ i ] != NULL; i++ ) { 260 fprintf( stderr, "\t\t%s\n", ctrls[ i ]->ldctl_oid ); 261 } 262 ldap_controls_free( ctrls ); 263 ctrls = NULL; 264 } 265 266 if ( err == LDAP_REFERRAL ) { 267 char **refs = NULL; 268 269 ldap_get_option( ld, LDAP_OPT_REFERRAL_URLS, (void *)&refs ); 270 271 if ( refs ) { 272 int i; 273 274 fprintf( stderr, "\treferral:\n" ); 275 for ( i = 0; refs[ i ] != NULL; i++ ) { 276 fprintf( stderr, "\t\t%s\n", refs[ i ] ); 277 } 278 279 ber_memvfree( (void **)refs ); 280 } 281 } 282} 283 284void 285tester_perror( const char *fname, const char *msg ) 286{ 287 int save_errno = errno; 288 char buf[ BUFSIZ ]; 289 290 fprintf( stderr, "%s: %s: (%d) %s %s\n", 291 progname, fname, save_errno, 292 AC_STRERROR_R( save_errno, buf, sizeof( buf ) ), 293 msg ? msg : "" ); 294} 295 296void 297tester_error( const char *msg ) 298{ 299 fprintf( stderr, "%s: %s\n", progname, msg ); 300} 301