X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdn.c;h=95520700e381e565fece56be343ed9d2e1398f9f;hb=3bf9998d7885ef6bbc4690d4229e5cb5068a35de;hp=a47d1c418f25e8432cd8a82d8f89913f1d5b29c1;hpb=b15a72caecd6750ce76b8b6296dd481c6235de33;p=openldap diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index a47d1c418f..95520700e3 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,6 +53,8 @@ #define AVA_PRIVATE( ava ) ( ( AttributeDescription * )(ava)->la_private ) +int slap_DN_strict = SLAP_AD_NOINSERT; + static int LDAPRDN_validate( LDAPRDN rdn ) { @@ -73,12 +75,24 @@ LDAPRDN_validate( LDAPRDN rdn ) rc = slap_bv2ad( &ava->la_attr, &ad, &text ); if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; + rc = slap_bv2undef_ad( &ava->la_attr, + &ad, &text, + SLAP_AD_PROXIED|slap_DN_strict ); + if ( rc != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } } ava->la_private = ( void * )ad; } + /* + * Do not allow X-ORDERED 'VALUES' naming attributes + */ + if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) { + return LDAP_INVALID_SYNTAX; + } + /* * Replace attr oid/name with the canonical name */ @@ -115,47 +129,9 @@ LDAPDN_validate( LDAPDN dn ) assert( dn != NULL ); for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) { - LDAPRDN rdn = dn[ iRDN ]; - int iAVA; - - assert( rdn != NULL ); - - for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { - LDAPAVA *ava = rdn[ iAVA ]; - AttributeDescription *ad; - slap_syntax_validate_func *validate = NULL; - - assert( ava != NULL ); - - if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) { - const char *text = NULL; - - rc = slap_bv2ad( &ava->la_attr, &ad, &text ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - ava->la_private = ( void * )ad; - } - - /* - * Replace attr oid/name with the canonical name - */ - ava->la_attr = ad->ad_cname; - - validate = ad->ad_type->sat_syntax->ssyn_validate; - - if ( validate ) { - /* - * validate value by validate function - */ - rc = ( *validate )( ad->ad_type->sat_syntax, - &ava->la_value ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } + rc = LDAPRDN_validate( dn[ iRDN ] ); + if ( rc != LDAP_SUCCESS ) { + return rc; } } @@ -252,81 +228,62 @@ rdnValidate( * Note: the sorting can be slightly improved by sorting first * by attribute type length, then by alphabetical order. * - * uses a linear search; should be fine since the number of AVAs in + * uses an insertion sort; should be fine since the number of AVAs in * a RDN should be limited. */ -static void -AVA_Sort( LDAPRDN rdn, int iAVA ) +static int +AVA_Sort( LDAPRDN rdn, int nAVAs ) { + LDAPAVA *ava_i; int i; - LDAPAVA *ava_in = rdn[ iAVA ]; assert( rdn != NULL ); - assert( ava_in != NULL ); - - for ( i = 0; i < iAVA; i++ ) { - LDAPAVA *ava = rdn[ i ]; - int a, j; - assert( ava != NULL ); + for ( i = 1; i < nAVAs; i++ ) { + LDAPAVA *ava_j; + int j; - a = strcmp( ava_in->la_attr.bv_val, ava->la_attr.bv_val ); + ava_i = rdn[ i ]; + for ( j = i-1; j >=0; j-- ) { + int a; - if ( a > 0 ) { - break; - } + ava_j = rdn[ j ]; + a = strcmp( ava_i->la_attr.bv_val, ava_j->la_attr.bv_val ); - while ( a == 0 ) { - int v, d; + if ( a == 0 ) { + int d; - d = ava_in->la_value.bv_len - ava->la_value.bv_len; + d = ava_i->la_value.bv_len - ava_j->la_value.bv_len; - v = memcmp( ava_in->la_value.bv_val, - ava->la_value.bv_val, - d <= 0 ? ava_in->la_value.bv_len - : ava->la_value.bv_len ); + a = memcmp( ava_i->la_value.bv_val, + ava_j->la_value.bv_val, + d <= 0 ? ava_i->la_value.bv_len + : ava_j->la_value.bv_len ); - if ( v == 0 && d != 0 ) { - v = d; + if ( a == 0 ) { + a = d; + } } + /* Duplicates are not allowed */ + if ( a == 0 ) + return LDAP_INVALID_DN_SYNTAX; - if ( v <= 0 ) { - /* - * got it! - */ + if ( a > 0 ) break; - } - if ( ++i == iAVA ) { - /* - * already sorted - */ - return; - } - - ava = rdn[ i ]; - a = strcmp( ava_in->la_attr.bv_val, - ava->la_attr.bv_val ); + rdn[ j+1 ] = rdn[ j ]; } - - /* - * move ahead - */ - for ( j = iAVA; j > i; j-- ) { - rdn[ j ] = rdn[ j - 1 ]; - } - rdn[ i ] = ava_in; - - return; + rdn[ j+1 ] = ava_i; } + return LDAP_SUCCESS; } static int LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) { - int rc; - int iAVA; + int rc, iAVA, do_sort = 0; + for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { LDAPAVA *ava = rdn[ iAVA ]; AttributeDescription *ad; @@ -335,7 +292,6 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) slap_syntax_transform_func *transf = NULL; MatchingRule *mr = NULL; struct berval bv = BER_BVNULL; - int do_sort = 0; assert( ava != NULL ); @@ -344,7 +300,12 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) rc = slap_bv2ad( &ava->la_attr, &ad, &text ); if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; + rc = slap_bv2undef_ad( &ava->la_attr, + &ad, &text, + SLAP_AD_PROXIED|slap_DN_strict ); + if ( rc != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } } ava->la_private = ( void * )ad; @@ -362,6 +323,10 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) return LDAP_INVALID_SYNTAX; } + /* Do not allow X-ORDERED 'VALUES' naming attributes */ + } else if( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) { + return LDAP_INVALID_SYNTAX; + /* AVA is binary encoded, don't muck with it */ } else if( flags & SLAP_LDAPDN_PRETTY ) { transf = ad->ad_type->sat_syntax->ssyn_pretty; @@ -371,7 +336,9 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) } else { /* normalization */ validf = ad->ad_type->sat_syntax->ssyn_validate; mr = ad->ad_type->sat_equality; - if( mr ) normf = mr->smr_normalize; + if( mr && (!( mr->smr_usage & SLAP_MR_MUTATION_NORMALIZER ))) { + normf = mr->smr_normalize; + } } if ( validf ) { @@ -428,10 +395,14 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) ava->la_value = bv; ava->la_flags |= LDAP_AVA_FREE_VALUE; } + } + rc = LDAP_SUCCESS; - if( do_sort ) AVA_Sort( rdn, iAVA ); + if ( do_sort ) { + rc = AVA_Sort( rdn, iAVA ); } - return LDAP_SUCCESS; + + return rc; } /* @@ -447,114 +418,9 @@ LDAPDN_rewrite( LDAPDN dn, unsigned flags, void *ctx ) assert( dn != NULL ); for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) { - LDAPRDN rdn = dn[ iRDN ]; - int iAVA; - - assert( rdn != NULL ); - - for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { - LDAPAVA *ava = rdn[ iAVA ]; - AttributeDescription *ad; - slap_syntax_validate_func *validf = NULL; - slap_mr_normalize_func *normf = NULL; - slap_syntax_transform_func *transf = NULL; - MatchingRule *mr = NULL; - struct berval bv = BER_BVNULL; - int do_sort = 0; - - assert( ava != NULL ); - - if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) { - const char *text = NULL; - - rc = slap_bv2ad( &ava->la_attr, &ad, &text ); - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - - ava->la_private = ( void * )ad; - do_sort = 1; - } - - /* - * Replace attr oid/name with the canonical name - */ - ava->la_attr = ad->ad_cname; - - if( ava->la_flags & LDAP_AVA_BINARY ) { - if( ava->la_value.bv_len == 0 ) { - /* BER encoding is empty */ - return LDAP_INVALID_SYNTAX; - } - - /* AVA is binary encoded, don't muck with it */ - } else if( flags & SLAP_LDAPDN_PRETTY ) { - transf = ad->ad_type->sat_syntax->ssyn_pretty; - if( !transf ) { - validf = ad->ad_type->sat_syntax->ssyn_validate; - } - } else { /* normalization */ - validf = ad->ad_type->sat_syntax->ssyn_validate; - mr = ad->ad_type->sat_equality; - if( mr ) normf = mr->smr_normalize; - } - - if ( validf ) { - /* validate value before normalization */ - rc = ( *validf )( ad->ad_type->sat_syntax, - ava->la_value.bv_len - ? &ava->la_value - : (struct berval *) &slap_empty_bv ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } - - if ( transf ) { - /* - * transform value by pretty function - * if value is empty, use empty_bv - */ - rc = ( *transf )( ad->ad_type->sat_syntax, - ava->la_value.bv_len - ? &ava->la_value - : (struct berval *) &slap_empty_bv, - &bv, ctx ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } - - if ( normf ) { - /* - * normalize value - * if value is empty, use empty_bv - */ - rc = ( *normf )( - SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, - ad->ad_type->sat_syntax, - mr, - ava->la_value.bv_len - ? &ava->la_value - : (struct berval *) &slap_empty_bv, - &bv, ctx ); - - if ( rc != LDAP_SUCCESS ) { - return LDAP_INVALID_SYNTAX; - } - } - - - if( bv.bv_val ) { - if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) - ber_memfree_x( ava->la_value.bv_val, ctx ); - ava->la_value = bv; - ava->la_flags |= LDAP_AVA_FREE_VALUE; - } - - if( do_sort ) AVA_Sort( rdn, iAVA ); + rc = LDAPRDN_rewrite( dn[ iRDN ], flags, ctx ); + if ( rc != LDAP_SUCCESS ) { + return rc; } } @@ -573,7 +439,7 @@ dnNormalize( assert( val != NULL ); assert( out != NULL ); - Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len != 0 ) { LDAPDN dn = NULL; @@ -612,7 +478,7 @@ dnNormalize( ber_dupbv_x( out, val, ctx ); } - Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; } @@ -629,7 +495,7 @@ rdnNormalize( assert( val != NULL ); assert( out != NULL ); - Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len != 0 ) { LDAPRDN rdn = NULL; int rc; @@ -670,7 +536,7 @@ rdnNormalize( ber_dupbv_x( out, val, ctx ); } - Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; } @@ -685,7 +551,7 @@ dnPretty( assert( val != NULL ); assert( out != NULL ); - Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len == 0 ) { ber_dupbv_x( out, val, ctx ); @@ -727,7 +593,7 @@ dnPretty( } } - Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; } @@ -742,7 +608,7 @@ rdnPretty( assert( val != NULL ); assert( out != NULL ); - Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, ">>> rdnPretty: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len == 0 ) { ber_dupbv_x( out, val, ctx ); @@ -786,7 +652,7 @@ rdnPretty( } } - Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; } @@ -805,7 +671,7 @@ dnPrettyNormalDN( Debug( LDAP_DEBUG_TRACE, ">>> dn%sDN: <%s>\n", flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", - val->bv_val, 0 ); + val->bv_val ? val->bv_val : "", 0 ); if ( val->bv_len == 0 ) { return LDAP_SUCCESS; @@ -852,7 +718,7 @@ dnPrettyNormal( struct berval *normal, void *ctx) { - Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); assert( val != NULL ); assert( pretty != NULL ); @@ -920,7 +786,8 @@ dnPrettyNormal( } Debug( LDAP_DEBUG_TRACE, "<<< dnPrettyNormal: <%s>, <%s>\n", - pretty->bv_val, normal->bv_val, 0 ); + pretty->bv_val ? pretty->bv_val : "", + normal->bv_val ? normal->bv_val : "", 0 ); return LDAP_SUCCESS; } @@ -1109,7 +976,7 @@ dnParent( { char *p; - p = strchr( dn->bv_val, ',' ); + p = ber_bvchr( dn, ',' ); /* one-level dn */ if ( p == NULL ) { @@ -1141,7 +1008,7 @@ dnRdn( char *p; *rdn = *dn; - p = strchr( dn->bv_val, ',' ); + p = ber_bvchr( dn, ',' ); /* one-level dn */ if ( p == NULL ) { @@ -1187,7 +1054,7 @@ dnExtractRdn( /* * We can assume the input is a prettied or normalized DN */ -int +ber_len_t dn_rdnlen( Backend *be, struct berval *dn_in ) @@ -1208,7 +1075,7 @@ dn_rdnlen( return 0; } - p = strchr( dn_in->bv_val, ',' ); + p = ber_bvchr( dn_in, ',' ); return p ? p - dn_in->bv_val : dn_in->bv_len; } @@ -1232,7 +1099,7 @@ rdn_validate( struct berval *rdn ) { return LDAP_INVALID_SYNTAX; } - return strchr( rdn->bv_val, ',' ) == NULL + return ber_bvchr( rdn, ',' ) == NULL ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX; #else @@ -1280,7 +1147,7 @@ rdn_validate( struct berval *rdn ) /* build_new_dn: * - * Used by ldbm/bdb2 back_modrdn to create the new dn of entries being + * Used by back-bdb back_modrdn to create the new dn of entries being * renamed. * * new_dn = parent (p_dn) + separator + rdn (newrdn) + null. @@ -1295,7 +1162,7 @@ build_new_dn( struct berval * new_dn, char *ptr; if ( parent_dn == NULL || parent_dn->bv_len == 0 ) { - ber_dupbv( new_dn, newrdn ); + ber_dupbv_x( new_dn, newrdn, memctx ); return; } @@ -1375,7 +1242,6 @@ int register_certificate_map_function(SLAP_CERT_MAP_FN *fn) return -1; } -#ifdef HAVE_TLS /* * Convert an X.509 DN into a normalized LDAP DN */ @@ -1386,11 +1252,13 @@ dnX509normalize( void *x509_name, struct berval *out ) int rc = ldap_X509dn2bv( x509_name, out, LDAPDN_rewrite, 0 ); Debug( LDAP_DEBUG_TRACE, - "dnX509Normalize: <%s>\n", out->bv_val, 0, 0 ); + "dnX509Normalize: <%s> (%d)\n", + BER_BVISNULL( out ) ? "(null)" : out->bv_val, rc, 0 ); return rc; } +#ifdef HAVE_TLS /* * Get the TLS session's peer's DN into a normalized LDAP DN */