X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fentry.c;h=9b768a9ce2952ff84c87a7f3656e5fe0d550579c;hb=001f14965402aa86f3d7cd364fc781caeb603719;hp=dda4e185023f86f3a4f92125f5d595eba0397611;hpb=f58ea89c20a49224b4be2efc9a24df71a59b1d85;p=openldap diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index dda4e18502..9b768a9ce2 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-2011 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 ) { @@ -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; @@ -238,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 ); @@ -390,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; @@ -415,7 +461,7 @@ entry2str( /* put "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 */ @@ -425,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 ); @@ -689,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; @@ -723,6 +770,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); @@ -745,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; } @@ -762,29 +814,51 @@ 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 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 +910,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 +943,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 ) @@ -880,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 @@ -941,6 +1037,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;