X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fattr.c;h=2f6203e66f2934457c08f29d0576a41a783f189c;hb=22bf5188a91d300453c4077eaa88af6b399ce7e9;hp=15b1e31f6a83ef14a7571b71bf39da358cc0cc1f;hpb=f9fb5e63f4b43bc2089ad1d94f19a04e2294b37b;p=openldap diff --git a/servers/slapd/back-bdb/attr.c b/servers/slapd/back-bdb/attr.c index 15b1e31f6a..2f6203e66f 100644 --- a/servers/slapd/back-bdb/attr.c +++ b/servers/slapd/back-bdb/attr.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2005 The OpenLDAP Foundation. + * Copyright 2000-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,28 +23,59 @@ #include "slap.h" #include "back-bdb.h" +#include "config.h" #include "lutil.h" - -static int -ainfo_type_cmp( - const void *v_desc, - const void *v_a -) +/* Find the ad, return -1 if not found, + * set point for insertion if ins is non-NULL + */ +int +bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, int *ins ) { - const AttributeDescription *desc = v_desc; - const AttrInfo *a = v_a; - return SLAP_PTRCMP(desc, a->ai_desc); + unsigned base = 0, cursor = 0; + unsigned n = bdb->bi_nattrs; + int val = 0; + + while ( 0 < n ) { + unsigned pivot = n >> 1; + cursor = base + pivot; + + val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc ); + if ( val < 0 ) { + n = pivot; + } else if ( val > 0 ) { + base = cursor + 1; + n -= pivot + 1; + } else { + return cursor; + } + } + if ( ins ) { + if ( val > 0 ) + ++cursor; + *ins = cursor; + } + return -1; } static int -ainfo_cmp( - const void *v_a, - const void *v_b -) +ainfo_insert( struct bdb_info *bdb, AttrInfo *a ) { - const AttrInfo *a = v_a, *b = v_b; - return SLAP_PTRCMP(a->ai_desc, b->ai_desc); + int x; + int i = bdb_attr_slot( bdb, a->ai_desc, &x ); + + /* Is it a dup? */ + if ( i >= 0 ) + return -1; + + bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * + sizeof( AttrInfo * )); + if ( x < bdb->bi_nattrs ) + AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x], + ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *)); + bdb->bi_attrs[x] = a; + bdb->bi_nattrs++; + return 0; } AttrInfo * @@ -52,8 +83,8 @@ bdb_attr_mask( struct bdb_info *bdb, AttributeDescription *desc ) { - - return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp ); + int i = bdb_attr_slot( bdb, desc, NULL ); + return i < 0 ? NULL : bdb->bi_attrs[i]; } int @@ -62,9 +93,10 @@ bdb_attr_index_config( const char *fname, int lineno, int argc, - char **argv ) + char **argv, + struct config_reply_s *c_reply) { - int rc; + int rc = 0; int i; slap_mask_t mask; char **attrs; @@ -86,7 +118,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "no indexes specified: %s\n", fname, lineno, argv[1] ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } @@ -101,10 +134,16 @@ bdb_attr_index_config( rc = slap_str2index( indexes[i], &index ); if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "%s: line %d: " - "index type \"%s\" undefined\n", - fname, lineno, indexes[i] ); - return LDAP_PARAM_ERROR; + if ( c_reply ) + { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "index type \"%s\" undefined", indexes[i] ); + + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_PARAM_ERROR; + goto done; } mask |= index; @@ -112,10 +151,15 @@ bdb_attr_index_config( } if( !mask ) { - fprintf( stderr, "%s: line %d: " - "no indexes selected\n", - fname, lineno ); - return LDAP_PARAM_ERROR; + if ( c_reply ) + { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "no indexes selected" ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_PARAM_ERROR; + goto done; } for ( i = 0; attrs[i] != NULL; i++ ) { @@ -136,10 +180,15 @@ bdb_attr_index_config( if ( is_component_reference( attrs[i] ) ) { rc = extract_component_reference( attrs[i], &cr ); if ( rc != LDAP_SUCCESS ) { - fprintf( stderr, "%s: line %d: " - "index component reference\"%s\" undefined\n", - fname, lineno, attrs[i] ); - return rc; + if ( c_reply ) + { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "index component reference\"%s\" undefined", + attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + goto done; } cr->cr_indexmask = mask; /* @@ -149,27 +198,32 @@ bdb_attr_index_config( } else { cr = NULL; } -#endif - a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); - -#ifdef LDAP_COMP_MATCH - a->ai_cr = NULL; #endif ad = NULL; rc = slap_str2ad( attrs[i], &ad, &text ); if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "%s: line %d: " - "index attribute \"%s\" undefined\n", - fname, lineno, attrs[i] ); - return rc; + if ( c_reply ) + { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "index attribute \"%s\" undefined", + attrs[i] ); + + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + goto done; } - if( slap_ad_is_binary( ad ) ) { - fprintf( stderr, "%s: line %d: " - "index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - return LDAP_UNWILLING_TO_PERFORM; + if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) { + if (c_reply) { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "index of attribute \"%s\" disallowed", attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_UNWILLING_TO_PERFORM; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( @@ -177,10 +231,14 @@ bdb_attr_index_config( && ad->ad_type->sat_approx->smr_indexer && ad->ad_type->sat_approx->smr_filter ) ) { - fprintf( stderr, "%s: line %d: " - "approx index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + if (c_reply) { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "approx index of attribute \"%s\" disallowed", attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( @@ -188,10 +246,14 @@ bdb_attr_index_config( && ad->ad_type->sat_equality->smr_indexer && ad->ad_type->sat_equality->smr_filter ) ) { - fprintf( stderr, "%s: line %d: " - "equality index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + if (c_reply) { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "equality index of attribute \"%s\" disallowed", attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( @@ -199,15 +261,24 @@ bdb_attr_index_config( && ad->ad_type->sat_substr->smr_indexer && ad->ad_type->sat_substr->smr_filter ) ) { - fprintf( stderr, "%s: line %d: " - "substr index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + if (c_reply) { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "substr index of attribute \"%s\" disallowed", attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); + } + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", ad->ad_cname.bv_val, mask, 0 ); + a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); + +#ifdef LDAP_COMP_MATCH + a->ai_cr = NULL; +#endif a->ai_desc = ad; if ( bdb->bi_flags & BDB_IS_OPEN ) { @@ -220,7 +291,7 @@ bdb_attr_index_config( #ifdef LDAP_COMP_MATCH if ( cr ) { - a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp ); + a_cr = bdb_attr_mask( bdb, ad ); if ( a_cr ) { /* * AttrInfo is already in AVL @@ -230,48 +301,60 @@ bdb_attr_index_config( rc = insert_component_reference( cr, &a_cr->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } continue; } else { rc = insert_component_reference( cr, &a->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } } #endif - rc = avl_insert( &bdb->bi_attrs, (caddr_t) a, - ainfo_cmp, avl_dup_error ); - + rc = ainfo_insert( bdb, a ); if( rc ) { if ( bdb->bi_flags & BDB_IS_OPEN ) { - AttrInfo *b = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp ); - /* If we were editing this attr, reset it */ - b->ai_indexmask &= ~BDB_INDEX_DELETING; - /* If this is leftover from a previous add, commit it */ - if ( b->ai_newmask ) - b->ai_indexmask = b->ai_newmask; - b->ai_newmask = a->ai_newmask; - ch_free( a ); - continue; + AttrInfo *b = bdb_attr_mask( bdb, ad ); + /* If there is already an index defined for this attribute + * it must be replaced. Otherwise we end up with multiple + * olcIndex values for the same attribute */ + if ( b->ai_indexmask & BDB_INDEX_DELETING ) { + /* If we were editing this attr, reset it */ + b->ai_indexmask &= ~BDB_INDEX_DELETING; + /* If this is leftover from a previous add, commit it */ + if ( b->ai_newmask ) + b->ai_indexmask = b->ai_newmask; + b->ai_newmask = a->ai_newmask; + ch_free( a ); + rc = 0; + continue; + } + } + if (c_reply) { + snprintf(c_reply->msg, sizeof(c_reply->msg), + "duplicate index definition for attr \"%s\"", + attrs[i] ); + fprintf( stderr, "%s: line %d: %s\n", + fname, lineno, c_reply->msg ); } - fprintf( stderr, "%s: line %d: duplicate index definition " - "for attr \"%s\"" SLAPD_CONF_UNKNOWN_IGNORED ".\n", - fname, lineno, attrs[i] ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } +done: ldap_charray_free( attrs ); if ( indexes != NULL ) ldap_charray_free( indexes ); - return LDAP_SUCCESS; + return rc; } -static void +static int bdb_attr_index_unparser( void *v1, void *v2 ) { AttrInfo *ai = v1; @@ -289,6 +372,7 @@ bdb_attr_index_unparser( void *v1, void *v2 ) bv.bv_val = ptr; ber_bvarray_add( bva, &bv ); } + return 0; } static AttributeDescription addef = { NULL, NULL, BER_BVC("default") }; @@ -297,17 +381,19 @@ static AttrInfo aidef = { &addef }; void bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva ) { + int i; + if ( bdb->bi_defaultmask ) { aidef.ai_indexmask = bdb->bi_defaultmask; bdb_attr_index_unparser( &aidef, bva ); } - avl_apply( bdb->bi_attrs, bdb_attr_index_unparser, bva, -1, AVL_INORDER ); + for ( i=0; ibi_nattrs; i++ ) + bdb_attr_index_unparser( bdb->bi_attrs[i], bva ); } -static void -bdb_attrinfo_free( void *v ) +void +bdb_attr_info_free( AttrInfo *ai ) { - AttrInfo *ai = v; #ifdef LDAP_COMP_MATCH free( ai->ai_cr ); #endif @@ -315,52 +401,41 @@ bdb_attrinfo_free( void *v ) } void -bdb_attr_index_destroy( Avlnode *tree ) +bdb_attr_index_destroy( struct bdb_info *bdb ) { - avl_free( tree, bdb_attrinfo_free ); -} + int i; -void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad ) -{ - AttrInfo *ai; + for ( i=0; ibi_nattrs; i++ ) + bdb_attr_info_free( bdb->bi_attrs[i] ); - ai = avl_delete( &bdb->bi_attrs, ad, ainfo_type_cmp ); - if ( ai ) - bdb_attrinfo_free( ai ); + free( bdb->bi_attrs ); } -/* Get a list of AttrInfo's to delete */ - -typedef struct Alist { - struct Alist *next; - AttrInfo *ptr; -} Alist; - -static int -bdb_attrinfo_flush( void *v1, void *arg ) +void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad ) { - AttrInfo *ai = v1; - - if ( ai->ai_indexmask & BDB_INDEX_DELETING ) { - Alist **al = arg; - Alist *a = ch_malloc( sizeof( Alist )); - a->ptr = ai; - a->next = *al; - *al = a; + int i; + + i = bdb_attr_slot( bdb, ad, NULL ); + if ( i >= 0 ) { + bdb_attr_info_free( bdb->bi_attrs[i] ); + bdb->bi_nattrs--; + for (; ibi_nattrs; i++) + bdb->bi_attrs[i] = bdb->bi_attrs[i+1]; } - return 0; } void bdb_attr_flush( struct bdb_info *bdb ) { - Alist *al = NULL, *a2; - - avl_apply( bdb->bi_attrs, bdb_attrinfo_flush, &al, -1, AVL_INORDER ); - - while (( a2 = al )) { - al = al->next; - avl_delete( &bdb->bi_attrs, a2->ptr, ainfo_cmp ); - bdb_attrinfo_free( a2->ptr ); - ch_free( a2 ); + int i; + + for ( i=0; ibi_nattrs; i++ ) { + if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) { + int j; + bdb_attr_info_free( bdb->bi_attrs[i] ); + bdb->bi_nattrs--; + for (j=i; jbi_nattrs; j++) + bdb->bi_attrs[j] = bdb->bi_attrs[j+1]; + i--; + } } }