Back to index

openldap  2.4.31
error.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 
00016 #include "portable.h"
00017 
00018 #include <stdio.h>
00019 
00020 #include <ac/stdlib.h>
00021 
00022 #include <ac/socket.h>
00023 #include <ac/string.h>
00024 #include <ac/time.h>
00025 
00026 #include "ldap-int.h"
00027 
00028 void ldap_int_error_init( void ) {
00029 }
00030 
00031 char *
00032 ldap_err2string( int err )
00033 {
00034        char *m;
00035 
00036        Debug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
00037 
00038        switch ( err ) {
00039 #      define C(code, message) case code: m = message; break
00040 
00041        /* LDAPv3 (RFC 4511) codes */
00042        C(LDAP_SUCCESS,                                  N_("Success"));
00043        C(LDAP_OPERATIONS_ERROR,           N_("Operations error"));
00044        C(LDAP_PROTOCOL_ERROR,                    N_("Protocol error"));
00045        C(LDAP_TIMELIMIT_EXCEEDED,         N_("Time limit exceeded"));
00046        C(LDAP_SIZELIMIT_EXCEEDED,         N_("Size limit exceeded"));
00047        C(LDAP_COMPARE_FALSE,                     N_("Compare False"));
00048        C(LDAP_COMPARE_TRUE,                      N_("Compare True"));
00049        C(LDAP_STRONG_AUTH_NOT_SUPPORTED,N_("Authentication method not supported"));
00050        C(LDAP_STRONG_AUTH_REQUIRED,       N_("Strong(er) authentication required"));
00051 
00052        C(LDAP_REFERRAL,                          N_("Referral"));
00053        C(LDAP_ADMINLIMIT_EXCEEDED,        N_("Administrative limit exceeded"));
00054        C(LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
00055                                                                N_("Critical extension is unavailable"));
00056        C(LDAP_CONFIDENTIALITY_REQUIRED,N_("Confidentiality required"));
00057        C(LDAP_SASL_BIND_IN_PROGRESS,      N_("SASL bind in progress"));
00058 
00059        C(LDAP_NO_SUCH_ATTRIBUTE,          N_("No such attribute"));
00060        C(LDAP_UNDEFINED_TYPE,                    N_("Undefined attribute type"));
00061        C(LDAP_INAPPROPRIATE_MATCHING,     N_("Inappropriate matching"));
00062        C(LDAP_CONSTRAINT_VIOLATION,       N_("Constraint violation"));
00063        C(LDAP_TYPE_OR_VALUE_EXISTS,       N_("Type or value exists"));
00064        C(LDAP_INVALID_SYNTAX,                    N_("Invalid syntax"));
00065 
00066        C(LDAP_NO_SUCH_OBJECT,                    N_("No such object"));
00067        C(LDAP_ALIAS_PROBLEM,                     N_("Alias problem"));
00068        C(LDAP_INVALID_DN_SYNTAX,          N_("Invalid DN syntax"));
00069 
00070        C(LDAP_ALIAS_DEREF_PROBLEM,        N_("Alias dereferencing problem"));
00071 
00072        C(LDAP_INAPPROPRIATE_AUTH,         N_("Inappropriate authentication"));
00073        C(LDAP_INVALID_CREDENTIALS,        N_("Invalid credentials"));
00074        C(LDAP_INSUFFICIENT_ACCESS,        N_("Insufficient access"));
00075        C(LDAP_BUSY,                              N_("Server is busy"));
00076        C(LDAP_UNAVAILABLE,                N_("Server is unavailable"));
00077        C(LDAP_UNWILLING_TO_PERFORM,       N_("Server is unwilling to perform"));
00078        C(LDAP_LOOP_DETECT,                N_("Loop detected"));
00079 
00080        C(LDAP_NAMING_VIOLATION,           N_("Naming violation"));
00081        C(LDAP_OBJECT_CLASS_VIOLATION,     N_("Object class violation"));
00082        C(LDAP_NOT_ALLOWED_ON_NONLEAF,     N_("Operation not allowed on non-leaf"));
00083        C(LDAP_NOT_ALLOWED_ON_RDN,         N_("Operation not allowed on RDN"));
00084        C(LDAP_ALREADY_EXISTS,                    N_("Already exists"));
00085        C(LDAP_NO_OBJECT_CLASS_MODS,       N_("Cannot modify object class"));
00086 
00087        C(LDAP_AFFECTS_MULTIPLE_DSAS,      N_("Operation affects multiple DSAs"));
00088 
00089        /* Virtual List View draft */
00090        C(LDAP_VLV_ERROR,                         N_("Virtual List View error"));
00091 
00092        C(LDAP_OTHER, N_("Other (e.g., implementation specific) error"));
00093 
00094        /* LDAPv2 (RFC 1777) codes */
00095        C(LDAP_PARTIAL_RESULTS, N_("Partial results and referral received"));
00096        C(LDAP_IS_LEAF,                           N_("Entry is a leaf"));
00097 
00098        /* Connection-less LDAP (CLDAP - RFC 1798) code */
00099        C(LDAP_RESULTS_TOO_LARGE,          N_("Results too large"));
00100 
00101        /* Cancel Operation (RFC 3909) codes */
00102        C(LDAP_CANCELLED,                         N_("Cancelled"));
00103        C(LDAP_NO_SUCH_OPERATION,          N_("No Operation to Cancel"));
00104        C(LDAP_TOO_LATE,                          N_("Too Late to Cancel"));
00105        C(LDAP_CANNOT_CANCEL,                     N_("Cannot Cancel"));
00106 
00107        /* Assert Control (RFC 4528 and old internet-draft) codes */
00108        C(LDAP_ASSERTION_FAILED,           N_("Assertion Failed"));
00109        C(LDAP_X_ASSERTION_FAILED,         N_("Assertion Failed (X)"));
00110 
00111        /* Proxied Authorization Control (RFC 4370 and I-D) codes */
00112        C(LDAP_PROXIED_AUTHORIZATION_DENIED, N_("Proxied Authorization Denied"));
00113        C(LDAP_X_PROXY_AUTHZ_FAILURE,      N_("Proxy Authorization Failure (X)"));
00114 
00115        /* Content Sync Operation (RFC 4533 and I-D) codes */
00116        C(LDAP_SYNC_REFRESH_REQUIRED,      N_("Content Sync Refresh Required"));
00117        C(LDAP_X_SYNC_REFRESH_REQUIRED,    N_("Content Sync Refresh Required (X)"));
00118 
00119        /* No-Op Control (draft-zeilenga-ldap-noop) code */
00120        C(LDAP_X_NO_OPERATION,                    N_("No Operation (X)"));
00121 
00122        /* Client Update Protocol (RFC 3928) codes */
00123        C(LDAP_CUP_RESOURCES_EXHAUSTED,    N_("LCUP Resources Exhausted"));
00124        C(LDAP_CUP_SECURITY_VIOLATION,     N_("LCUP Security Violation"));
00125        C(LDAP_CUP_INVALID_DATA,           N_("LCUP Invalid Data"));
00126        C(LDAP_CUP_UNSUPPORTED_SCHEME,     N_("LCUP Unsupported Scheme"));
00127        C(LDAP_CUP_RELOAD_REQUIRED,        N_("LCUP Reload Required"));
00128 
00129 #ifdef LDAP_X_TXN
00130        /* Codes related to LDAP Transactions (draft-zeilenga-ldap-txn) */
00131        C(LDAP_X_TXN_SPECIFY_OKAY,         N_("TXN specify okay"));
00132        C(LDAP_X_TXN_ID_INVALID,           N_("TXN ID is invalid"));
00133 #endif
00134 
00135        /* API codes - renumbered since draft-ietf-ldapext-ldap-c-api */
00136        C(LDAP_SERVER_DOWN,                       N_("Can't contact LDAP server"));
00137        C(LDAP_LOCAL_ERROR,                       N_("Local error"));
00138        C(LDAP_ENCODING_ERROR,                    N_("Encoding error"));
00139        C(LDAP_DECODING_ERROR,                    N_("Decoding error"));
00140        C(LDAP_TIMEOUT,                                  N_("Timed out"));
00141        C(LDAP_AUTH_UNKNOWN,               N_("Unknown authentication method"));
00142        C(LDAP_FILTER_ERROR,               N_("Bad search filter"));
00143        C(LDAP_USER_CANCELLED,                    N_("User cancelled operation"));
00144        C(LDAP_PARAM_ERROR,                       N_("Bad parameter to an ldap routine"));
00145        C(LDAP_NO_MEMORY,                         N_("Out of memory"));
00146        C(LDAP_CONNECT_ERROR,                     N_("Connect error"));
00147        C(LDAP_NOT_SUPPORTED,                     N_("Not Supported"));
00148        C(LDAP_CONTROL_NOT_FOUND,          N_("Control not found"));
00149        C(LDAP_NO_RESULTS_RETURNED,        N_("No results returned"));
00150        C(LDAP_MORE_RESULTS_TO_RETURN,     N_("More results to return"));
00151        C(LDAP_CLIENT_LOOP,                       N_("Client Loop"));
00152        C(LDAP_REFERRAL_LIMIT_EXCEEDED,    N_("Referral Limit Exceeded"));
00153 #      undef C
00154 
00155        default:
00156               m = (LDAP_API_ERROR(err) ? N_("Unknown API error")
00157                       : LDAP_E_ERROR(err) ? N_("Unknown (extension) error")
00158                       : LDAP_X_ERROR(err) ? N_("Unknown (private extension) error")
00159                       : N_("Unknown error"));
00160               break;
00161        }
00162 
00163        return _(m);
00164 }
00165 
00166 /* deprecated */
00167 void
00168 ldap_perror( LDAP *ld, LDAP_CONST char *str )
00169 {
00170     int i;
00171 
00172        assert( ld != NULL );
00173        assert( LDAP_VALID( ld ) );
00174        assert( str != NULL );
00175 
00176        fprintf( stderr, "%s: %s (%d)\n",
00177               str ? str : "ldap_perror",
00178               ldap_err2string( ld->ld_errno ),
00179               ld->ld_errno );
00180 
00181        if ( ld->ld_matched != NULL && ld->ld_matched[0] != '\0' ) {
00182               fprintf( stderr, _("\tmatched DN: %s\n"), ld->ld_matched );
00183        }
00184 
00185        if ( ld->ld_error != NULL && ld->ld_error[0] != '\0' ) {
00186               fprintf( stderr, _("\tadditional info: %s\n"), ld->ld_error );
00187        }
00188 
00189        if ( ld->ld_referrals != NULL && ld->ld_referrals[0] != NULL) {
00190               fprintf( stderr, _("\treferrals:\n") );
00191               for (i=0; ld->ld_referrals[i]; i++) {
00192                      fprintf( stderr, _("\t\t%s\n"), ld->ld_referrals[i] );
00193               }
00194        }
00195 
00196        fflush( stderr );
00197 }
00198 
00199 /* deprecated */
00200 int
00201 ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
00202 {
00203        int rc, err;
00204 
00205        rc = ldap_parse_result( ld, r, &err,
00206               NULL, NULL, NULL, NULL, freeit );
00207 
00208        return err != LDAP_SUCCESS ? err : rc;
00209 }
00210 
00211 /*
00212  * Parse LDAPResult Messages:
00213  *
00214  *   LDAPResult ::= SEQUENCE {
00215  *     resultCode      ENUMERATED,
00216  *     matchedDN       LDAPDN,
00217  *     errorMessage    LDAPString,
00218  *     referral        [3] Referral OPTIONAL }
00219  *
00220  * including Bind results:
00221  *
00222  *   BindResponse ::= [APPLICATION 1] SEQUENCE {
00223  *     COMPONENTS OF LDAPResult,
00224  *     serverSaslCreds  [7] OCTET STRING OPTIONAL }
00225  *
00226  * and ExtendedOp results:
00227  *
00228  *   ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
00229  *     COMPONENTS OF LDAPResult,
00230  *     responseName     [10] LDAPOID OPTIONAL,
00231  *     response         [11] OCTET STRING OPTIONAL }
00232  *
00233  */
00234 int
00235 ldap_parse_result(
00236        LDAP                 *ld,
00237        LDAPMessage          *r,
00238        int                         *errcodep,
00239        char                 **matcheddnp,
00240        char                 **errmsgp,
00241        char                 ***referralsp,
00242        LDAPControl          ***serverctrls,
00243        int                         freeit )
00244 {
00245        LDAPMessage   *lm;
00246        ber_int_t errcode = LDAP_SUCCESS;
00247 
00248        ber_tag_t tag;
00249        BerElement    *ber;
00250 
00251        Debug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );
00252 
00253        assert( ld != NULL );
00254        assert( LDAP_VALID( ld ) );
00255        assert( r != NULL );
00256 
00257        if(errcodep != NULL) *errcodep = LDAP_SUCCESS;
00258        if(matcheddnp != NULL) *matcheddnp = NULL;
00259        if(errmsgp != NULL) *errmsgp = NULL;
00260        if(referralsp != NULL) *referralsp = NULL;
00261        if(serverctrls != NULL) *serverctrls = NULL;
00262 
00263        LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
00264        /* Find the result, last msg in chain... */
00265        lm = r->lm_chain_tail;
00266        /* FIXME: either this is not possible (assert?)
00267         * or it should be handled */
00268        if ( lm != NULL ) {
00269               switch ( lm->lm_msgtype ) {
00270               case LDAP_RES_SEARCH_ENTRY:
00271               case LDAP_RES_SEARCH_REFERENCE:
00272               case LDAP_RES_INTERMEDIATE:
00273                      lm = NULL;
00274                      break;
00275 
00276               default:
00277                      break;
00278               }
00279        }
00280 
00281        if( lm == NULL ) {
00282               errcode = ld->ld_errno = LDAP_NO_RESULTS_RETURNED;
00283               LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
00284            goto done;
00285        }
00286 
00287        if ( ld->ld_error ) {
00288               LDAP_FREE( ld->ld_error );
00289               ld->ld_error = NULL;
00290        }
00291        if ( ld->ld_matched ) {
00292               LDAP_FREE( ld->ld_matched );
00293               ld->ld_matched = NULL;
00294        }
00295        if ( ld->ld_referrals ) {
00296               LDAP_VFREE( ld->ld_referrals );
00297               ld->ld_referrals = NULL;
00298        }
00299 
00300        /* parse results */
00301 
00302        ber = ber_dup( lm->lm_ber );
00303 
00304        if ( ld->ld_version < LDAP_VERSION2 ) {
00305               tag = ber_scanf( ber, "{iA}",
00306                      &ld->ld_errno, &ld->ld_error );
00307 
00308        } else {
00309               ber_len_t len;
00310 
00311               tag = ber_scanf( ber, "{iAA" /*}*/,
00312                      &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
00313 
00314               if( tag != LBER_ERROR ) {
00315                      /* peek for referrals */
00316                      if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
00317                             tag = ber_scanf( ber, "v", &ld->ld_referrals );
00318                      }
00319               }
00320 
00321               /* need to clean out misc items */
00322               if( tag != LBER_ERROR ) {
00323                      if( lm->lm_msgtype == LDAP_RES_BIND ) {
00324                             /* look for sasl result creditials */
00325                             if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
00326                                    /* skip 'em */
00327                                    tag = ber_scanf( ber, "x" );
00328                             }
00329 
00330                      } else if( lm->lm_msgtype == LDAP_RES_EXTENDED ) {
00331                             /* look for exop result oid or value */
00332                             if ( ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_OID ) {
00333                                    /* skip 'em */
00334                                    tag = ber_scanf( ber, "x" );
00335                             }
00336 
00337                             if ( tag != LBER_ERROR &&
00338                                    ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_VALUE )
00339                             {
00340                                    /* skip 'em */
00341                                    tag = ber_scanf( ber, "x" );
00342                             }
00343                      }
00344               }
00345 
00346               if( tag != LBER_ERROR ) {
00347                      int rc = ldap_pvt_get_controls( ber, serverctrls );
00348 
00349                      if( rc != LDAP_SUCCESS ) {
00350                             tag = LBER_ERROR;
00351                      }
00352               }
00353 
00354               if( tag != LBER_ERROR ) {
00355                      tag = ber_scanf( ber, /*{*/"}" );
00356               }
00357        }
00358 
00359        if ( tag == LBER_ERROR ) {
00360               ld->ld_errno = errcode = LDAP_DECODING_ERROR;
00361        }
00362 
00363        if( ber != NULL ) {
00364               ber_free( ber, 0 );
00365        }
00366 
00367        /* return */
00368        if( errcodep != NULL ) {
00369               *errcodep = ld->ld_errno;
00370        }
00371        if ( errcode == LDAP_SUCCESS ) {
00372               if( matcheddnp != NULL ) {
00373                      if ( ld->ld_matched )
00374                      {
00375                             *matcheddnp = LDAP_STRDUP( ld->ld_matched );
00376                      }
00377               }
00378               if( errmsgp != NULL ) {
00379                      if ( ld->ld_error )
00380                      {
00381                             *errmsgp = LDAP_STRDUP( ld->ld_error );
00382                      }
00383               }
00384 
00385               if( referralsp != NULL) {
00386                      *referralsp = ldap_value_dup( ld->ld_referrals );
00387               }
00388        }
00389        LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
00390 
00391 done:
00392        if ( freeit ) {
00393               ldap_msgfree( r );
00394        }
00395 
00396        return errcode;
00397 }