]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/attr.c
3947aeab7294afed0abd813f9bbf74367d968b27
[openldap] / servers / slapd / back-bdb / attr.c
1 /* attr.c - backend routines for dealing with attributes */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2000-2004 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
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>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/socket.h>
22 #include <ac/string.h>
23
24 #include "slap.h"
25 #include "back-bdb.h"
26
27 /* for the cache of attribute information (which are indexed, etc.) */
28 typedef struct bdb_attrinfo {
29         AttributeDescription *ai_desc; /* attribute description cn;lang-en */
30         slap_mask_t ai_indexmask;       /* how the attr is indexed      */
31 #ifdef LDAP_COMP_MATCH
32         ComponentReference* ai_cr; /*component indexing*/
33 #endif
34 } AttrInfo;
35
36 static int
37 ainfo_type_cmp(
38         const void *v_desc,
39         const void *v_a
40 )
41 {
42         const AttributeDescription *desc = v_desc;
43         const AttrInfo  *a = v_a;
44         return SLAP_PTRCMP(desc, a->ai_desc);
45 }
46
47 static int
48 ainfo_cmp(
49         const void      *v_a,
50         const void      *v_b
51 )
52 {
53         const AttrInfo *a = v_a, *b = v_b;
54         return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
55 }
56
57 #ifdef LDAP_COMP_MATCH
58 void
59 bdb_attr_comp_ref(
60         struct bdb_info *bdb,
61         AttributeDescription *desc,
62         ComponentReference** cr )
63 {
64         AttrInfo        *a;
65
66         a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
67         
68         *cr = a != NULL ? a->ai_cr : 0 ;
69 }
70 #endif
71
72 void
73 bdb_attr_mask(
74         struct bdb_info *bdb,
75         AttributeDescription *desc,
76         slap_mask_t *indexmask )
77 {
78         AttrInfo        *a;
79
80         a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
81         
82         *indexmask = a != NULL ? a->ai_indexmask : 0;
83 }
84
85 int
86 bdb_attr_index_config(
87         struct bdb_info *bdb,
88         const char              *fname,
89         int                     lineno,
90         int                     argc,
91         char            **argv )
92 {
93         int rc;
94         int     i;
95         slap_mask_t mask;
96         char **attrs;
97         char **indexes = NULL;
98
99         attrs = ldap_str2charray( argv[0], "," );
100
101         if( attrs == NULL ) {
102                 fprintf( stderr, "%s: line %d: "
103                         "no attributes specified: %s\n",
104                         fname, lineno, argv[0] );
105                 return LDAP_PARAM_ERROR;
106         }
107
108         if ( argc > 1 ) {
109                 indexes = ldap_str2charray( argv[1], "," );
110
111                 if( indexes == NULL ) {
112                         fprintf( stderr, "%s: line %d: "
113                                 "no indexes specified: %s\n",
114                                 fname, lineno, argv[1] );
115                         return LDAP_PARAM_ERROR;
116                 }
117         }
118
119         if( indexes == NULL ) {
120                 mask = bdb->bi_defaultmask;
121
122         } else {
123                 mask = 0;
124
125                 for ( i = 0; indexes[i] != NULL; i++ ) {
126                         slap_mask_t index;
127                         rc = slap_str2index( indexes[i], &index );
128
129                         if( rc != LDAP_SUCCESS ) {
130                                 fprintf( stderr, "%s: line %d: "
131                                         "index type \"%s\" undefined\n",
132                                         fname, lineno, indexes[i] );
133                                 return LDAP_PARAM_ERROR;
134                         }
135
136                         mask |= index;
137                 }
138         }
139
140         if( !mask ) {
141                 fprintf( stderr, "%s: line %d: "
142                         "no indexes selected\n",
143                         fname, lineno );
144                 return LDAP_PARAM_ERROR;
145         }
146
147         for ( i = 0; attrs[i] != NULL; i++ ) {
148                 AttrInfo        *a;
149                 AttributeDescription *ad;
150                 const char *text;
151 #ifdef LDAP_COMP_MATCH
152                 ComponentReference* cr = NULL;
153                 AttrInfo *a_cr = NULL;
154 #endif
155
156                 if( strcasecmp( attrs[i], "default" ) == 0 ) {
157                         bdb->bi_defaultmask |= mask;
158                         continue;
159                 }
160
161 #ifdef LDAP_COMP_MATCH
162                 if ( is_component_reference( attrs[i] ) ) {
163                         rc = extract_component_reference( attrs[i], &cr );
164                         if ( rc != LDAP_SUCCESS ) {
165                                 fprintf( stderr, "%s: line %d: "
166                                         "index component reference\"%s\" undefined\n",
167                                         fname, lineno, attrs[i] );
168                                 return rc;
169                         }
170                         cr->cr_indexmask = mask;
171                         /*
172                          * After extracting a component reference
173                          * only the name of a attribute will be remaining
174                          */
175                 } else {
176                         cr = NULL;
177                 }
178 #endif
179                 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
180
181 #ifdef LDAP_COMP_MATCH
182                 a->ai_cr = NULL;
183 #endif
184                 ad = NULL;
185                 rc = slap_str2ad( attrs[i], &ad, &text );
186
187                 if( rc != LDAP_SUCCESS ) {
188                         fprintf( stderr, "%s: line %d: "
189                                 "index attribute \"%s\" undefined\n",
190                                 fname, lineno, attrs[i] );
191                         return rc;
192                 }
193
194                 if( slap_ad_is_binary( ad ) ) {
195                         fprintf( stderr, "%s: line %d: "
196                                 "index of attribute \"%s\" disallowed\n",
197                                 fname, lineno, attrs[i] );
198                         return LDAP_UNWILLING_TO_PERFORM;
199                 }
200
201                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
202                         ad->ad_type->sat_approx
203                                 && ad->ad_type->sat_approx->smr_indexer
204                                 && ad->ad_type->sat_approx->smr_filter ) )
205                 {
206                         fprintf( stderr, "%s: line %d: "
207                                 "approx index of attribute \"%s\" disallowed\n",
208                                 fname, lineno, attrs[i] );
209                         return LDAP_INAPPROPRIATE_MATCHING;
210                 }
211
212                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
213                         ad->ad_type->sat_equality
214                                 && ad->ad_type->sat_equality->smr_indexer
215                                 && ad->ad_type->sat_equality->smr_filter ) )
216                 {
217                         fprintf( stderr, "%s: line %d: "
218                                 "equality index of attribute \"%s\" disallowed\n",
219                                 fname, lineno, attrs[i] );
220                         return LDAP_INAPPROPRIATE_MATCHING;
221                 }
222
223                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
224                         ad->ad_type->sat_substr
225                                 && ad->ad_type->sat_substr->smr_indexer
226                                 && ad->ad_type->sat_substr->smr_filter ) )
227                 {
228                         fprintf( stderr, "%s: line %d: "
229                                 "substr index of attribute \"%s\" disallowed\n",
230                                 fname, lineno, attrs[i] );
231                         return LDAP_INAPPROPRIATE_MATCHING;
232                 }
233
234                 Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n",
235                         ad->ad_cname.bv_val, mask, 0 ); 
236
237                 a->ai_desc = ad;
238                 a->ai_indexmask = mask;
239 #ifdef LDAP_COMP_MATCH
240                 if ( cr ) {
241                         a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
242                         if ( a_cr ) {
243                                 /*
244                                  * AttrInfo is already in AVL
245                                  * just add the extracted component reference
246                                  * in the AttrInfo
247                                  */
248                                 rc = insert_component_reference( cr, &a_cr->ai_cr );
249                                 if ( rc != LDAP_SUCCESS) {
250                                         fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
251                                         return LDAP_PARAM_ERROR;
252                                 }
253                                 continue;
254                         } else {
255                                 rc = insert_component_reference( cr, &a->ai_cr );
256                                 if ( rc != LDAP_SUCCESS) {
257                                         fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
258                                         return LDAP_PARAM_ERROR;
259                                 }
260                         }
261                 }
262 #endif
263                 rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
264                                  ainfo_cmp, avl_dup_error );
265
266                 if( rc ) {
267                         fprintf( stderr, "%s: line %d: duplicate index definition "
268                                 "for attr \"%s\" (ignored)\n",
269                                 fname, lineno, attrs[i] );
270
271                         return LDAP_PARAM_ERROR;
272                 }
273         }
274
275         ldap_charray_free( attrs );
276         if ( indexes != NULL ) ldap_charray_free( indexes );
277
278         return LDAP_SUCCESS;
279 }
280
281 void
282 bdb_attr_index_destroy( Avlnode *tree )
283 {
284         avl_free( tree, free );
285 }
286