]> 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 dda4e185023f86f3a4f92125f5d595eba0397611..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",
@@ -207,8 +212,6 @@ str2entry2( char *s, int checkvals )
                goto fail;
        }
 
-#define bvcasematch(bv1, bv2)  ( ((bv1)->bv_len == (bv2)->bv_len) && (strncasecmp((bv1)->bv_val, (bv2)->bv_val, (bv1)->bv_len) == 0) )
-
        /* Make sure all attributes with multiple values are contiguous */
        if ( checkvals ) {
                int j, k;
@@ -260,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 &&
@@ -297,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 =
@@ -350,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;
                        }
                }
@@ -723,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);
@@ -784,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;
@@ -836,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) {
@@ -868,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 )
@@ -941,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;