1 /* attr.c - backend routines for dealing with attributes */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/attr.c,v 1.36.2.4 2008/05/27 20:26:12 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2008 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 /* Find the ad, return -1 if not found,
29 * set point for insertion if ins is non-NULL
32 bdb_attr_slot( struct bdb_info
*bdb
, AttributeDescription
*ad
, unsigned *ins
)
34 unsigned base
= 0, cursor
= 0;
35 unsigned n
= bdb
->bi_nattrs
;
40 cursor
= base
+ pivot
;
42 val
= SLAP_PTRCMP( ad
, bdb
->bi_attrs
[cursor
]->ai_desc
);
45 } else if ( val
> 0 ) {
61 ainfo_insert( struct bdb_info
*bdb
, AttrInfo
*a
)
64 int i
= bdb_attr_slot( bdb
, a
->ai_desc
, &x
);
70 bdb
->bi_attrs
= ch_realloc( bdb
->bi_attrs
, ( bdb
->bi_nattrs
+1 ) *
71 sizeof( AttrInfo
* ));
72 if ( x
< bdb
->bi_nattrs
)
73 AC_MEMCPY( &bdb
->bi_attrs
[x
+1], &bdb
->bi_attrs
[x
],
74 ( bdb
->bi_nattrs
- x
) * sizeof( AttrInfo
*));
83 AttributeDescription
*desc
)
85 int i
= bdb_attr_slot( bdb
, desc
, NULL
);
86 return i
< 0 ? NULL
: bdb
->bi_attrs
[i
];
90 bdb_attr_index_config(
101 char **indexes
= NULL
;
103 attrs
= ldap_str2charray( argv
[0], "," );
105 if( attrs
== NULL
) {
106 fprintf( stderr
, "%s: line %d: "
107 "no attributes specified: %s\n",
108 fname
, lineno
, argv
[0] );
109 return LDAP_PARAM_ERROR
;
113 indexes
= ldap_str2charray( argv
[1], "," );
115 if( indexes
== NULL
) {
116 fprintf( stderr
, "%s: line %d: "
117 "no indexes specified: %s\n",
118 fname
, lineno
, argv
[1] );
119 rc
= LDAP_PARAM_ERROR
;
124 if( indexes
== NULL
) {
125 mask
= bdb
->bi_defaultmask
;
130 for ( i
= 0; indexes
[i
] != NULL
; i
++ ) {
132 rc
= slap_str2index( indexes
[i
], &index
);
134 if( rc
!= LDAP_SUCCESS
) {
135 fprintf( stderr
, "%s: line %d: "
136 "index type \"%s\" undefined\n",
137 fname
, lineno
, indexes
[i
] );
138 rc
= LDAP_PARAM_ERROR
;
147 fprintf( stderr
, "%s: line %d: "
148 "no indexes selected\n",
150 rc
= LDAP_PARAM_ERROR
;
154 for ( i
= 0; attrs
[i
] != NULL
; i
++ ) {
156 AttributeDescription
*ad
;
158 #ifdef LDAP_COMP_MATCH
159 ComponentReference
* cr
= NULL
;
160 AttrInfo
*a_cr
= NULL
;
163 if( strcasecmp( attrs
[i
], "default" ) == 0 ) {
164 bdb
->bi_defaultmask
|= mask
;
168 #ifdef LDAP_COMP_MATCH
169 if ( is_component_reference( attrs
[i
] ) ) {
170 rc
= extract_component_reference( attrs
[i
], &cr
);
171 if ( rc
!= LDAP_SUCCESS
) {
172 fprintf( stderr
, "%s: line %d: "
173 "index component reference\"%s\" undefined\n",
174 fname
, lineno
, attrs
[i
] );
177 cr
->cr_indexmask
= mask
;
179 * After extracting a component reference
180 * only the name of a attribute will be remaining
187 rc
= slap_str2ad( attrs
[i
], &ad
, &text
);
189 if( rc
!= LDAP_SUCCESS
) {
190 fprintf( stderr
, "%s: line %d: "
191 "index attribute \"%s\" undefined\n",
192 fname
, lineno
, attrs
[i
] );
196 if( slap_ad_is_binary( ad
) ) {
197 fprintf( stderr
, "%s: line %d: "
198 "index of attribute \"%s\" disallowed\n",
199 fname
, lineno
, attrs
[i
] );
200 rc
= LDAP_UNWILLING_TO_PERFORM
;
204 if( IS_SLAP_INDEX( mask
, SLAP_INDEX_APPROX
) && !(
205 ad
->ad_type
->sat_approx
206 && ad
->ad_type
->sat_approx
->smr_indexer
207 && ad
->ad_type
->sat_approx
->smr_filter
) )
209 fprintf( stderr
, "%s: line %d: "
210 "approx index of attribute \"%s\" disallowed\n",
211 fname
, lineno
, attrs
[i
] );
212 rc
= LDAP_INAPPROPRIATE_MATCHING
;
216 if( IS_SLAP_INDEX( mask
, SLAP_INDEX_EQUALITY
) && !(
217 ad
->ad_type
->sat_equality
218 && ad
->ad_type
->sat_equality
->smr_indexer
219 && ad
->ad_type
->sat_equality
->smr_filter
) )
221 fprintf( stderr
, "%s: line %d: "
222 "equality index of attribute \"%s\" disallowed\n",
223 fname
, lineno
, attrs
[i
] );
224 rc
= LDAP_INAPPROPRIATE_MATCHING
;
228 if( IS_SLAP_INDEX( mask
, SLAP_INDEX_SUBSTR
) && !(
229 ad
->ad_type
->sat_substr
230 && ad
->ad_type
->sat_substr
->smr_indexer
231 && ad
->ad_type
->sat_substr
->smr_filter
) )
233 fprintf( stderr
, "%s: line %d: "
234 "substr index of attribute \"%s\" disallowed\n",
235 fname
, lineno
, attrs
[i
] );
236 rc
= LDAP_INAPPROPRIATE_MATCHING
;
240 Debug( LDAP_DEBUG_CONFIG
, "index %s 0x%04lx\n",
241 ad
->ad_cname
.bv_val
, mask
, 0 );
243 a
= (AttrInfo
*) ch_malloc( sizeof(AttrInfo
) );
245 #ifdef LDAP_COMP_MATCH
250 if ( bdb
->bi_flags
& BDB_IS_OPEN
) {
252 a
->ai_newmask
= mask
;
254 a
->ai_indexmask
= mask
;
258 #ifdef LDAP_COMP_MATCH
260 a_cr
= bdb_attr_mask( bdb
, ad
);
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 rc
= LDAP_PARAM_ERROR
;
275 rc
= insert_component_reference( cr
, &a
->ai_cr
);
276 if ( rc
!= LDAP_SUCCESS
) {
277 fprintf( stderr
, " error during inserting component reference in %s ", attrs
[i
]);
278 rc
= LDAP_PARAM_ERROR
;
284 rc
= ainfo_insert( bdb
, a
);
286 if ( bdb
->bi_flags
& BDB_IS_OPEN
) {
287 AttrInfo
*b
= bdb_attr_mask( bdb
, ad
);
288 /* If we were editing this attr, reset it */
289 b
->ai_indexmask
&= ~BDB_INDEX_DELETING
;
290 /* If this is leftover from a previous add, commit it */
292 b
->ai_indexmask
= b
->ai_newmask
;
293 b
->ai_newmask
= a
->ai_newmask
;
299 "%s: line %d: duplicate index definition for attr \"%s\".\n",
300 fname
, lineno
, attrs
[i
] );
302 rc
= LDAP_PARAM_ERROR
;
308 ldap_charray_free( attrs
);
309 if ( indexes
!= NULL
) ldap_charray_free( indexes
);
315 bdb_attr_index_unparser( void *v1
, void *v2
)
322 slap_index2bvlen( ai
->ai_indexmask
, &bv
);
324 bv
.bv_len
+= ai
->ai_desc
->ad_cname
.bv_len
+ 1;
325 ptr
= ch_malloc( bv
.bv_len
+1 );
326 bv
.bv_val
= lutil_strcopy( ptr
, ai
->ai_desc
->ad_cname
.bv_val
);
328 slap_index2bv( ai
->ai_indexmask
, &bv
);
330 ber_bvarray_add( bva
, &bv
);
335 static AttributeDescription addef
= { NULL
, NULL
, BER_BVC("default") };
336 static AttrInfo aidef
= { &addef
};
339 bdb_attr_index_unparse( struct bdb_info
*bdb
, BerVarray
*bva
)
343 if ( bdb
->bi_defaultmask
) {
344 aidef
.ai_indexmask
= bdb
->bi_defaultmask
;
345 bdb_attr_index_unparser( &aidef
, bva
);
347 for ( i
=0; i
<bdb
->bi_nattrs
; i
++ )
348 bdb_attr_index_unparser( bdb
->bi_attrs
[i
], bva
);
352 bdb_attr_info_free( AttrInfo
*ai
)
354 #ifdef LDAP_COMP_MATCH
361 bdb_attr_index_destroy( struct bdb_info
*bdb
)
365 for ( i
=0; i
<bdb
->bi_nattrs
; i
++ )
366 bdb_attr_info_free( bdb
->bi_attrs
[i
] );
368 free( bdb
->bi_attrs
);
371 void bdb_attr_index_free( struct bdb_info
*bdb
, AttributeDescription
*ad
)
375 i
= bdb_attr_slot( bdb
, ad
, NULL
);
377 bdb_attr_info_free( bdb
->bi_attrs
[i
] );
379 for (; i
<bdb
->bi_nattrs
; i
++)
380 bdb
->bi_attrs
[i
] = bdb
->bi_attrs
[i
+1];
384 void bdb_attr_flush( struct bdb_info
*bdb
)
388 for ( i
=0; i
<bdb
->bi_nattrs
; i
++ ) {
389 if ( bdb
->bi_attrs
[i
]->ai_indexmask
& BDB_INDEX_DELETING
) {
391 bdb_attr_info_free( bdb
->bi_attrs
[i
] );
393 for (j
=i
; j
<bdb
->bi_nattrs
; j
++)
394 bdb
->bi_attrs
[j
] = bdb
->bi_attrs
[j
+1];