]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/dn.c
ITS#6932: Clean up strange asserts & nearby code.
[openldap] / servers / slapd / dn.c
index 95520700e381e565fece56be343ed9d2e1398f9f..cb4c6951655718bf4b97b278512bea16fa2ec61b 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2011 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -220,10 +220,7 @@ 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.
@@ -250,21 +247,8 @@ AVA_Sort( LDAPRDN rdn, int nAVAs )
                        ava_j = rdn[ j ];
                        a = strcmp( ava_i->la_attr.bv_val, ava_j->la_attr.bv_val );
 
-                       if ( a == 0 ) {
-                               int             d;
-
-                               d = ava_i->la_value.bv_len - ava_j->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 ( a == 0 ) {
-                                       a = d;
-                               }
-                       }
-                       /* Duplicates are not allowed */
+                       /* RFC4512 does not allow multiple AVAs
+                        * with the same attribute type in RDN (ITS#5968) */
                        if ( a == 0 )
                                return LDAP_INVALID_DN_SYNTAX;
 
@@ -318,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 ) {
@@ -395,6 +376,10 @@ 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;
 
@@ -718,11 +703,10 @@ dnPrettyNormal(
        struct berval *normal,
        void *ctx)
 {
-       Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 );
-
        assert( val != NULL );
        assert( pretty != NULL );
        assert( normal != NULL );
+       Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 );
 
        if ( val->bv_len == 0 ) {
                ber_dupbv_x( pretty, val, ctx );
@@ -980,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;
        }
 
@@ -1077,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;
 }
 
 
@@ -1184,11 +1168,13 @@ dnIsSuffix(
        const struct berval *dn,
        const struct berval *suffix )
 {
-       int     d = dn->bv_len - suffix->bv_len;
+       int     d;
 
        assert( dn != NULL );
        assert( suffix != NULL );
 
+       d = dn->bv_len - suffix->bv_len;
+
        /* empty suffix matches any dn */
        if ( suffix->bv_len == 0 ) {
                return 1;
@@ -1210,7 +1196,71 @@ dnIsSuffix(
        }
 
        /* compare */
-       return( strcmp( dn->bv_val + d, suffix->bv_val ) == 0 );
+       return( strncmp( dn->bv_val + d, suffix->bv_val, suffix->bv_len ) == 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