/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/*
* 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 );
-
- a = strcmp( ava_in->la_attr.bv_val, ava->la_attr.bv_val );
-
- if ( a > 0 ) {
- break;
- }
- while ( a == 0 ) {
- int v, d;
+ for ( i = 1; i < nAVAs; i++ ) {
+ LDAPAVA *ava_j;
+ int j;
- d = ava_in->la_value.bv_len - ava->la_value.bv_len;
+ ava_i = rdn[ i ];
+ for ( j = i-1; j >=0; j-- ) {
+ int a;
- 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 );
+ ava_j = rdn[ j ];
+ a = strcmp( ava_i->la_attr.bv_val, ava_j->la_attr.bv_val );
- if ( v == 0 && d != 0 ) {
- 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;
- 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;
slap_syntax_transform_func *transf = NULL;
MatchingRule *mr = NULL;
struct berval bv = BER_BVNULL;
- int do_sort = 0;
assert( ava != NULL );
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;
}
/*
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;
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;
}
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;
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;
}
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 );
}
}
- 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;
}
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 );
}
}
- 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;
}
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;
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 );
}
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;
}
/* one-level dn */
if ( p == NULL ) {
- pdn->bv_len = 0;
pdn->bv_val = dn->bv_val + dn->bv_len;
+ pdn->bv_len = 0;
return;
}
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;
}
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 )
{