X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fattr.c;h=6bfa9824b4a12a096fe6e6b15697924b852d99be;hb=82540c5cc1be5bf17b22f3a41d12d1bc56180654;hp=07bbcfdb6e2d9fed11b26db2ae079482635235df;hpb=4e160e83b606f512c0ed89adc6970b606d9c314b;p=openldap diff --git a/servers/slapd/back-ldbm/attr.c b/servers/slapd/back-ldbm/attr.c index 07bbcfdb6e..6bfa9824b4 100644 --- a/servers/slapd/back-ldbm/attr.c +++ b/servers/slapd/back-ldbm/attr.c @@ -1,4 +1,9 @@ /* attr.c - backend routines for dealing with attributes */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ #include "portable.h" @@ -10,159 +15,205 @@ #include "slap.h" #include "back-ldbm.h" +/* for the cache of attribute information (which are indexed, etc.) */ +typedef struct ldbm_attrinfo { + AttributeDescription *ai_desc; /* attribute description cn;lang-en */ + slap_mask_t ai_indexmask; /* how the attr is indexed */ +} AttrInfo; + static int ainfo_type_cmp( - char *type, - struct attrinfo *a + AttributeDescription *desc, + AttrInfo *a ) { - return( strcasecmp( type, a->ai_type ) ); + return desc - a->ai_desc; } static int ainfo_cmp( - struct attrinfo *a, - struct attrinfo *b + AttrInfo *a, + AttrInfo *b ) { - return( strcasecmp( a->ai_type, b->ai_type ) ); -} - -/* - * Called when a duplicate "index" line is encountered. - * - * returns 1 => original from init code, indexmask updated - * 2 => original not from init code, warn the user - */ - -static int -ainfo_dup( - struct attrinfo *a, - struct attrinfo *b -) -{ - /* - * if the duplicate definition is because we initialized the attr, - * just add what came from the config file. otherwise, complain. - */ - if ( a->ai_indexmask & INDEX_FROMINIT ) { - a->ai_indexmask |= b->ai_indexmask; - - return( 1 ); - } - - return( 2 ); + return a->ai_desc - b->ai_desc; } void -attr_masks( +attr_mask( struct ldbminfo *li, - char *type, - int *indexmask, - int *syntaxmask -) + AttributeDescription *desc, + slap_mask_t *indexmask ) { - struct attrinfo *a; - - *indexmask = 0; - *syntaxmask = 0; - if ( (a = (struct attrinfo *) avl_find( li->li_attrs, type, - (AVL_CMP) ainfo_type_cmp )) == NULL ) { - if ( (a = (struct attrinfo *) avl_find( li->li_attrs, "default", - (AVL_CMP) ainfo_type_cmp )) == NULL ) { - return; - } - } - *indexmask = a->ai_indexmask; - if ( strcasecmp( a->ai_type, "default" ) == 0 ) { - *syntaxmask = attr_syntax( type ); - } else { - *syntaxmask = a->ai_syntaxmask; - } + AttrInfo *a; + + a = (AttrInfo *) avl_find( li->li_attrs, desc, + (AVL_CMP) ainfo_type_cmp ); + + *indexmask = a != NULL ? a->ai_indexmask : 0; } -void +int attr_index_config( struct ldbminfo *li, - char *fname, + const char *fname, int lineno, int argc, - char **argv, - int init -) + char **argv ) { - int i, j; - char **attrs, **indexes; - struct attrinfo *a; + int rc; + int i; + slap_mask_t mask; + char **attrs; + char **indexes = NULL; attrs = str2charray( argv[0], "," ); + + if( attrs == NULL ) { + fprintf( stderr, "%s: line %d: " + "no attributes specified: %s\n", + fname, lineno, argv[0] ); + return LDAP_PARAM_ERROR; + } + if ( argc > 1 ) { indexes = str2charray( argv[1], "," ); + + if( indexes == NULL ) { + fprintf( stderr, "%s: line %d: " + "no indexes specified: %s\n", + fname, lineno, argv[1] ); + return LDAP_PARAM_ERROR; + } } - for ( i = 0; attrs[i] != NULL; i++ ) { - a = (struct attrinfo *) ch_malloc( sizeof(struct attrinfo) ); - a->ai_type = ch_strdup( attrs[i] ); - a->ai_syntaxmask = attr_syntax( a->ai_type ); - if ( argc == 1 ) { - a->ai_indexmask = (INDEX_PRESENCE | INDEX_EQUALITY | - INDEX_APPROX | INDEX_SUB); - } else { - a->ai_indexmask = 0; - for ( j = 0; indexes[j] != NULL; j++ ) { - if ( strncasecmp( indexes[j], "pres", 4 ) - == 0 ) { - a->ai_indexmask |= INDEX_PRESENCE; - } else if ( strncasecmp( indexes[j], "eq", 2 ) - == 0 ) { - a->ai_indexmask |= INDEX_EQUALITY; - } else if ( strncasecmp( indexes[j], "approx", - 6 ) == 0 ) { - a->ai_indexmask |= INDEX_APPROX; - } else if ( strncasecmp( indexes[j], "sub", 3 ) - == 0 ) { - a->ai_indexmask |= INDEX_SUB; - } else if ( strncasecmp( indexes[j], "none", 4 ) - == 0 ) { - if ( a->ai_indexmask != 0 ) { - fprintf( stderr, -"%s: line %d: index type \"none\" cannot be combined with other types\n", - fname, lineno ); - } - a->ai_indexmask = 0; - } else { - fprintf( stderr, - "%s: line %d: unknown index type \"%s\" (ignored)\n", - fname, lineno, indexes[j] ); - fprintf( stderr, - "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" ); - } + + if( indexes == NULL ) { + mask = li->li_defaultmask; + + } else { + mask = 0; + + for ( i = 0; indexes[i] != NULL; i++ ) { + slap_mask_t index; + 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; } + + mask |= index; } - if ( init ) { - a->ai_indexmask |= INDEX_FROMINIT; + } + + if( !mask ) { + fprintf( stderr, "%s: line %d: " + "no indexes selected\n", + fname, lineno ); + return LDAP_PARAM_ERROR; + } + + for ( i = 0; attrs[i] != NULL; i++ ) { + AttrInfo *a; + AttributeDescription *ad; + const char *text; + + if( strcasecmp( attrs[i], "default" ) == 0 ) { + li->li_defaultmask = mask; + continue; + } + + a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); + + 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( 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( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( + ( ad->ad_type->sat_approx + && ad->ad_type->sat_approx->smr_indexer + && ad->ad_type->sat_approx->smr_filter ) + && ( ad->ad_type->sat_equality + && ad->ad_type->sat_equality->smr_indexer + && ad->ad_type->sat_equality->smr_filter ) ) ) + { + fprintf( stderr, "%s: line %d: " + "approx index of attribute \"%s\" disallowed\n", + fname, lineno, attrs[i] ); + return LDAP_INAPPROPRIATE_MATCHING; + } + + if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( + ad->ad_type->sat_equality + && 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; } - switch (avl_insert( &li->li_attrs, (caddr_t) a, - (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup )) + if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( + ad->ad_type->sat_substr + && ad->ad_type->sat_substr->smr_indexer + && ad->ad_type->sat_substr->smr_filter ) ) { - case 1: /* duplicate - updating init version */ - free( a->ai_type ); - free( (char *) a ); - break; - - case 2: /* user duplicate - ignore and warn */ - fprintf( stderr, - "%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n", - fname, lineno, a->ai_type ); - free( a->ai_type ); - free( (char *) a ); - break; - - default:; /* inserted ok */ - /* FALL */ + fprintf( stderr, "%s: line %d: " + "substr index of attribute \"%s\" disallowed\n", + fname, lineno, attrs[i] ); + return LDAP_INAPPROPRIATE_MATCHING; + } + +#ifdef NEW_LOGGING + LDAP_LOG( BACK_LDBM, DETAIL1, + "attr_index_config: index %s 0x%04lx\n", + ad->ad_cname.bv_val, mask, 0 ); +#else + Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", + ad->ad_cname.bv_val, mask, 0 ); +#endif + + + a->ai_desc = ad; + + a->ai_indexmask = mask; + + rc = avl_insert( &li->li_attrs, (caddr_t) a, + (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error ); + + if( rc ) { + fprintf( stderr, "%s: line %d: duplicate index definition " + "for attr \"%s\" (ignored)\n", + fname, lineno, attrs[i] ); + + return LDAP_PARAM_ERROR; } } + charray_free( attrs ); - if ( argc > 1 ) - charray_free( indexes ); + if ( indexes != NULL ) charray_free( indexes ); + + return LDAP_SUCCESS; +} + +void +attr_index_destroy( Avlnode *tree ) +{ + avl_free( tree, free ); }