1 /* attr.c - backend routines for dealing with attributes */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2005 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
21 #include <ac/socket.h>
22 #include <ac/string.h>
28 /* for the cache of attribute information (which are indexed, etc.) */
29 typedef struct bdb_attrinfo {
30 AttributeDescription *ai_desc; /* attribute description cn;lang-en */
31 slap_mask_t ai_indexmask; /* how the attr is indexed */
32 #ifdef LDAP_COMP_MATCH
33 ComponentReference* ai_cr; /*component indexing*/
43 const AttributeDescription *desc = v_desc;
44 const AttrInfo *a = v_a;
45 return SLAP_PTRCMP(desc, a->ai_desc);
54 const AttrInfo *a = v_a, *b = v_b;
55 return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
58 #ifdef LDAP_COMP_MATCH
62 AttributeDescription *desc,
63 ComponentReference** cr )
67 a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
69 *cr = a != NULL ? a->ai_cr : 0 ;
74 AttributeDescription *desc,
75 slap_mask_t *indexmask,
76 ComponentReference** cr )
80 a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
82 *indexmask = a->ai_indexmask;
94 AttributeDescription *desc,
95 slap_mask_t *indexmask )
99 a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
101 *indexmask = a != NULL ? a->ai_indexmask : 0;
105 bdb_attr_index_config(
106 struct bdb_info *bdb,
116 char **indexes = NULL;
118 attrs = ldap_str2charray( argv[0], "," );
120 if( attrs == NULL ) {
121 fprintf( stderr, "%s: line %d: "
122 "no attributes specified: %s\n",
123 fname, lineno, argv[0] );
124 return LDAP_PARAM_ERROR;
128 indexes = ldap_str2charray( argv[1], "," );
130 if( indexes == NULL ) {
131 fprintf( stderr, "%s: line %d: "
132 "no indexes specified: %s\n",
133 fname, lineno, argv[1] );
134 return LDAP_PARAM_ERROR;
138 if( indexes == NULL ) {
139 mask = bdb->bi_defaultmask;
144 for ( i = 0; indexes[i] != NULL; i++ ) {
146 rc = slap_str2index( indexes[i], &index );
148 if( rc != LDAP_SUCCESS ) {
149 fprintf( stderr, "%s: line %d: "
150 "index type \"%s\" undefined\n",
151 fname, lineno, indexes[i] );
152 return LDAP_PARAM_ERROR;
160 fprintf( stderr, "%s: line %d: "
161 "no indexes selected\n",
163 return LDAP_PARAM_ERROR;
166 for ( i = 0; attrs[i] != NULL; i++ ) {
168 AttributeDescription *ad;
170 #ifdef LDAP_COMP_MATCH
171 ComponentReference* cr = NULL;
172 AttrInfo *a_cr = NULL;
175 if( strcasecmp( attrs[i], "default" ) == 0 ) {
176 bdb->bi_defaultmask |= mask;
180 #ifdef LDAP_COMP_MATCH
181 if ( is_component_reference( attrs[i] ) ) {
182 rc = extract_component_reference( attrs[i], &cr );
183 if ( rc != LDAP_SUCCESS ) {
184 fprintf( stderr, "%s: line %d: "
185 "index component reference\"%s\" undefined\n",
186 fname, lineno, attrs[i] );
189 cr->cr_indexmask = mask;
191 * After extracting a component reference
192 * only the name of a attribute will be remaining
198 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
200 #ifdef LDAP_COMP_MATCH
204 rc = slap_str2ad( attrs[i], &ad, &text );
206 if( rc != LDAP_SUCCESS ) {
207 fprintf( stderr, "%s: line %d: "
208 "index attribute \"%s\" undefined\n",
209 fname, lineno, attrs[i] );
213 if( slap_ad_is_binary( ad ) ) {
214 fprintf( stderr, "%s: line %d: "
215 "index of attribute \"%s\" disallowed\n",
216 fname, lineno, attrs[i] );
217 return LDAP_UNWILLING_TO_PERFORM;
220 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
221 ad->ad_type->sat_approx
222 && ad->ad_type->sat_approx->smr_indexer
223 && ad->ad_type->sat_approx->smr_filter ) )
225 fprintf( stderr, "%s: line %d: "
226 "approx index of attribute \"%s\" disallowed\n",
227 fname, lineno, attrs[i] );
228 return LDAP_INAPPROPRIATE_MATCHING;
231 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
232 ad->ad_type->sat_equality
233 && ad->ad_type->sat_equality->smr_indexer
234 && ad->ad_type->sat_equality->smr_filter ) )
236 fprintf( stderr, "%s: line %d: "
237 "equality index of attribute \"%s\" disallowed\n",
238 fname, lineno, attrs[i] );
239 return LDAP_INAPPROPRIATE_MATCHING;
242 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
243 ad->ad_type->sat_substr
244 && ad->ad_type->sat_substr->smr_indexer
245 && ad->ad_type->sat_substr->smr_filter ) )
247 fprintf( stderr, "%s: line %d: "
248 "substr index of attribute \"%s\" disallowed\n",
249 fname, lineno, attrs[i] );
250 return LDAP_INAPPROPRIATE_MATCHING;
253 Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n",
254 ad->ad_cname.bv_val, mask, 0 );
257 a->ai_indexmask = mask;
258 #ifdef LDAP_COMP_MATCH
260 a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
263 * AttrInfo is already in AVL
264 * just add the extracted component reference
267 rc = insert_component_reference( cr, &a_cr->ai_cr );
268 if ( rc != LDAP_SUCCESS) {
269 fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
270 return LDAP_PARAM_ERROR;
274 rc = insert_component_reference( cr, &a->ai_cr );
275 if ( rc != LDAP_SUCCESS) {
276 fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
277 return LDAP_PARAM_ERROR;
282 rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
283 ainfo_cmp, avl_dup_error );
286 fprintf( stderr, "%s: line %d: duplicate index definition "
287 "for attr \"%s\" (ignored)\n",
288 fname, lineno, attrs[i] );
290 return LDAP_PARAM_ERROR;
294 ldap_charray_free( attrs );
295 if ( indexes != NULL ) ldap_charray_free( indexes );
301 bdb_attr_index_unparser( void *v1, void *v2 )
308 slap_index2bvlen( ai->ai_indexmask, &bv );
310 bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1;
311 ptr = ch_malloc( bv.bv_len+1 );
312 bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val );
314 slap_index2bv( ai->ai_indexmask, &bv );
316 ber_bvarray_add( bva, &bv );
320 static AttributeDescription addef = { NULL, NULL, BER_BVC("default") };
321 static AttrInfo aidef = { &addef };
324 bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva )
326 if ( bdb->bi_defaultmask ) {
327 aidef.ai_indexmask = bdb->bi_defaultmask;
328 bdb_attr_index_unparser( &aidef, bva );
330 avl_apply( bdb->bi_attrs, bdb_attr_index_unparser, bva, -1, AVL_INORDER );
334 bdb_attr_index_destroy( Avlnode *tree )
336 avl_free( tree, free );