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