home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / error.c < prev    next >
C/C++ Source or Header  |  2000-07-29  |  9KB  |  361 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/error.c,v 1.20.4.6 2000/07/29 01:53:08 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6.  
  7. #include "portable.h"
  8.  
  9. #include <stdio.h>
  10.  
  11. #include <ac/stdlib.h>
  12.  
  13. #include <ac/socket.h>
  14. #include <ac/string.h>
  15. #include <ac/time.h>
  16.  
  17. #include "ldap-int.h"
  18.  
  19. struct ldaperror {
  20.     int    e_code;
  21.     char    *e_reason;
  22. };
  23.  
  24. static const struct ldaperror ldap_errlist[] = {
  25.     {LDAP_SUCCESS,                     "Success" },
  26.     {LDAP_OPERATIONS_ERROR,         "Operations error" },
  27.     {LDAP_PROTOCOL_ERROR,             "Protocol error" },
  28.     {LDAP_TIMELIMIT_EXCEEDED,        "Time limit exceeded" },
  29.     {LDAP_SIZELIMIT_EXCEEDED,         "Size limit exceeded" },
  30.     {LDAP_COMPARE_FALSE,             "Compare false" },
  31.     {LDAP_COMPARE_TRUE,             "Compare true" },
  32.     {LDAP_STRONG_AUTH_NOT_SUPPORTED, "Authentication method not supported" },
  33.     {LDAP_STRONG_AUTH_REQUIRED,     "Strong authentication required" },
  34.     {LDAP_PARTIAL_RESULTS,             "Partial results and referral received" },
  35.  
  36.     {LDAP_REFERRAL,                    "Referral"},
  37.     {LDAP_ADMINLIMIT_EXCEEDED,        "Administrative limit exceeded"},
  38.     {LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
  39.                                     "Criticial extension is unavailable"},
  40.     {LDAP_CONFIDENTIALITY_REQUIRED,    "Confidentiality required"},
  41.     {LDAP_SASL_BIND_IN_PROGRESS,    "SASL bind in progress"},
  42.  
  43.     {LDAP_NO_SUCH_ATTRIBUTE,         "No such attribute" },
  44.     {LDAP_UNDEFINED_TYPE,             "Undefined attribute type" },
  45.     {LDAP_INAPPROPRIATE_MATCHING,     "Inappropriate matching" },
  46.     {LDAP_CONSTRAINT_VIOLATION,     "Constraint violation" },
  47.     {LDAP_TYPE_OR_VALUE_EXISTS,     "Type or value exists" },
  48.     {LDAP_INVALID_SYNTAX,             "Invalid syntax" },
  49.  
  50.     {LDAP_NO_SUCH_OBJECT,             "No such object" },
  51.     {LDAP_ALIAS_PROBLEM,             "Alias problem" },
  52.     {LDAP_INVALID_DN_SYNTAX,        "Invalid DN syntax" },
  53.     {LDAP_IS_LEAF,                     "Entry is a leaf" },
  54.     {LDAP_ALIAS_DEREF_PROBLEM,         "Alias dereferencing problem" },
  55.  
  56.     {LDAP_INAPPROPRIATE_AUTH,         "Inappropriate authentication" },
  57.     {LDAP_INVALID_CREDENTIALS,         "Invalid credentials" },
  58.     {LDAP_INSUFFICIENT_ACCESS,         "Insufficient access" },
  59.     {LDAP_BUSY,                     "DSA is busy" },
  60.     {LDAP_UNAVAILABLE,                 "DSA is unavailable" },
  61.     {LDAP_UNWILLING_TO_PERFORM,     "DSA is unwilling to perform" },
  62.     {LDAP_LOOP_DETECT,                 "Loop detected" },
  63.  
  64.     {LDAP_NAMING_VIOLATION,         "Naming violation" },
  65.     {LDAP_OBJECT_CLASS_VIOLATION,     "Object class violation" },
  66.     {LDAP_NOT_ALLOWED_ON_NONLEAF,     "Operation not allowed on nonleaf" },
  67.     {LDAP_NOT_ALLOWED_ON_RDN,         "Operation not allowed on RDN" },
  68.     {LDAP_ALREADY_EXISTS,             "Already exists" },
  69.     {LDAP_NO_OBJECT_CLASS_MODS,     "Cannot modify object class" },
  70.     {LDAP_RESULTS_TOO_LARGE,        "Results too large" },
  71.     {LDAP_AFFECTS_MULTIPLE_DSAS,    "Operation affects multiple DSAs" },
  72.  
  73.     {LDAP_OTHER,                     "Unknown error" },
  74.  
  75.     /* API ResultCodes */
  76.     {LDAP_SERVER_DOWN,                "Can't contact LDAP server" },
  77.     {LDAP_LOCAL_ERROR,                "Local error" },
  78.     {LDAP_ENCODING_ERROR,            "Encoding error" },
  79.     {LDAP_DECODING_ERROR,            "Decoding error" },
  80.     {LDAP_TIMEOUT,                    "Timed out" },
  81.     {LDAP_AUTH_UNKNOWN,                "Unknown authentication method" },
  82.     {LDAP_FILTER_ERROR,                "Bad search filter" },
  83.     {LDAP_USER_CANCELLED,            "User cancelled operation" },
  84.     {LDAP_PARAM_ERROR,                "Bad parameter to an ldap routine" },
  85.     {LDAP_NO_MEMORY,                "Out of memory" },
  86.  
  87.     {LDAP_CONNECT_ERROR,            "Connect error" },
  88.     {LDAP_NOT_SUPPORTED,            "Not Supported" },
  89.     {LDAP_CONTROL_NOT_FOUND,        "Control not found" },
  90.     {LDAP_NO_RESULTS_RETURNED,        "No results returned" },
  91.     {LDAP_MORE_RESULTS_TO_RETURN,    "More results to return" },
  92.     {LDAP_CLIENT_LOOP,                "Client Loop" },
  93.     {LDAP_REFERRAL_LIMIT_EXCEEDED,    "Referral Limit Exceeded" },
  94.  
  95.     {-1, NULL }
  96. };
  97.  
  98. static const struct ldaperror *
  99. ldap_int_error( int err )
  100. {
  101.     int    i;
  102.  
  103.     for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
  104.         if ( err == ldap_errlist[i].e_code )
  105.             return &ldap_errlist[i];
  106.     }
  107.  
  108.     return NULL;
  109. }
  110.  
  111. char *
  112. ldap_err2string( int err )
  113. {
  114.     const struct ldaperror *e;
  115.     
  116.     Debug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
  117.  
  118.     e = ldap_int_error( err );
  119.  
  120.     return ( e != NULL ) ? e->e_reason : "Unknown error";
  121. }
  122.  
  123. /* deprecated */
  124. void
  125. ldap_perror( LDAP *ld, LDAP_CONST char *str )
  126. {
  127.     const char *s;
  128.     const struct ldaperror *e;
  129.     Debug( LDAP_DEBUG_TRACE, "ldap_perror\n", 0, 0, 0 );
  130.  
  131.     assert( ld != NULL );
  132.     assert( LDAP_VALID( ld ) );
  133.     assert( str );
  134.  
  135.     s = ( str != NULL ) ? str : "ldap_perror";
  136.  
  137.     if ( ld == NULL ) {
  138.         perror( s );
  139.         return;
  140.     }
  141.  
  142.     e = ldap_int_error( ld->ld_errno );
  143.  
  144.     if ( e != NULL ) {
  145.         fprintf( stderr, "%s: %s\n",
  146.             s, e->e_reason );
  147.     } else {
  148.         fprintf( stderr, "%s: unknown LDAP error number %d\n",
  149.             s, ld->ld_errno );
  150.     }
  151.  
  152.     if ( ld->ld_matched != NULL && ld->ld_matched[0] != '\0' ) {
  153.         fprintf( stderr, "\tmatched DN: \"%s\"\n",
  154.             ld->ld_matched );
  155.     }
  156.  
  157.     if ( ld->ld_error != NULL && ld->ld_error[0] != '\0' ) {
  158.         fprintf( stderr, "\tadditional info: %s\n",
  159.             ld->ld_error );
  160.     }
  161.  
  162.     fflush( stderr );
  163. }
  164.  
  165. /* deprecated */
  166. int
  167. ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
  168. {
  169.     int rc, err;
  170.  
  171.     rc = ldap_parse_result( ld, r, &err,
  172.         NULL, NULL, NULL, NULL, freeit );
  173.  
  174.     return err != LDAP_SUCCESS ? err : rc;
  175. }
  176.  
  177. /*
  178.  * Parse LDAPResult Messages:
  179.  *
  180.  *   LDAPResult ::= SEQUENCE {
  181.  *     resultCode      ENUMERATED,
  182.  *     matchedDN       LDAPDN,
  183.  *     errorMessage    LDAPString,
  184.  *     referral        [3] Referral OPTIONAL }
  185.  *
  186.  * including Bind results:
  187.  *
  188.  *   BindResponse ::= [APPLICATION 1] SEQUENCE {
  189.  *     COMPONENTS OF LDAPResult,
  190.  *     serverSaslCreds  [7] OCTET STRING OPTIONAL }
  191.  * 
  192.  * and ExtendedOp results:
  193.  *
  194.  *   ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
  195.  *     COMPONENTS OF LDAPResult,
  196.  *     responseName     [10] LDAPOID OPTIONAL,
  197.  *     response         [11] OCTET STRING OPTIONAL }
  198.  *
  199.  */
  200. int
  201. ldap_parse_result(
  202.     LDAP            *ld,
  203.     LDAPMessage        *r,
  204.     int                *errcodep,
  205.     char            **matcheddnp,
  206.     char            **errmsgp,
  207.     char            ***referralsp,
  208.     LDAPControl        ***serverctrls,
  209.     int                freeit )
  210. {
  211.     LDAPMessage    *lm;
  212.     ber_int_t errcode = LDAP_SUCCESS;
  213.  
  214.     ber_tag_t tag;
  215.     BerElement    *ber;
  216.  
  217.     Debug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );
  218.  
  219.     assert( ld != NULL );
  220.     assert( LDAP_VALID( ld ) );
  221.     assert( r != NULL );
  222.  
  223.     if ( ld == NULL || r == NULL ) {
  224.         return LDAP_PARAM_ERROR;
  225.     }
  226.  
  227.     if(errcodep != NULL) *errcodep = LDAP_SUCCESS;
  228.     if(matcheddnp != NULL) *matcheddnp = NULL;
  229.     if(errmsgp != NULL) *errmsgp = NULL;
  230.     if(referralsp != NULL) *referralsp = NULL;
  231.     if(serverctrls != NULL) *serverctrls = NULL;
  232.  
  233.     /* Find the next result... */
  234.     for ( lm = r; lm != NULL; lm = lm->lm_chain ) {
  235.         /* skip over entries and references */
  236.         if( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
  237.             lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE &&
  238.             lm->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL )
  239.         {
  240.             break;
  241.         }
  242.     }
  243.  
  244.     if( lm == NULL ) {
  245.         ld->ld_errno = LDAP_NO_RESULTS_RETURNED;
  246.         return ld->ld_errno;
  247.     }
  248.  
  249.     if ( ld->ld_error ) {
  250.         LDAP_FREE( ld->ld_error );
  251.         ld->ld_error = NULL;
  252.     }
  253.     if ( ld->ld_matched ) {
  254.         LDAP_FREE( ld->ld_matched );
  255.         ld->ld_matched = NULL;
  256.     }
  257.  
  258.     /* parse results */
  259.  
  260.     ber = ber_dup( lm->lm_ber );
  261.  
  262.     if ( ld->ld_version < LDAP_VERSION2 ) {
  263.         tag = ber_scanf( ber, "{ia}",
  264.             &ld->ld_errno, &ld->ld_error );
  265.     } else {
  266.         ber_len_t len;
  267.         tag = ber_scanf( ber, "{iaa" /*}*/,
  268.             &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
  269.  
  270.         if( tag != LBER_ERROR ) {
  271.             /* peek for referrals */
  272.             if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
  273.                 if( referralsp != NULL ) {
  274.                     tag = ber_scanf( ber, "v", referralsp );
  275.  
  276.                 } else {
  277.                     /* no place to put them so skip 'em */
  278.                     tag = ber_scanf( ber, "x" );
  279.                 }
  280.             }
  281.         }
  282.  
  283.         /* need to clean out misc items */
  284.         if( tag != LBER_ERROR ) {
  285.             if( lm->lm_msgtype == LDAP_RES_BIND ) {
  286.                 /* look for sasl result creditials */
  287.                 if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
  288.                     /* skip 'em */
  289.                     tag = ber_scanf( ber, "x" );
  290.                 }
  291.  
  292.             } else if( lm->lm_msgtype == LDAP_RES_EXTENDED ) {
  293.                 /* look for exop result oid or value */
  294.                 if ( ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_OID ) {
  295.                     /* skip 'em */
  296.                     tag = ber_scanf( ber, "x" );
  297.                 }
  298.  
  299.                 if ( tag != LBER_ERROR &&
  300.                     ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_VALUE )
  301.                 {
  302.                     /* skip 'em */
  303.                     tag = ber_scanf( ber, "x" );
  304.                 }
  305.             }
  306.         }
  307.  
  308.         if( tag != LBER_ERROR ) {
  309.             int rc = ldap_int_get_controls( ber, serverctrls );
  310.  
  311.             if( rc != LDAP_SUCCESS ) {
  312.                 tag = LBER_ERROR;
  313.             }
  314.         }
  315.  
  316.         if( tag != LBER_ERROR ) {
  317.             tag = ber_scanf( ber, /*{*/"}" );
  318.         }
  319.     }
  320.  
  321.     if ( tag == LBER_ERROR ) {
  322.         ld->ld_errno = errcode = LDAP_DECODING_ERROR;
  323.     }
  324.  
  325.     if( ber != NULL ) {
  326.         ber_free( ber, 0 );
  327.     }
  328.  
  329.     /* return */
  330.     if( errcodep != NULL ) {
  331.         *errcodep = ld->ld_errno;
  332.     }
  333.     if ( errcode == LDAP_SUCCESS ) {
  334.         if( matcheddnp != NULL ) {
  335.             *matcheddnp = LDAP_STRDUP( ld->ld_matched );
  336.         }
  337.         if( errmsgp != NULL ) {
  338.             *errmsgp = LDAP_STRDUP( ld->ld_error );
  339.         }
  340.  
  341.         /* Find the next result... */
  342.         for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
  343.             /* skip over entries and references */
  344.             if( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
  345.                 lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE &&
  346.                 lm->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL )
  347.             {
  348.                 /* more results to return */
  349.                 errcode = LDAP_MORE_RESULTS_TO_RETURN;
  350.                 break;
  351.             }
  352.         }
  353.     }
  354.  
  355.     if ( freeit ) {
  356.         ldap_msgfree( r );
  357.     }
  358.  
  359.     return( errcode );
  360. }
  361.