]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/attr.c
Experiment with busy loop protection...
[openldap] / servers / slapd / back-bdb / attr.c
1 /* attr.c - backend routines for dealing with attributes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16 #include "back-bdb.h"
17
18 /* for the cache of attribute information (which are indexed, etc.) */
19 typedef struct bdb_attrinfo {
20 #ifdef SLAPD_USE_AD
21         AttributeDescription *ai_desc; /* attribute description cn;lang-en      */
22 #else
23         char *ai_desc;
24 #endif
25         slap_mask_t ai_indexmask;       /* how the attr is indexed      */
26 } AttrInfo;
27
28 static int
29 ainfo_type_cmp(
30 #ifdef SLAPD_USE_AD
31         AttributeDescription *desc,
32 #else
33     char                *desc,
34 #endif
35     AttrInfo    *a
36 )
37 {
38 #ifdef SLAPD_USE_AD
39         return ad_cmp( desc, a->ai_desc );
40 #else
41         return( strcasecmp( desc, a->ai_desc ) );
42 #endif
43 }
44
45 static int
46 ainfo_cmp(
47     AttrInfo    *a,
48     AttrInfo    *b
49 )
50 {
51 #ifdef SLAPD_USE_AD
52         return ad_cmp( a->ai_desc, b->ai_desc );
53 #else
54         return( strcasecmp( a->ai_desc, b->ai_desc ) );
55 #endif
56 }
57
58 void
59 bdb_attr_mask(
60     struct bdb_info     *bdb,
61 #ifdef SLAPD_USE_AD
62         AttributeDescription *desc,
63 #else
64     const char *desc,
65 #endif
66     slap_mask_t *indexmask )
67 {
68         AttrInfo        *a;
69
70         a = (AttrInfo *) avl_find( bdb->bi_attrs, desc,
71             (AVL_CMP) ainfo_type_cmp );
72         
73         *indexmask = a != NULL ? a->ai_indexmask : 0;
74 }
75
76 int
77 bdb_attr_index_config(
78     struct bdb_info     *bdb,
79     const char          *fname,
80     int                 lineno,
81     int                 argc,
82     char                **argv )
83 {
84         int rc;
85         int     i;
86         slap_mask_t mask;
87         char **attrs;
88         char **indexes = NULL;
89
90         attrs = str2charray( argv[0], "," );
91
92         if( attrs == NULL ) {
93                 fprintf( stderr, "%s: line %d: "
94                         "no attributes specified: %s\n",
95                         fname, lineno, argv[0] );
96                 return LDAP_PARAM_ERROR;
97         }
98
99         if ( argc > 1 ) {
100                 indexes = str2charray( argv[1], "," );
101
102                 if( indexes == NULL ) {
103                         fprintf( stderr, "%s: line %d: "
104                                 "no indexes specified: %s\n",
105                                 fname, lineno, argv[1] );
106                         return LDAP_PARAM_ERROR;
107                 }
108         }
109
110         if( indexes == NULL ) {
111                 mask = bdb->bi_defaultmask;
112
113         } else {
114                 mask = 0;
115
116                 for ( i = 0; indexes[i] != NULL; i++ ) {
117                         slap_mask_t index;
118                         rc = slap_str2index( indexes[i], &index );
119
120                         if( rc != LDAP_SUCCESS ) {
121                                 fprintf( stderr, "%s: line %d: "
122                                         "index type \"%s\" undefined\n",
123                                         fname, lineno, indexes[i] );
124                                 return LDAP_PARAM_ERROR;
125                         }
126
127                         mask |= index;
128                 }
129         }
130
131     if( !mask ) {
132                 fprintf( stderr, "%s: line %d: "
133                         "no indexes selected\n",
134                         fname, lineno );
135                 return LDAP_PARAM_ERROR;
136         }
137
138         for ( i = 0; attrs[i] != NULL; i++ ) {
139                 AttrInfo        *a;
140                 AttributeDescription *ad;
141                 const char *text;
142
143                 if( strcasecmp( attrs[i], "default" ) == 0 ) {
144                         bdb->bi_defaultmask = mask;
145                         continue;
146                 }
147
148                 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
149
150                 ad = NULL;
151                 rc = slap_str2ad( attrs[i], &ad, &text );
152
153                 if( rc != LDAP_SUCCESS ) {
154                         fprintf( stderr, "%s: line %d: "
155                                 "index attribute \"%s\" undefined\n",
156                                 fname, lineno, attrs[i] );
157                         return rc;
158                 }
159
160                 if( slap_ad_is_binary( ad ) ) {
161                         fprintf( stderr, "%s: line %d: "
162                                 "index of attribute \"%s\" disallowed\n",
163                                 fname, lineno, attrs[i] );
164                         return LDAP_UNWILLING_TO_PERFORM;
165                 }
166
167                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
168                         ( ad->ad_type->sat_approx
169                                 && ad->ad_type->sat_approx->smr_indexer
170                                 && ad->ad_type->sat_approx->smr_filter )
171                         && ( ad->ad_type->sat_equality
172                                 && ad->ad_type->sat_equality->smr_indexer
173                                 && ad->ad_type->sat_equality->smr_filter ) ) )
174                 {
175                         fprintf( stderr, "%s: line %d: "
176                                 "approx index of attribute \"%s\" disallowed\n",
177                                 fname, lineno, attrs[i] );
178                         return LDAP_INAPPROPRIATE_MATCHING;
179                 }
180
181                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
182                         ad->ad_type->sat_equality
183                                 && ad->ad_type->sat_equality->smr_indexer
184                                 && ad->ad_type->sat_equality->smr_filter ) )
185                 {
186                         fprintf( stderr, "%s: line %d: "
187                                 "equality index of attribute \"%s\" disallowed\n",
188                                 fname, lineno, attrs[i] );
189                         return LDAP_INAPPROPRIATE_MATCHING;
190                 }
191
192                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
193                         ad->ad_type->sat_substr
194                                 && ad->ad_type->sat_substr->smr_indexer
195                                 && ad->ad_type->sat_substr->smr_filter ) )
196                 {
197                         fprintf( stderr, "%s: line %d: "
198                                 "substr index of attribute \"%s\" disallowed\n",
199                                 fname, lineno, attrs[i] );
200                         return LDAP_INAPPROPRIATE_MATCHING;
201                 }
202
203 #ifdef NEW_LOGGING
204                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
205                            "attr_index_config: index %s 0x%04x\n",
206                            ad->ad_cname->bv_val, mask ));
207 #else
208                 Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04x\n",
209                         ad->ad_cname->bv_val, mask, 0 ); 
210 #endif
211
212
213 #ifdef SLAPD_USE_AD
214                 a->ai_desc = ad;
215 #else
216                 a->ai_desc = ch_strdup( ad->ad_cname->bv_val );
217                 ad_free( ad, 1 );
218 #endif
219
220                 a->ai_indexmask = mask;
221
222                 rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
223                         (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
224
225                 if( rc ) {
226                         fprintf( stderr, "%s: line %d: duplicate index definition "
227                                 "for attr \"%s\" (ignored)\n",
228                             fname, lineno, attrs[i] );
229
230                         return LDAP_PARAM_ERROR;
231                 }
232         }
233
234         charray_free( attrs );
235         if ( indexes != NULL ) charray_free( indexes );
236
237         return LDAP_SUCCESS;
238 }
239
240
241 static void
242 ainfo_free( void *attr )
243 {
244         AttrInfo *ai = attr;
245 #ifdef SLAPD_USE_AD
246         ad_free( ai->ai_desc, 1 );
247 #else
248         free( ai->ai_desc );
249 #endif
250         free( ai );
251 }
252
253 void
254 bdb_attr_index_destroy( Avlnode *tree )
255 {
256         avl_free( tree, ainfo_free );
257 }
258