X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fentry.c;h=ff2b3574a80478496caf2eb9aa283a0d397b0f6d;hb=40f785f62a209c0653340cc5d11e7a965df873ae;hp=7f1461d24f2ac544c84475ac536269ca4014d5ac;hpb=2271fb463636428ff3941810794fce62ca28e703;p=openldap diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 7f1461d24f..ff2b3574a8 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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 @@ -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 ) { @@ -180,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", @@ -212,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; @@ -243,124 +241,157 @@ str2entry2( char *s, int checkvals ) } } - for ( i=0; i<=lines; i++ ) { - ad_prev = ad; - if ( !ad || ( iad_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 || ( iad_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( 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: slap_str2undef_ad(%s): %s\n", - type[i].bv_val, text, 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; } } - } - - if (( ad_prev && ad != ad_prev ) || ( i == lines )) { - int j, k; - atail->a_next = attr_alloc( NULL ); - atail = atail->a_next; - atail->a_flags = 0; - 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; ja_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; ja_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++; - } - 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; } - attr_cnt = 0; - if ( i == lines ) break; - } - - 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 %d)\n", rc, 0, 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 ); @@ -694,13 +725,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; @@ -728,6 +760,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); @@ -750,6 +783,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; } @@ -789,7 +826,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; @@ -841,7 +878,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) { @@ -873,6 +911,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 ) @@ -946,6 +997,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;