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