X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdn.c;h=e898942501035a726be802284612330158e4ff05;hb=1adee08e8912c1f47c7b170fe62bebdd9797921f;hp=8bd440dd7e86572a01f18f458004174b2625c557;hpb=69be5fd67532e9375e8e496b073af73bfa3ba21b;p=openldap diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index 8bd440dd7e..e898942501 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-2007 The OpenLDAP Foundation. + * Copyright 1998-2010 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -220,87 +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 ) { - continue; - } + 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 ); - } - /* - * move ahead - */ - for ( j = iAVA; j > i; j-- ) { - rdn[ j ] = rdn[ j - 1 ]; + rdn[ j+1 ] = rdn[ j ]; } - rdn[ i ] = ava_in; + 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; @@ -309,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 ); @@ -413,10 +379,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; } /* @@ -453,7 +423,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; @@ -492,7 +462,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; } @@ -509,7 +479,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; @@ -550,7 +520,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; } @@ -565,7 +535,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 ); @@ -607,7 +577,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; } @@ -622,7 +592,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 ); @@ -666,7 +636,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; } @@ -685,7 +655,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; @@ -732,7 +702,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 ); @@ -800,7 +770,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; } @@ -993,8 +964,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; } @@ -1090,7 +1061,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; } @@ -1226,6 +1197,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 ) {