]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/getdn.c
More cleanup in ldap_pvt_tls_destroy()
[openldap] / libraries / libldap / getdn.c
index 5c3e042ed92203fade388fbb468ef2ea9abe60de..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
@@ -111,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 );
 }
@@ -174,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 );
        }
@@ -299,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;
@@ -533,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 );
 }
@@ -586,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;
@@ -615,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;
@@ -650,7 +652,7 @@ ldap_str2dn( const char *str, LDAPDN **dn, unsigned flags )
        for ( ; p[ 0 ]; p++ ) {
                int             err;
                
-               err = ldap_str2rdn( p, &newRDN, &p, flags );
+               err = ldap_str2rdn( p, &newRDN, (char **) &p, flags );
                if ( err != LDAP_SUCCESS ) {
                        goto parsing_error;
                }
@@ -662,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;
@@ -670,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;
@@ -688,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' ) {
                        /* 
@@ -728,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;
        
@@ -744,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;
 
@@ -780,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;
@@ -1036,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:
@@ -1100,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);
                        }
                        
@@ -1254,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;
@@ -2232,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 ] = '.';
@@ -2597,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;
@@ -2625,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 );
@@ -2687,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;
 }
 
 /*
@@ -2720,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;
@@ -2728,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 */
@@ -3019,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;
                        }
 
@@ -3048,8 +3085,7 @@ got_funcs:
        }
 
        default:
-               return( LDAP_INVALID_DN_SYNTAX );
-
+               return LDAP_PARAM_ERROR;
        }
 
        Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n",