]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/entry.c
Partial revert from 1.246, not sure what's the point
[openldap] / servers / slapd / entry.c
index 220d7a22f57bb0777d586fbeb457e23404bd246c..b83c550defe664064e6fee2875d5d75b74ed650c 100644 (file)
@@ -100,6 +100,8 @@ str2entry( char *s )
        return str2entry2( s, 1 );
 }
 
+#define bvcasematch(bv1, bv2)  (ber_bvstrcasecmp(bv1, bv2) == 0)
+
 Entry *
 str2entry2( char *s, int checkvals )
 {
@@ -166,6 +168,11 @@ str2entry2( char *s, int checkvals )
                        break;
                }
                i++;
+               if (i >= lines) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= str2entry ran past end of entry\n", 0, 0, 0 );
+                       goto fail;
+               }
 
                rc = ldif_parse_line2( s, type+i, vals+i, &freev );
                freeval[i] = freev;
@@ -175,9 +182,7 @@ str2entry2( char *s, int checkvals )
                        continue;
                }
 
-               if ( type[i].bv_len == dn_bv.bv_len &&
-                       strcasecmp( type[i].bv_val, dn_bv.bv_val ) == 0 ) {
-
+               if ( bvcasematch( &type[i], &dn_bv ) ) {
                        if ( e->e_dn != NULL ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry: "
                                        "entry %ld has multiple DNs \"%s\" and \"%s\"\n",
@@ -215,7 +220,7 @@ str2entry2( char *s, int checkvals )
 
                for (i=0; i<lines; i++) {
                        for ( j=i+1; j<lines; j++ ) {
-                               if ( bvmatch( type+i, type+j )) {
+                               if ( bvcasematch( type+i, type+j )) {
                                        /* out of order, move intervening attributes down */
                                        if ( j != i+1 ) {
                                                bv = vals[j];
@@ -238,7 +243,7 @@ str2entry2( char *s, int checkvals )
 
        for ( i=0; i<=lines; i++ ) {
                ad_prev = ad;
-               if ( !ad || ( i<lines && !bvmatch( type+i, &ad->ad_cname ))) {
+               if ( !ad || ( i<lines && !bvcasematch( type+i, &ad->ad_cname ))) {
                        ad = NULL;
                        rc = slap_bv2ad( type+i, &ad, &text );
 
@@ -258,13 +263,36 @@ str2entry2( char *s, int checkvals )
                                        goto fail;
                                }
                        }
+
+                       /* require ';binary' when appropriate (ITS#5071) */
+                       if ( slap_syntax_is_binary( ad->ad_type->sat_syntax ) && !slap_ad_is_binary( ad ) ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "str2entry: attributeType %s #%d: "
+                                       "needs ';binary' transfer as per syntax %s\n", 
+                                       ad->ad_cname.bv_val, 0,
+                                       ad->ad_type->sat_syntax->ssyn_oid );
+                               goto fail;
+                       }
                }
 
                if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
                        int j, k;
+                       /* FIXME: we only need this when migrating from an unsorted DB */
+                       if ( atail != &ahead && atail->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
+                               rc = slap_sort_vals( (Modifications *)atail, &text, &j, NULL );
+                               if ( rc == LDAP_SUCCESS ) {
+                                       atail->a_flags |= SLAP_ATTR_SORTED_VALS;
+                               } else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "str2entry: attributeType %s value #%d provided more than once\n",
+                                               atail->a_desc->ad_cname.bv_val, j, 0 );
+                                       goto fail;
+                               }
+                       }
                        atail->a_next = attr_alloc( NULL );
                        atail = atail->a_next;
                        atail->a_flags = 0;
+                       atail->a_numvals = attr_cnt;
                        atail->a_desc = ad_prev;
                        atail->a_vals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
                        if( ad_prev->ad_type->sat_equality &&
@@ -295,6 +323,14 @@ str2entry2( char *s, int checkvals )
                        if ( i == lines ) break;
                }
 
+               if ( BER_BVISNULL( &vals[i] ) ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "str2entry: attributeType %s #%d: "
+                               "no value\n", 
+                               ad->ad_cname.bv_val, attr_cnt, 0 );
+                       goto fail;
+               }
+
                if( slapMode & SLAP_TOOL_MODE ) {
                        struct berval pval;
                        slap_syntax_validate_func *validate =
@@ -348,7 +384,7 @@ str2entry2( char *s, int checkvals )
 
                        if ( rc ) {
                                Debug( LDAP_DEBUG_ANY,
-                                       "<= str2entry NULL (smr_normalize %d)\n", rc, 0, 0 );
+                                       "<= str2entry NULL (smr_normalize %s %d)\n", ad->ad_cname.bv_val, rc, 0 );
                                goto fail;
                        }
                }
@@ -500,10 +536,12 @@ entry_prealloc( int num )
 
        if (!num) return 0;
 
+#if STRIDE_FACTOR > 1
        /* Round up to our stride factor */
        num += STRIDE_FACTOR-1;
        num /= STRIDE_FACTOR;
        num *= STRIDE_FACTOR;
+#endif
 
        s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Entry));
        s->next = entry_chunks;
@@ -719,6 +757,7 @@ int entry_encode(Entry *e, struct berval *bv)
                *ptr++ = '\0';
                if (a->a_vals) {
                        for (i=0; a->a_vals[i].bv_val; i++);
+                       assert( i == a->a_numvals );
                        entry_putlen(&ptr, i);
                        for (i=0; a->a_vals[i].bv_val; i++) {
                                entry_putlen(&ptr, a->a_vals[i].bv_len);
@@ -780,7 +819,7 @@ int entry_decode(EntryHeader *eh, Entry **e, void *ctx)
 int entry_decode(EntryHeader *eh, Entry **e)
 #endif
 {
-       int i, j, count, nattrs, nvals;
+       int i, j, nattrs, nvals;
        int rc;
        Attribute *a;
        Entry *x;
@@ -832,7 +871,8 @@ int entry_decode(EntryHeader *eh, Entry **e)
                ptr += i + 1;
                a->a_desc = ad;
                a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
-               count = j = entry_getlen(&ptr);
+               j = entry_getlen(&ptr);
+               a->a_numvals = j;
                a->a_vals = bptr;
 
                while (j) {
@@ -864,6 +904,19 @@ int entry_decode(EntryHeader *eh, Entry **e)
                } else {
                        a->a_nvals = a->a_vals;
                }
+               /* FIXME: This is redundant once a sorted entry is saved into the DB */
+               if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
+                       rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL );
+                       if ( rc == LDAP_SUCCESS ) {
+                               a->a_flags |= SLAP_ATTR_SORTED_VALS;
+                       } else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
+                               /* should never happen */
+                               Debug( LDAP_DEBUG_ANY,
+                                       "entry_decode: attributeType %s value #%d provided more than once\n",
+                                       a->a_desc->ad_cname.bv_val, j, 0 );
+                               return rc;
+                       }
+               }
                a = a->a_next;
                nattrs--;
                if ( !nattrs )
@@ -937,6 +990,7 @@ Entry *entry_dup_bv( Entry *e )
                dst->a_desc = src->a_desc;
                dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
                dst->a_vals = bvl;
+               dst->a_numvals = src->a_numvals;
                for ( i=0; src->a_vals[i].bv_val; i++ ) {
                        bvl->bv_len = src->a_vals[i].bv_len;
                        bvl->bv_val = ptr;