X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdn.c;h=6383a7b2bfc34223002efe0ba4c438d1567c635a;hb=c7305c4133eca44f2cf10f8b5f11dcfc0c1ff98b;hp=bbcf5a53885e3ea9f17135c3b33cf7ba3c236210;hpb=9da24acb53bee272fce0cb3b59e1c59cc314ecad;p=openldap diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index bbcf5a5388..6383a7b2bf 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-2006 The OpenLDAP Foundation. + * Copyright 1998-2010 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -129,52 +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 ) { - 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; - } - - /* - * 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; } } @@ -263,89 +220,54 @@ rdnValidate( /* * AVA sorting inside a RDN * - * rule: sort attributeTypes in alphabetical order; in case of multiple - * occurrences of the same attributeType, sort values in byte order - * (use memcmp, which implies alphabetical order in case of IA5 value; - * this should guarantee the repeatability of the operation). + * Rule: sort attributeTypes in alphabetical order. * * 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; + /* RFC4512 does not allow multiple AVAs + * with the same attribute type in RDN (ITS#5968) */ + if ( a == 0 ) + return LDAP_INVALID_DN_SYNTAX; - d = ava_in->la_value.bv_len - ava->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 ); - - if ( v == 0 && d != 0 ) { - v = d; - } - - 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; @@ -354,7 +276,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 ); @@ -381,16 +302,13 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) 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, not supported */ + 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; if( !transf ) { @@ -458,10 +376,18 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx ) ava->la_value = bv; ava->la_flags |= LDAP_AVA_FREE_VALUE; } + /* reject empty values */ + if (!ava->la_value.bv_len) { + return LDAP_INVALID_SYNTAX; + } + } + rc = LDAP_SUCCESS; - if( do_sort ) AVA_Sort( rdn, iAVA ); + if ( do_sort ) { + rc = AVA_Sort( rdn, iAVA ); } - return LDAP_SUCCESS; + + return rc; } /* @@ -477,121 +403,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 ) { - 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_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 && (!( mr->smr_usage & SLAP_MR_MUTATION_NORMALIZER ))) { - 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; } } @@ -610,7 +424,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; @@ -649,7 +463,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; } @@ -666,7 +480,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; @@ -707,7 +521,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; } @@ -722,7 +536,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 ); @@ -764,7 +578,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; } @@ -779,7 +593,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 ); @@ -823,7 +637,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; } @@ -842,7 +656,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; @@ -889,7 +703,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 ); @@ -957,7 +771,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; } @@ -1150,8 +965,8 @@ dnParent( /* one-level dn */ if ( p == NULL ) { - pdn->bv_len = 0; pdn->bv_val = dn->bv_val + dn->bv_len; + pdn->bv_len = 0; return; } @@ -1247,7 +1062,7 @@ dn_rdnlen( p = ber_bvchr( dn_in, ',' ); - return p ? p - dn_in->bv_val : dn_in->bv_len; + return p ? (ber_len_t) (p - dn_in->bv_val) : dn_in->bv_len; } @@ -1383,6 +1198,70 @@ dnIsSuffix( return( strcmp( dn->bv_val + d, suffix->bv_val ) == 0 ); } +/* + * In place; assumes: + * - ndn is normalized + * - nbase is normalized + * - dnIsSuffix( ndn, nbase ) == TRUE + * - LDAP_SCOPE_DEFAULT == LDAP_SCOPE_SUBTREE + */ +int +dnIsWithinScope( struct berval *ndn, struct berval *nbase, int scope ) +{ + assert( ndn != NULL ); + assert( nbase != NULL ); + assert( !BER_BVISNULL( ndn ) ); + assert( !BER_BVISNULL( nbase ) ); + + switch ( scope ) { + case LDAP_SCOPE_DEFAULT: + case LDAP_SCOPE_SUBTREE: + break; + + case LDAP_SCOPE_BASE: + if ( ndn->bv_len != nbase->bv_len ) { + return 0; + } + break; + + case LDAP_SCOPE_ONELEVEL: { + struct berval pndn; + dnParent( ndn, &pndn ); + if ( pndn.bv_len != nbase->bv_len ) { + return 0; + } + } break; + + case LDAP_SCOPE_SUBORDINATE: + if ( ndn->bv_len == nbase->bv_len ) { + return 0; + } + break; + + /* unknown scope */ + default: + return -1; + } + + return 1; +} + +/* + * In place; assumes: + * - ndn is normalized + * - nbase is normalized + * - LDAP_SCOPE_DEFAULT == LDAP_SCOPE_SUBTREE + */ +int +dnIsSuffixScope( struct berval *ndn, struct berval *nbase, int scope ) +{ + if ( !dnIsSuffix( ndn, nbase ) ) { + return 0; + } + + return dnIsWithinScope( ndn, nbase, scope ); +} + int dnIsOneLevelRDN( struct berval *rdn ) { @@ -1412,7 +1291,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 */ @@ -1429,6 +1307,7 @@ dnX509normalize( void *x509_name, struct berval *out ) return rc; } +#ifdef HAVE_TLS /* * Get the TLS session's peer's DN into a normalized LDAP DN */