]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/entry.c
Relax entry_header, zero-length entries are valid.
[openldap] / servers / slapd / entry.c
index b88440461526712dffaec2c9c2a0c0bf1bbb42d9..9b768a9ce2952ff84c87a7f3656e5fe0d550579c 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
@@ -241,155 +241,157 @@ str2entry2( char *s, int checkvals )
                }
        }
 
-       for ( i=0; i<=lines; i++ ) {
-               ad_prev = ad;
-               if ( !ad || ( i<lines && !bvcasematch( type+i, &ad->ad_cname ))) {
-                       ad = NULL;
-                       rc = slap_bv2ad( type+i, &ad, &text );
-
-                       if( rc != LDAP_SUCCESS ) {
-                               Debug( slapMode & SLAP_TOOL_MODE
-                                       ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
-                                       "<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text, 0 );
-                               if( slapMode & SLAP_TOOL_MODE ) {
-                                       goto fail;
-                               }
-
-                               rc = slap_bv2undef_ad( type+i, &ad, &text, 0 );
+       if ( lines > 0 ) {
+               for ( i=0; i<=lines; i++ ) {
+                       ad_prev = ad;
+                       if ( !ad || ( i<lines && !bvcasematch( type+i, &ad->ad_cname ))) {
+                               ad = NULL;
+                               rc = slap_bv2ad( type+i, &ad, &text );
+       
                                if( rc != LDAP_SUCCESS ) {
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "<= str2entry: slap_str2undef_ad(%s): %s\n",
-                                                       type[i].bv_val, text, 0 );
-                                       goto fail;
+                                       Debug( slapMode & SLAP_TOOL_MODE
+                                               ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
+                                               "<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text, 0 );
+                                       if( slapMode & SLAP_TOOL_MODE ) {
+                                               goto fail;
+                                       }
+       
+                                       rc = slap_bv2undef_ad( type+i, &ad, &text, 0 );
+                                       if( rc != LDAP_SUCCESS ) {
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "<= str2entry: slap_str2undef_ad(%s): %s\n",
+                                                               type[i].bv_val, text, 0 );
+                                               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 ) {
+       
+                               /* 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 value #%d provided more than once\n",
-                                               atail->a_desc->ad_cname.bv_val, j, 0 );
+                                               "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;
                                }
                        }
-                       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 &&
-                               ad_prev->ad_type->sat_equality->smr_normalize )
-                               atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
-                       else
-                               atail->a_nvals = NULL;
-                       k = i - attr_cnt;
-                       for ( j=0; j<attr_cnt; j++ ) {
-                               if ( freeval[k] )
-                                       atail->a_vals[j] = vals[k];
+       
+                       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 &&
+                                       ad_prev->ad_type->sat_equality->smr_normalize )
+                                       atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
                                else
-                                       ber_dupbv( atail->a_vals+j, &vals[k] );
-                               vals[k].bv_val = NULL;
+                                       atail->a_nvals = NULL;
+                               k = i - attr_cnt;
+                               for ( j=0; j<attr_cnt; j++ ) {
+                                       if ( freeval[k] )
+                                               atail->a_vals[j] = vals[k];
+                                       else
+                                               ber_dupbv( atail->a_vals+j, &vals[k] );
+                                       vals[k].bv_val = NULL;
+                                       if ( atail->a_nvals ) {
+                                               atail->a_nvals[j] = nvals[k];
+                                               nvals[k].bv_val = NULL;
+                                       }
+                                       k++;
+                               }
+                               BER_BVZERO( &atail->a_vals[j] );
                                if ( atail->a_nvals ) {
-                                       atail->a_nvals[j] = nvals[k];
-                                       nvals[k].bv_val = NULL;
+                                       BER_BVZERO( &atail->a_nvals[j] );
+                               } else {
+                                       atail->a_nvals = atail->a_vals;
                                }
-                               k++;
+                               attr_cnt = 0;
+                               if ( i == lines ) break;
                        }
-                       BER_BVZERO( &atail->a_vals[j] );
-                       if ( atail->a_nvals ) {
-                               BER_BVZERO( &atail->a_nvals[j] );
-                       } else {
-                               atail->a_nvals = atail->a_vals;
-                       }
-                       attr_cnt = 0;
-                       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 =
-                               ad->ad_type->sat_syntax->ssyn_validate;
-                       slap_syntax_transform_func *pretty =
-                               ad->ad_type->sat_syntax->ssyn_pretty;
-
-                       if ( pretty ) {
-                               rc = ordered_value_pretty( ad,
-                                       &vals[i], &pval, NULL );
-
-                       } else if ( validate ) {
-                               /*
-                                * validate value per syntax
-                                */
-                               rc = ordered_value_validate( ad, &vals[i], LDAP_MOD_ADD );
-
-                       } else {
+       
+                       if ( BER_BVISNULL( &vals[i] ) ) {
                                Debug( LDAP_DEBUG_ANY,
                                        "str2entry: attributeType %s #%d: "
-                                       "no validator for syntax %s\n", 
-                                       ad->ad_cname.bv_val, attr_cnt,
-                                       ad->ad_type->sat_syntax->ssyn_oid );
-                               goto fail;
-                       }
-
-                       if( rc != 0 ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "str2entry: invalid value "
-                                       "for attributeType %s #%d (syntax %s)\n",
-                                       ad->ad_cname.bv_val, attr_cnt,
-                                       ad->ad_type->sat_syntax->ssyn_oid );
+                                       "no value\n", 
+                                       ad->ad_cname.bv_val, attr_cnt, 0 );
                                goto fail;
                        }
-
-                       if( pretty ) {
-                               if ( freeval[i] ) free( vals[i].bv_val );
-                               vals[i] = pval;
-                               freeval[i] = 1;
+       
+                       if( slapMode & SLAP_TOOL_MODE ) {
+                               struct berval pval;
+                               slap_syntax_validate_func *validate =
+                                       ad->ad_type->sat_syntax->ssyn_validate;
+                               slap_syntax_transform_func *pretty =
+                                       ad->ad_type->sat_syntax->ssyn_pretty;
+       
+                               if ( pretty ) {
+                                       rc = ordered_value_pretty( ad,
+                                               &vals[i], &pval, NULL );
+       
+                               } else if ( validate ) {
+                                       /*
+                                        * validate value per syntax
+                                        */
+                                       rc = ordered_value_validate( ad, &vals[i], LDAP_MOD_ADD );
+       
+                               } else {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "str2entry: attributeType %s #%d: "
+                                               "no validator for syntax %s\n", 
+                                               ad->ad_cname.bv_val, attr_cnt,
+                                               ad->ad_type->sat_syntax->ssyn_oid );
+                                       goto fail;
+                               }
+       
+                               if( rc != 0 ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "str2entry: invalid value "
+                                               "for attributeType %s #%d (syntax %s)\n",
+                                               ad->ad_cname.bv_val, attr_cnt,
+                                               ad->ad_type->sat_syntax->ssyn_oid );
+                                       goto fail;
+                               }
+       
+                               if( pretty ) {
+                                       if ( freeval[i] ) free( vals[i].bv_val );
+                                       vals[i] = pval;
+                                       freeval[i] = 1;
+                               }
                        }
-               }
-
-               if ( ad->ad_type->sat_equality &&
-                       ad->ad_type->sat_equality->smr_normalize )
-               {
-                       rc = ordered_value_normalize(
-                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                               ad,
-                               ad->ad_type->sat_equality,
-                               &vals[i], &nvals[i], NULL );
-
-                       if ( rc ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "<= str2entry NULL (smr_normalize %s %d)\n", ad->ad_cname.bv_val, rc, 0 );
-                               goto fail;
+       
+                       if ( ad->ad_type->sat_equality &&
+                               ad->ad_type->sat_equality->smr_normalize )
+                       {
+                               rc = ordered_value_normalize(
+                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                       ad,
+                                       ad->ad_type->sat_equality,
+                                       &vals[i], &nvals[i], NULL );
+       
+                               if ( rc ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "<= str2entry NULL (smr_normalize %s %d)\n", ad->ad_cname.bv_val, rc, 0 );
+                                       goto fail;
+                               }
                        }
+       
+                       attr_cnt++;
                }
-
-               attr_cnt++;
        }
 
        free( type );
@@ -424,10 +426,20 @@ fail:
                } \
        }
 
+/* NOTE: only preserved for binary compatibility */
 char *
 entry2str(
        Entry   *e,
        int             *len )
+{
+       return entry2str_wrap( e, len, LDIF_LINE_WIDTH );
+}
+
+char *
+entry2str_wrap(
+       Entry           *e,
+       int                     *len,
+       ber_len_t       wrap )
 {
        Attribute       *a;
        struct berval   *bv;
@@ -449,7 +461,7 @@ entry2str(
                /* put "dn: <dn>" */
                tmplen = e->e_name.bv_len;
                MAKE_SPACE( LDIF_SIZE_NEEDED( 2, tmplen ));
-               ldif_sput( &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen );
+               ldif_sput_wrap( &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen, wrap );
        }
 
        /* put the attributes */
@@ -459,9 +471,9 @@ entry2str(
                        bv = &a->a_vals[i];
                        tmplen = a->a_desc->ad_cname.bv_len;
                        MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
-                       ldif_sput( &ecur, LDIF_PUT_VALUE,
+                       ldif_sput_wrap( &ecur, LDIF_PUT_VALUE,
                                a->a_desc->ad_cname.bv_val,
-                               bv->bv_val, bv->bv_len );
+                               bv->bv_val, bv->bv_len, wrap );
                }
        }
        MAKE_SPACE( 1 );
@@ -723,13 +735,14 @@ ber_len_t entry_flatsize(Entry *e, int norm)
  */
 int entry_encode(Entry *e, struct berval *bv)
 {
-       ber_len_t len, dnlen, ndnlen;
-       int i, nattrs, nvals;
+       ber_len_t len, dnlen, ndnlen, i;
+       int nattrs, nvals;
        Attribute *a;
        unsigned char *ptr;
 
        Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
                (long) e->e_id, e->e_dn, 0 );
+
        dnlen = e->e_name.bv_len;
        ndnlen = e->e_nname.bv_len;
 
@@ -780,6 +793,10 @@ int entry_encode(Entry *e, struct berval *bv)
                        }
                }
        }
+
+       Debug( LDAP_DEBUG_TRACE, "<= entry_encode(0x%08lx): %s\n",
+               (long) e->e_id, e->e_dn, 0 );
+
        return 0;
 }
 
@@ -797,22 +814,44 @@ int entry_header(EntryHeader *eh)
 {
        unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
 
+       /* Some overlays can create empty entries
+        * so don't check for zeros here.
+        */
        eh->nattrs = entry_getlen(&ptr);
-       if ( !eh->nattrs ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "entry_header: attribute count was zero\n", 0, 0, 0);
-               return LDAP_OTHER;
-       }
        eh->nvals = entry_getlen(&ptr);
-       if ( !eh->nvals ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "entry_header: value count was zero\n", 0, 0, 0);
-               return LDAP_OTHER;
-       }
        eh->data = (char *)ptr;
        return LDAP_SUCCESS;
 }
 
+int
+entry_decode_dn( EntryHeader *eh, struct berval *dn, struct berval *ndn )
+{
+       int i;
+       unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
+
+       assert( dn != NULL || ndn != NULL );
+
+       ptr = (unsigned char *)eh->data;
+       i = entry_getlen(&ptr);
+       if ( dn != NULL ) {
+               dn->bv_val = (char *) ptr;
+               dn->bv_len = i;
+       }
+
+       if ( ndn != NULL ) {
+               ptr += i + 1;
+               i = entry_getlen(&ptr);
+               ndn->bv_val = (char *) ptr;
+               ndn->bv_len = i;
+       }
+
+       Debug( LDAP_DEBUG_TRACE,
+               "entry_decode_dn: \"%s\"\n",
+               dn ? dn->bv_val : ndn->bv_val, 0, 0 );
+
+       return 0;
+}
+
 #ifdef SLAP_ZONE_ALLOC
 int entry_decode(EntryHeader *eh, Entry **e, void *ctx)
 #else
@@ -929,19 +968,27 @@ int entry_decode(EntryHeader *eh, Entry **e)
        return 0;
 }
 
-Entry *entry_dup( Entry *e )
+Entry *
+entry_dup2( Entry *dest, Entry *source )
 {
-       Entry *ret;
+       assert( dest != NULL );
+       assert( source != NULL );
 
-       ret = entry_alloc();
+       assert( dest->e_private == NULL );
 
-       ret->e_id = e->e_id;
-       ber_dupbv( &ret->e_name, &e->e_name );
-       ber_dupbv( &ret->e_nname, &e->e_nname );
-       ret->e_attrs = attrs_dup( e->e_attrs );
-       ret->e_ocflags = e->e_ocflags;
+       dest->e_id = source->e_id;
+       ber_dupbv( &dest->e_name, &source->e_name );
+       ber_dupbv( &dest->e_nname, &source->e_nname );
+       dest->e_attrs = attrs_dup( source->e_attrs );
+       dest->e_ocflags = source->e_ocflags;
 
-       return ret;
+       return dest;
+}
+
+Entry *
+entry_dup( Entry *e )
+{
+       return entry_dup2( entry_alloc(), e );
 }
 
 #if 1