]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/getdn.c
More cleanup in ldap_pvt_tls_destroy()
[openldap] / libraries / libldap / getdn.c
index 8be043f9d667e35896be9fe427ed8016d9bf3c6c..5af3069c77bb02fcd42cc7893753300187d5e108 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -27,9 +27,6 @@
 #define DC_IN_UFN
 /* #define PRETTY_ESCAPE */
 
-/* from libraries/libldap/schema.c */
-extern char * parse_numericoid(const char **sp, int *code, const int flags);
-
 /* parsing/printing routines */
 static int str2strval( const char *str, struct berval *val, 
                const char **next, unsigned flags, unsigned *retFlags );
@@ -114,7 +111,7 @@ ldap_dn2ufn( LDAP_CONST char *dn )
        Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
 
        ( void )ldap_dn_normalize( dn, LDAP_DN_FORMAT_LDAP, 
-                                  &out, LDAP_DN_FORMAT_UFN );
+               &out, LDAP_DN_FORMAT_UFN );
        
        return( out );
 }
@@ -177,7 +174,7 @@ ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
         * FIXME: we prefer efficiency over checking if the _ENTIRE_
         * dn can be parsed
         */
-       if ( ldap_str2rdn( rdn, &tmpRDN, &p, LDAP_DN_FORMAT_LDAP ) 
+       if ( ldap_str2rdn( rdn, &tmpRDN, (char **) &p, LDAP_DN_FORMAT_LDAP ) 
                        != LDAP_SUCCESS ) {
                return( NULL );
        }
@@ -302,7 +299,8 @@ ldap_dn2ad_canonical( LDAP_CONST char *dn )
  *     LDAP_DN_FORMAT_AD_CANONICAL     (?)
  */
 int
-ldap_dn_normalize( const char *dnin, unsigned fin, char **dnout, unsigned fout )
+ldap_dn_normalize( LDAP_CONST char *dnin,
+       unsigned fin, char **dnout, unsigned fout )
 {
        int     rc;
        LDAPDN  *tmpDN = NULL;
@@ -354,25 +352,21 @@ ldap_dn_normalize( const char *dnin, unsigned fin, char **dnout, unsigned fout )
  */
 #define LDAP_DN_ASCII_SPACE(c) \
        ( (c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' )
-#define LDAP_DN_ASCII_LOWER(c)         ( (c) >= 'a' && (c) <= 'z' )
-#define LDAP_DN_ASCII_UPPER(c)         ( (c) >= 'A' && (c) <= 'Z' )
-#define LDAP_DN_ASCII_ALPHA(c) \
-       ( LDAP_DN_ASCII_LOWER(c) || LDAP_DN_ASCII_UPPER(c) )
-#define LDAP_DN_ASCII_DIGIT(c)         ( (c) >= '0' && (c) <= '9' )
-#define LDAP_DN_ASCII_LCASE_HEXALPHA(c)        ( (c) >= 'a' && (c) <= 'f' )
-#define LDAP_DN_ASCII_UCASE_HEXALPHA(c)        ( (c) >= 'A' && (c) <= 'F' )
-#define LDAP_DN_ASCII_HEXDIGIT(c) \
-       ( LDAP_DN_ASCII_DIGIT(c) \
-         || LDAP_DN_ASCII_LCASE_HEXALPHA(c) \
-         || LDAP_DN_ASCII_UCASE_HEXALPHA(c) )
-#define LDAP_DN_ASCII_ALNUM(c) \
-       ( LDAP_DN_ASCII_ALPHA(c) || LDAP_DN_ASCII_DIGIT(c) )
+#define LDAP_DN_ASCII_LOWER(c)         LDAP_LOWER(c)
+#define LDAP_DN_ASCII_UPPER(c)         LDAP_UPPER(c)
+#define LDAP_DN_ASCII_ALPHA(c)         LDAP_ALPHA(c)
+
+#define LDAP_DN_ASCII_DIGIT(c)         LDAP_DIGIT(c)
+#define LDAP_DN_ASCII_LCASE_HEXALPHA(c)        LDAP_HEXLOWER(c)
+#define LDAP_DN_ASCII_UCASE_HEXALPHA(c)        LDAP_HEXUPPER(c)
+#define LDAP_DN_ASCII_HEXDIGIT(c)      LDAP_HEX(c)
+#define LDAP_DN_ASCII_ALNUM(c)         LDAP_ALNUM(c)
 #define LDAP_DN_ASCII_PRINTABLE(c)     ( (c) >= ' ' && (c) <= '~' )
 
 /* attribute type */
-#define LDAP_DN_OID_LEADCHAR(c)                ( LDAP_DN_ASCII_DIGIT(c) )
-#define LDAP_DN_DESC_LEADCHAR(c)       ( LDAP_DN_ASCII_ALPHA(c) )
-#define LDAP_DN_DESC_CHAR(c)           ( LDAP_DN_ASCII_ALNUM(c) || (c) == '-' )
+#define LDAP_DN_OID_LEADCHAR(c)                LDAP_DIGIT(c)
+#define LDAP_DN_DESC_LEADCHAR(c)       LDAP_ALPHA(c)
+#define LDAP_DN_DESC_CHAR(c)           LDAP_LDH(c)
 #define LDAP_DN_LANG_SEP(c)            ( (c) == ';' )
 #define LDAP_DN_ATTRDESC_CHAR(c) \
        ( LDAP_DN_DESC_CHAR(c) || LDAP_DN_LANG_SEP(c) )
@@ -540,9 +534,9 @@ ldap_avafree( LDAPAVA *ava )
 
 #if 0
        /* la_attr is now contiguous with ava, not freed separately */
-       free( ava->la_attr.bv_val );
+       LDAP_FREE( ava->la_attr.bv_val );
 #endif
-       free( ava->la_value.bv_val );
+       LDAP_FREE( ava->la_value.bv_val );
 
        LDAP_FREE( ava );
 }
@@ -593,13 +587,13 @@ ldap_dnfree( LDAPDN *dn )
  * and readable as soon as it works as expected.
  */
 
-#define        TMP_SLOTS       256
+#define        TMP_SLOTS       1024
 
 int
-ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
+ldap_str2dn( LDAP_CONST char *str, LDAPDN **dn, unsigned flags )
 {
        const char      *p;
-       int             rc = LDAP_INVALID_DN_SYNTAX;
+       int             rc = LDAP_DECODING_ERROR;
        int             nrdns = 0;
 
        LDAPDN          *newDN = NULL;
@@ -622,14 +616,15 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
        /* unsupported in str2dn */
        case LDAP_DN_FORMAT_UFN:
        case LDAP_DN_FORMAT_AD_CANONICAL:
-               return( LDAP_INVALID_DN_SYNTAX );
+               return LDAP_PARAM_ERROR;
 
+       case LDAP_DN_FORMAT_LBER:
        default:
-               return( LDAP_OTHER );
+               return LDAP_PARAM_ERROR;
        }
 
        if ( str[ 0 ] == '\0' ) {
-               return( LDAP_SUCCESS );
+               return LDAP_SUCCESS;
        }
 
        p = str;
@@ -655,10 +650,9 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
        }
 
        for ( ; p[ 0 ]; p++ ) {
-               LDAPDN          *dn;
                int             err;
                
-               err = ldap_str2rdn( p, &newRDN, &p, flags );
+               err = ldap_str2rdn( p, &newRDN, (char **) &p, flags );
                if ( err != LDAP_SUCCESS ) {
                        goto parsing_error;
                }
@@ -670,7 +664,7 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
                        switch ( LDAP_DN_FORMAT( flags ) ) {
                        case LDAP_DN_FORMAT_LDAPV3:
                                if ( !LDAP_DN_RDN_SEP( p[ 0 ] ) ) {
-                                       rc = LDAP_OTHER;
+                                       rc = LDAP_DECODING_ERROR;
                                        goto parsing_error;
                                }
                                break;
@@ -678,14 +672,14 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
                        case LDAP_DN_FORMAT_LDAP:
                        case LDAP_DN_FORMAT_LDAPV2:
                                if ( !LDAP_DN_RDN_SEP_V2( p[ 0 ] ) ) {
-                                       rc = LDAP_OTHER;
+                                       rc = LDAP_DECODING_ERROR;
                                        goto parsing_error;
                                }
                                break;
        
                        case LDAP_DN_FORMAT_DCE:
                                if ( !LDAP_DN_RDN_SEP_DCE( p[ 0 ] ) ) {
-                                       rc = LDAP_OTHER;
+                                       rc = LDAP_DECODING_ERROR;
                                        goto parsing_error;
                                }
                                break;
@@ -696,7 +690,20 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
                tmpDN[nrdns++] = newRDN;
                newRDN = NULL;
 
+#if 0
+               /*
+                * prone to attacks?
+                */
                assert (nrdns < TMP_SLOTS);
+#else
+               /*
+                * make the static AVA array dynamically rescalable
+                */
+               if (nrdns >= TMP_SLOTS) {
+                       rc = LDAP_DECODING_ERROR;
+                       goto parsing_error;
+               }
+#endif
                                
                if ( p[ 0 ] == '\0' ) {
                        /* 
@@ -736,7 +743,6 @@ parsing_error:;
                ldap_rdnfree( tmpDN[nrdns] );
 
 return_result:;
-
        Debug( LDAP_DEBUG_TRACE, "<= ldap_str2dn(%s,%u)=%d\n", str, flags, rc );
        *dn = newDN;
        
@@ -752,12 +758,14 @@ return_result:;
  * corresponds to the rdn separator or to '\0' in case the string is over.
  */
 int
-ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
+ldap_str2rdn( LDAP_CONST char *str, LDAPRDN **rdn,
+       char **n_in, unsigned flags )
 {
+       const char  **n = (const char **) n_in;
        const char      *p;
        int             navas = 0;
        int             state = B4AVA;
-       int             rc = LDAP_INVALID_DN_SYNTAX;
+       int             rc = LDAP_DECODING_ERROR;
        int             attrTypeEncoding = LDAP_AVA_STRING, 
                        attrValueEncoding = LDAP_AVA_STRING;
 
@@ -788,14 +796,15 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
        /* unsupported in str2dn */
        case LDAP_DN_FORMAT_UFN:
        case LDAP_DN_FORMAT_AD_CANONICAL:
-               return( LDAP_INVALID_DN_SYNTAX );
+               return LDAP_PARAM_ERROR;
 
+       case LDAP_DN_FORMAT_LBER:
        default:
-               return( LDAP_OTHER );
+               return LDAP_PARAM_ERROR;
        }
 
        if ( str[ 0 ] == '\0' ) {
-               return( LDAP_SUCCESS );
+               return LDAP_SUCCESS;
        }
 
        p = str;
@@ -887,7 +896,7 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
                case B4OIDATTRTYPE: {
                        int             err = LDAP_SUCCESS;
                        
-                       attrType.bv_val = parse_numericoid( &p, &err,
+                       attrType.bv_val = ldap_int_parse_numericoid( &p, &err,
                                LDAP_SCHEMA_SKIP);
 
                        if ( err != LDAP_SUCCESS ) {
@@ -1044,7 +1053,12 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
                         * here STRING means RFC 2253 string
                         * FIXME: what about DCE strings? 
                         */
-                       state = B4STRINGVALUE;
+                       if ( !p[ 0 ] ) {
+                               /* empty value */
+                               state = GOTAVA;
+                       } else {
+                               state = B4STRINGVALUE;
+                       }
                        break;
 
                case B4BINARYVALUE:
@@ -1108,12 +1122,16 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
                                 */
                                ava = ldapava_new( &attrType, &attrValue, 
                                                attrValueEncoding );
+                               
                                if ( ava == NULL ) {
                                        rc = LDAP_NO_MEMORY;
                                        goto parsing_error;
                                }
                                tmpRDN[navas++] = ava;
 
+                               attrValue.bv_val = NULL;
+                               attrValue.bv_len = 0;
+
                                assert(navas < TMP_SLOTS);
                        }
                        
@@ -1178,12 +1196,10 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags )
                        goto parsing_error;
                }
        }
+       *n = p;
        
 parsing_error:;
        /* They are set to NULL after they're used in an AVA */
-       if ( attrType.bv_val ) {
-               free( attrType.bv_val );
-       }
 
        if ( attrValue.bv_val ) {
                free( attrValue.bv_val );
@@ -1195,7 +1211,7 @@ parsing_error:;
 return_result:;
 
        Debug( LDAP_DEBUG_TRACE, "<= ldap_str2rdn(%*s)=%d\n", 
-                       *n - p, str, rc );
+                       p - str, str, rc );
        if ( rdn ) {
                *rdn = newRDN;
        }
@@ -1264,6 +1280,9 @@ str2strval( const char *str, struct berval *val, const char **next, unsigned fla
                         */
                        unescapes++;
 
+               } else if (!LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
+                       *retFlags = LDAP_AVA_NONPRINTABLE;
+
                } else if ( ( LDAP_DN_LDAP( flags ) && LDAP_DN_VALUE_END_V2( p[ 0 ] ) ) 
                                || ( LDAP_DN_LDAPV3( flags ) && LDAP_DN_VALUE_END( p[ 0 ] ) ) ) {
                        break;
@@ -2242,7 +2261,7 @@ dn2domain( LDAPDN *dn, struct berval *bv, int pos, int *iRDN )
                        l += ava->la_value.bv_len;
 
                } else {
-                       AC_MEMCPY( str + ava->la_value.bv_len + 1, bv->bv_val, l);
+                       AC_MEMCPY( str + ava->la_value.bv_len + 1, bv->bv_val + pos, l);
                        AC_MEMCPY( str, ava->la_value.bv_val, 
                                        ava->la_value.bv_len );
                        str[ ava->la_value.bv_len ] = '.';
@@ -2607,6 +2626,10 @@ ldap_rdn2str( LDAPRDN *rdn, char **str, unsigned flags )
 
        assert( str );
 
+       if((flags & LDAP_DN_FORMAT_MASK) == LDAP_DN_FORMAT_LBER) {
+               return LDAP_PARAM_ERROR;
+       }
+
        rc = ldap_rdn2bv( rdn, &bv, flags );
        *str = bv.bv_val;
        return rc;
@@ -2635,36 +2658,36 @@ ldap_rdn2bv( LDAPRDN *rdn, struct berval *bv, unsigned flags )
        switch ( LDAP_DN_FORMAT( flags ) ) {
        case LDAP_DN_FORMAT_LDAPV3:
                if ( rdn2strlen( rdn, flags, &l, strval2strlen ) ) {
-                       return( LDAP_OTHER );
+                       return LDAP_DECODING_ERROR;
                }
                break;
 
        case LDAP_DN_FORMAT_LDAPV2:
                if ( rdn2strlen( rdn, flags, &l, strval2IA5strlen ) ) {
-                       return( LDAP_OTHER );
+                       return LDAP_DECODING_ERROR;
                }
                break;
 
        case LDAP_DN_FORMAT_UFN:
                if ( rdn2UFNstrlen( rdn, flags, &l ) ) {
-                       return( LDAP_OTHER );
+                       return LDAP_DECODING_ERROR;
                }
                break;
 
        case LDAP_DN_FORMAT_DCE:
                if ( rdn2DCEstrlen( rdn, flags, &l ) ) {
-                       return( LDAP_OTHER );
+                       return LDAP_DECODING_ERROR;
                }
                break;
 
        case LDAP_DN_FORMAT_AD_CANONICAL:
                if ( rdn2ADstrlen( rdn, flags, &l ) ) {
-                       return( LDAP_OTHER );
+                       return LDAP_DECODING_ERROR;
                }
                break;
 
        default:
-               return( LDAP_INVALID_DN_SYNTAX );
+               return( LDAP_PARAM_ERROR );
        }
 
        bv->bv_val = LDAP_MALLOC( l + 1 );
@@ -2697,18 +2720,18 @@ ldap_rdn2bv( LDAPRDN *rdn, struct berval *bv, unsigned flags )
 
        default:
                /* need at least one of the previous */
-               return( LDAP_OTHER );
+               return LDAP_PARAM_ERROR;
        }
 
        if ( rc ) {
                ldap_memfree( bv->bv_val );
-               return( LDAP_OTHER );
+               return rc;
        }
 
        bv->bv_len = l - back;
        bv->bv_val[ bv->bv_len ] = '\0';
 
-       return( LDAP_SUCCESS );
+       return LDAP_SUCCESS;
 }
 
 /*
@@ -2730,6 +2753,10 @@ int ldap_dn2str( LDAPDN *dn, char **str, unsigned flags )
 
        assert( str );
 
+       if((flags & LDAP_DN_FORMAT_MASK) == LDAP_DN_FORMAT_LBER) {
+               return LDAP_PARAM_ERROR;
+       }
+       
        rc = ldap_dn2bv( dn, &bv, flags );
        *str = bv.bv_val;
        return rc;
@@ -2738,7 +2765,7 @@ int ldap_dn2str( LDAPDN *dn, char **str, unsigned flags )
 int ldap_dn2bv( LDAPDN *dn, struct berval *bv, unsigned flags )
 {
        int             iRDN;
-       int             rc = LDAP_OTHER;
+       int             rc = LDAP_ENCODING_ERROR;
        ber_len_t       len, l;
 
        /* stringifying helpers for LDAPv3/LDAPv2 */
@@ -3029,7 +3056,7 @@ got_funcs:
                        if ( flags & LDAP_DN_PEDANTIC ) {
                                LDAP_FREE( bv->bv_val );
                                bv->bv_val = NULL;
-                               rc = LDAP_INVALID_DN_SYNTAX;
+                               rc = LDAP_ENCODING_ERROR;
                                break;
                        }
 
@@ -3058,11 +3085,11 @@ got_funcs:
        }
 
        default:
-               return( LDAP_INVALID_DN_SYNTAX );
-
+               return LDAP_PARAM_ERROR;
        }
 
-       Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n", bv->bv_val, flags, rc );
+       Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n",
+               bv->bv_val, flags, rc );
 return_results:;
        return( rc );
 }