]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/attr.c
ITS#2368 - fix deleting key from range IDL
[openldap] / servers / slapd / back-ldbm / attr.c
1 /* attr.c - backend routines for dealing with attributes */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 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-ldbm.h"
17
18 /* for the cache of attribute information (which are indexed, etc.) */
19 typedef struct ldbm_attrinfo {
20         AttributeDescription *ai_desc; /* attribute description cn;lang-en */
21         slap_mask_t ai_indexmask;       /* how the attr is indexed      */
22 } AttrInfo;
23
24 static int
25 ainfo_type_cmp(
26         const void *v_desc,
27         const void *v_a
28 )
29 {
30         const AttributeDescription *desc = v_desc;
31         const AttrInfo             *a    = v_a;
32         return desc - a->ai_desc;
33 }
34
35 static int
36 ainfo_cmp(
37         const void      *v_a,
38         const void      *v_b
39 )
40 {
41         const AttrInfo *a = v_a, *b = v_b;
42         return a->ai_desc - b->ai_desc;
43 }
44
45 void
46 attr_mask(
47     struct ldbminfo     *li,
48     AttributeDescription *desc,
49     slap_mask_t *indexmask )
50 {
51         AttrInfo        *a;
52
53         a = avl_find( li->li_attrs, desc, ainfo_type_cmp );
54         
55         *indexmask = a != NULL ? a->ai_indexmask : 0;
56 }
57
58 int
59 attr_index_config(
60     struct ldbminfo     *li,
61     const char          *fname,
62     int                 lineno,
63     int                 argc,
64     char                **argv )
65 {
66         int rc;
67         int     i;
68         slap_mask_t mask;
69         char **attrs;
70         char **indexes = NULL;
71
72         attrs = ldap_str2charray( argv[0], "," );
73
74         if( attrs == NULL ) {
75                 fprintf( stderr, "%s: line %d: "
76                         "no attributes specified: %s\n",
77                         fname, lineno, argv[0] );
78                 return LDAP_PARAM_ERROR;
79         }
80
81         if ( argc > 1 ) {
82                 indexes = ldap_str2charray( argv[1], "," );
83
84                 if( indexes == NULL ) {
85                         fprintf( stderr, "%s: line %d: "
86                                 "no indexes specified: %s\n",
87                                 fname, lineno, argv[1] );
88                         return LDAP_PARAM_ERROR;
89                 }
90         }
91
92         if( indexes == NULL ) {
93                 mask = li->li_defaultmask;
94
95         } else {
96                 mask = 0;
97
98                 for ( i = 0; indexes[i] != NULL; i++ ) {
99                         slap_mask_t index;
100                         rc = slap_str2index( indexes[i], &index );
101
102                         if( rc != LDAP_SUCCESS ) {
103                                 fprintf( stderr, "%s: line %d: "
104                                         "index type \"%s\" undefined\n",
105                                         fname, lineno, indexes[i] );
106                                 return LDAP_PARAM_ERROR;
107                         }
108
109                         mask |= index;
110                 }
111         }
112
113     if( !mask ) {
114                 fprintf( stderr, "%s: line %d: "
115                         "no indexes selected\n",
116                         fname, lineno );
117                 return LDAP_PARAM_ERROR;
118         }
119
120         for ( i = 0; attrs[i] != NULL; i++ ) {
121                 AttrInfo        *a;
122                 AttributeDescription *ad;
123                 const char *text;
124
125                 if( strcasecmp( attrs[i], "default" ) == 0 ) {
126                         li->li_defaultmask = mask;
127                         continue;
128                 }
129
130                 a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
131
132                 ad = NULL;
133                 rc = slap_str2ad( attrs[i], &ad, &text );
134
135                 if( rc != LDAP_SUCCESS ) {
136                         fprintf( stderr, "%s: line %d: "
137                                 "index attribute \"%s\" undefined\n",
138                                 fname, lineno, attrs[i] );
139                         return rc;
140                 }
141
142                 if( slap_ad_is_binary( ad ) ) {
143                         fprintf( stderr, "%s: line %d: "
144                                 "index of attribute \"%s\" disallowed\n",
145                                 fname, lineno, attrs[i] );
146                         return LDAP_UNWILLING_TO_PERFORM;
147                 }
148
149                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
150                         ( ad->ad_type->sat_approx
151                                 && ad->ad_type->sat_approx->smr_indexer
152                                 && ad->ad_type->sat_approx->smr_filter )
153                         && ( ad->ad_type->sat_equality
154                                 && ad->ad_type->sat_equality->smr_indexer
155                                 && ad->ad_type->sat_equality->smr_filter ) ) )
156                 {
157                         fprintf( stderr, "%s: line %d: "
158                                 "approx index of attribute \"%s\" disallowed\n",
159                                 fname, lineno, attrs[i] );
160                         return LDAP_INAPPROPRIATE_MATCHING;
161                 }
162
163                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
164                         ad->ad_type->sat_equality
165                                 && ad->ad_type->sat_equality->smr_indexer
166                                 && ad->ad_type->sat_equality->smr_filter ) )
167                 {
168                         fprintf( stderr, "%s: line %d: "
169                                 "equality index of attribute \"%s\" disallowed\n",
170                                 fname, lineno, attrs[i] );
171                         return LDAP_INAPPROPRIATE_MATCHING;
172                 }
173
174                 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
175                         ad->ad_type->sat_substr
176                                 && ad->ad_type->sat_substr->smr_indexer
177                                 && ad->ad_type->sat_substr->smr_filter ) )
178                 {
179                         fprintf( stderr, "%s: line %d: "
180                                 "substr index of attribute \"%s\" disallowed\n",
181                                 fname, lineno, attrs[i] );
182                         return LDAP_INAPPROPRIATE_MATCHING;
183                 }
184
185 #ifdef NEW_LOGGING
186                 LDAP_LOG( BACK_LDBM, DETAIL1, 
187                         "attr_index_config: index %s 0x%04lx\n", 
188                         ad->ad_cname.bv_val, mask, 0 );
189 #else
190                 Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n",
191                         ad->ad_cname.bv_val, mask, 0 ); 
192 #endif
193
194
195                 a->ai_desc = ad;
196
197                 a->ai_indexmask = mask;
198
199                 rc = avl_insert( &li->li_attrs, (caddr_t) a,
200                                  ainfo_cmp, avl_dup_error );
201
202                 if( rc ) {
203                         fprintf( stderr, "%s: line %d: duplicate index definition "
204                                 "for attr \"%s\" (ignored)\n",
205                             fname, lineno, attrs[i] );
206
207                         return LDAP_PARAM_ERROR;
208                 }
209         }
210
211         ldap_charray_free( attrs );
212         if ( indexes != NULL ) ldap_charray_free( indexes );
213
214         return LDAP_SUCCESS;
215 }
216
217 void
218 attr_index_destroy( Avlnode *tree )
219 {
220         avl_free( tree, free );
221 }