]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
slapi_op_type_to_string/slapi_op_get_type implementation
[openldap] / servers / slapd / slapi / slapi_utils.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2002-2005 The OpenLDAP Foundation.
5  * Portions Copyright 1997,2002-2003 IBM Corporation.
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 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by IBM Corporation for use in
18  * IBM products and subsequently ported to OpenLDAP Software by
19  * Steve Omrani.  Additional significant contributors include:
20  *   Luke Howard
21  */
22
23 #include "portable.h"
24
25 #include <ac/string.h>
26 #include <ac/stdarg.h>
27 #include <ac/ctype.h>
28 #include <ac/unistd.h>
29
30 #include <slap.h>
31 #include <slapi.h>
32
33 #include <netdb.h>
34
35 #ifdef LDAP_SLAPI
36
37 /*
38  * server start time (should we use a struct timeval also in slapd?
39  */
40 static struct                   timeval base_time;
41 ldap_pvt_thread_mutex_t         slapi_hn_mutex;
42 ldap_pvt_thread_mutex_t         slapi_time_mutex;
43
44 struct slapi_mutex {
45         ldap_pvt_thread_mutex_t mutex;
46 };
47
48 struct slapi_condvar {
49         ldap_pvt_thread_cond_t cond;
50         ldap_pvt_thread_mutex_t mutex;
51 };
52
53 static int checkBVString(const struct berval *bv)
54 {
55         int i;
56
57         for ( i = 0; i < bv->bv_len; i++ ) {
58                 if ( bv->bv_val[i] == '\0' )
59                         return 0;
60         }
61         if ( bv->bv_val[i] != '\0' )
62                 return 0;
63
64         return 1;
65 }
66
67 /*
68  * This function converts an array of pointers to berval objects to
69  * an array of berval objects.
70  */
71
72 int
73 bvptr2obj(
74         struct berval   **bvptr, 
75         BerVarray       *bvobj )
76 {
77         int             rc = LDAP_SUCCESS;
78         int             i;
79         BerVarray       tmpberval;
80
81         if ( bvptr == NULL || *bvptr == NULL ) {
82                 return LDAP_OTHER;
83         }
84
85         for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
86                 ; /* EMPTY */
87         }
88
89         tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
90         if ( tmpberval == NULL ) {
91                 return LDAP_NO_MEMORY;
92         } 
93
94         for ( i = 0; bvptr[i] != NULL; i++ ) {
95                 tmpberval[i].bv_val = bvptr[i]->bv_val;
96                 tmpberval[i].bv_len = bvptr[i]->bv_len;
97         }
98         tmpberval[i].bv_val = NULL;
99         tmpberval[i].bv_len = 0;
100
101         if ( rc == LDAP_SUCCESS ) {
102                 *bvobj = tmpberval;
103         }
104
105         return rc;
106 }
107
108 Slapi_Entry *
109 slapi_str2entry(
110         char            *s, 
111         int             flags )
112 {
113         Slapi_Entry     *e = NULL;
114         char            *pTmpS;
115
116         pTmpS = slapi_ch_strdup( s );
117         if ( pTmpS != NULL ) {
118                 e = str2entry( pTmpS ); 
119                 slapi_ch_free( (void **)&pTmpS );
120         }
121
122         return e;
123 }
124
125 char *
126 slapi_entry2str(
127         Slapi_Entry     *e, 
128         int             *len ) 
129 {
130         char            *ret;
131
132         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
133         ret = entry2str( e, len );
134         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
135
136         return ret;
137 }
138
139 char *
140 slapi_entry_get_dn( Slapi_Entry *e ) 
141 {
142         return e->e_name.bv_val;
143 }
144
145 int
146 slapi_x_entry_get_id( Slapi_Entry *e )
147 {
148         return e->e_id;
149 }
150
151 void 
152 slapi_entry_set_dn(
153         Slapi_Entry     *e, 
154         char            *ldn )
155 {
156         struct berval   dn = BER_BVNULL;
157
158         dn.bv_val = ldn;
159         dn.bv_len = strlen( ldn );
160
161         dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname, NULL );
162 }
163
164 Slapi_Entry *
165 slapi_entry_dup( Slapi_Entry *e ) 
166 {
167         return entry_dup( e );
168 }
169
170 int 
171 slapi_entry_attr_delete(
172         Slapi_Entry     *e,             
173         char            *type ) 
174 {
175         AttributeDescription    *ad = NULL;
176         const char              *text;
177
178         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
179                 return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
180         }
181
182         if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
183                 return 0;       /* attribute is deleted */
184         } else {
185                 return -1;      /* something went wrong */
186         }
187 }
188
189 Slapi_Entry *
190 slapi_entry_alloc( void ) 
191 {
192         return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
193 }
194
195 void 
196 slapi_entry_free( Slapi_Entry *e ) 
197 {
198         if ( e != NULL )
199                 entry_free( e );
200 }
201
202 int 
203 slapi_entry_attr_merge(
204         Slapi_Entry     *e, 
205         char            *type, 
206         struct berval   **vals ) 
207 {
208         AttributeDescription    *ad = NULL;
209         const char              *text;
210         BerVarray               bv;
211         int                     rc;
212
213         rc = bvptr2obj( vals, &bv );
214         if ( rc != LDAP_SUCCESS ) {
215                 return -1;
216         }
217         
218         rc = slap_str2ad( type, &ad, &text );
219         if ( rc != LDAP_SUCCESS ) {
220                 return -1;
221         }
222         
223         rc = attr_merge_normalize_one( e, ad, bv, NULL );
224         ch_free( bv );
225
226         return rc;
227 }
228
229 int
230 slapi_entry_attr_find(
231         Slapi_Entry     *e, 
232         char            *type, 
233         Slapi_Attr      **attr ) 
234 {
235         AttributeDescription    *ad = NULL;
236         const char              *text;
237         int                     rc;
238
239         rc = slap_str2ad( type, &ad, &text );
240         if ( rc != LDAP_SUCCESS ) {
241                 return -1;
242         }
243
244         *attr = attr_find( e->e_attrs, ad );
245         if ( *attr == NULL ) {
246                 return -1;
247         }
248
249         return 0;
250 }
251
252 char *
253 slapi_entry_attr_get_charptr( const Slapi_Entry *e, const char *type )
254 {
255         AttributeDescription *ad = NULL;
256         const char *text;
257         int rc;
258         Attribute *attr;
259
260         rc = slap_str2ad( type, &ad, &text );
261         if ( rc != LDAP_SUCCESS ) {
262                 return NULL;
263         }
264
265         attr = attr_find( e->e_attrs, ad );
266         if ( attr == NULL ) {
267                 return NULL;
268         }
269
270         if ( attr->a_vals != NULL && attr->a_vals[0].bv_len != 0 ) {
271                 const char *p;
272
273                 p = slapi_value_get_string( &attr->a_vals[0] );
274                 if ( p != NULL ) {
275                         return slapi_ch_strdup( (char *)p );
276                 }
277         }
278
279         return NULL;
280 }
281
282 int
283 slapi_entry_attr_get_int( const Slapi_Entry *e, const char *type )
284 {
285         AttributeDescription *ad = NULL;
286         const char *text;
287         int rc;
288         Attribute *attr;
289
290         rc = slap_str2ad( type, &ad, &text );
291         if ( rc != LDAP_SUCCESS ) {
292                 return 0;
293         }
294
295         attr = attr_find( e->e_attrs, ad );
296         if ( attr == NULL ) {
297                 return 0;
298         }
299
300         return slapi_value_get_int( attr->a_vals );
301 }
302
303 long
304 slapi_entry_attr_get_long( const Slapi_Entry *e, const char *type )
305 {
306         AttributeDescription *ad = NULL;
307         const char *text;
308         int rc;
309         Attribute *attr;
310
311         rc = slap_str2ad( type, &ad, &text );
312         if ( rc != LDAP_SUCCESS ) {
313                 return 0;
314         }
315
316         attr = attr_find( e->e_attrs, ad );
317         if ( attr == NULL ) {
318                 return 0;
319         }
320
321         return slapi_value_get_long( attr->a_vals );
322 }
323
324 unsigned int
325 slapi_entry_attr_get_uint( const Slapi_Entry *e, const char *type )
326 {
327         AttributeDescription *ad = NULL;
328         const char *text;
329         int rc;
330         Attribute *attr;
331
332         rc = slap_str2ad( type, &ad, &text );
333         if ( rc != LDAP_SUCCESS ) {
334                 return 0;
335         }
336
337         attr = attr_find( e->e_attrs, ad );
338         if ( attr == NULL ) {
339                 return 0;
340         }
341
342         return slapi_value_get_uint( attr->a_vals );
343 }
344
345 unsigned long
346 slapi_entry_attr_get_ulong( const Slapi_Entry *e, const char *type )
347 {
348         AttributeDescription *ad = NULL;
349         const char *text;
350         int rc;
351         Attribute *attr;
352
353         rc = slap_str2ad( type, &ad, &text );
354         if ( rc != LDAP_SUCCESS ) {
355                 return 0;
356         }
357
358         attr = attr_find( e->e_attrs, ad );
359         if ( attr == NULL ) {
360                 return 0;
361         }
362
363         return slapi_value_get_ulong( attr->a_vals );
364 }
365
366 int
367 slapi_entry_attr_hasvalue( Slapi_Entry *e, const char *type, const char *value )
368 {
369         struct berval bv;
370         AttributeDescription *ad = NULL;
371         const char *text;
372         int rc;
373         Attribute *attr;
374         
375         rc = slap_str2ad( type, &ad, &text );
376         if ( rc != LDAP_SUCCESS ) {
377                 return 0;
378         }
379
380         attr = attr_find( e->e_attrs, ad );
381         if ( attr == NULL ) {
382                 return 0;
383         }
384
385         bv.bv_val = (char *)value;
386         bv.bv_len = strlen( value );
387
388         return ( slapi_attr_value_find( attr, &bv ) != -1 );
389 }
390
391 void
392 slapi_entry_attr_set_charptr(Slapi_Entry* e, const char *type, const char *value)
393 {
394         AttributeDescription    *ad = NULL;
395         const char              *text;
396         int                     rc;
397         struct berval           bv;
398         
399         rc = slap_str2ad( type, &ad, &text );
400         if ( rc != LDAP_SUCCESS ) {
401                 return;
402         }
403         
404         attr_delete ( &e->e_attrs, ad );
405         if ( value != NULL ) {
406                 bv.bv_val = (char *)value;
407                 bv.bv_len = strlen(value);
408                 attr_merge_normalize_one( e, ad, &bv, NULL );
409         }
410 }
411
412 void
413 slapi_entry_attr_set_int( Slapi_Entry* e, const char *type, int l)
414 {
415         char buf[64];
416
417         snprintf( buf, sizeof( buf ), "%d", l );
418         slapi_entry_attr_set_charptr( e, type, buf );
419 }
420
421 void
422 slapi_entry_attr_set_uint( Slapi_Entry* e, const char *type, unsigned int l)
423 {
424         char buf[64];
425
426         snprintf( buf, sizeof( buf ), "%u", l );
427         slapi_entry_attr_set_charptr( e, type, buf );
428 }
429
430 void
431 slapi_entry_attr_set_long(Slapi_Entry* e, const char *type, long l)
432 {
433         char buf[64];
434
435         snprintf( buf, sizeof( buf ), "%ld", l );
436         slapi_entry_attr_set_charptr( e, type, buf );
437 }
438
439 void
440 slapi_entry_attr_set_ulong(Slapi_Entry* e, const char *type, unsigned long l)
441 {
442         char buf[64];
443
444         snprintf( buf, sizeof( buf ), "%lu", l );
445         slapi_entry_attr_set_charptr( e, type, buf );
446 }
447
448 int
449 slapi_is_rootdse( const char *dn )
450 {
451         return ( dn == NULL || dn[0] == '\0' );
452 }
453
454 int
455 slapi_entry_has_children( const Slapi_Entry *e )
456 {
457         Slapi_PBlock *pb;
458         int hasSubordinates = 0;
459
460         pb = slapi_pblock_new();
461         slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH );
462
463         slapi_pblock_set( pb, SLAPI_TARGET_DN, slapi_entry_get_dn( (Entry *)e ) );
464
465         pb->pb_op->o_bd = select_backend( (struct berval *)&e->e_nname, 0, 0 );
466         if ( pb->pb_op->o_bd != NULL ) {
467                 pb->pb_op->o_bd->be_has_subordinates( pb->pb_op, (Entry *)e, &hasSubordinates );
468         }
469
470         slapi_pblock_destroy( pb );
471
472         return ( hasSubordinates == LDAP_COMPARE_TRUE );
473 }
474
475 /*
476  * Return approximate size of the entry rounded to the nearest
477  * 1K. Only the size of the attribute values are counted in the
478  * Sun implementation.
479  *
480  * http://docs.sun.com/source/816-6701-10/funcref.html#1017388
481  */
482 size_t slapi_entry_size(Slapi_Entry *e)
483 {
484         size_t size;
485         Attribute *a;
486         int i;
487
488         for ( size = 0, a = e->e_attrs; a != NULL; a = a->a_next ) {
489                 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
490                         size += a->a_vals[i].bv_len + 1;
491                 }
492         }
493
494         size += 1023;
495         size -= (size % 1024);
496
497         return size;
498 }
499
500 /*
501  * Add values to entry.
502  *
503  * Returns:
504  *      LDAP_SUCCESS                    Values added to entry
505  *      LDAP_TYPE_OR_VALUE_EXISTS       One or more values exist in entry already
506  *      LDAP_CONSTRAINT_VIOLATION       Any other error (odd, but it's the spec)
507  */
508 int
509 slapi_entry_add_values( Slapi_Entry *e, const char *type, struct berval **vals )
510 {
511         Modification            mod;
512         const char              *text;
513         int                     rc;
514         char                    textbuf[SLAP_TEXT_BUFLEN];
515
516         mod.sm_op = LDAP_MOD_ADD;
517         mod.sm_flags = 0;
518         mod.sm_desc = NULL;
519         mod.sm_type.bv_val = (char *)type;
520         mod.sm_type.bv_len = strlen( type );
521
522         rc = slap_str2ad( type, &mod.sm_desc, &text );
523         if ( rc != LDAP_SUCCESS ) {
524                 return rc;
525         }
526
527         if ( vals == NULL ) {
528                 /* Apparently vals can be NULL
529                  * FIXME: sm_values = NULL ? */
530                 mod.sm_values = (BerVarray)ch_malloc( sizeof(struct berval) );
531                 mod.sm_values->bv_val = NULL;
532
533         } else {
534                 rc = bvptr2obj( vals, &mod.sm_values );
535                 if ( rc != LDAP_SUCCESS ) {
536                         return LDAP_CONSTRAINT_VIOLATION;
537                 }
538         }
539         mod.sm_nvalues = NULL;
540
541         rc = modify_add_values( e, &mod, 0, &text, textbuf, sizeof(textbuf) );
542
543         slapi_ch_free( (void **)&mod.sm_values );
544
545         return (rc == LDAP_SUCCESS) ? LDAP_SUCCESS : LDAP_CONSTRAINT_VIOLATION;
546 }
547
548 int
549 slapi_entry_add_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
550 {
551         return slapi_entry_add_values( e, type, vals );
552 }
553
554 int
555 slapi_entry_add_valueset(Slapi_Entry *e, const char *type, Slapi_ValueSet *vs)
556 {
557         AttributeDescription    *ad = NULL;
558         const char              *text;
559         int                     rc;
560         
561         rc = slap_str2ad( type, &ad, &text );
562         if ( rc != LDAP_SUCCESS ) {
563                 return -1;
564         }
565
566         return attr_merge_normalize( e, ad, *vs, NULL );
567 }
568
569 int
570 slapi_entry_delete_values( Slapi_Entry *e, const char *type, struct berval **vals )
571 {
572         Modification            mod;
573         const char              *text;
574         int                     rc;
575         char                    textbuf[SLAP_TEXT_BUFLEN];
576
577         mod.sm_op = LDAP_MOD_DELETE;
578         mod.sm_flags = 0;
579         mod.sm_desc = NULL;
580         mod.sm_type.bv_val = (char *)type;
581         mod.sm_type.bv_len = strlen( type );
582
583         if ( vals == NULL ) {
584                 /* If vals is NULL, this is a NOOP. */
585                 return LDAP_SUCCESS;
586         }
587         
588         rc = slap_str2ad( type, &mod.sm_desc, &text );
589         if ( rc != LDAP_SUCCESS ) {
590                 return rc;
591         }
592
593         if ( vals[0] == NULL ) {
594                 /* SLAPI doco says LDApb_opERATIONS_ERROR but LDAP_OTHER is better */
595                 return attr_delete( &e->e_attrs, mod.sm_desc ) ? LDAP_OTHER : LDAP_SUCCESS;
596         }
597
598         rc = bvptr2obj( vals, &mod.sm_values );
599         if ( rc != LDAP_SUCCESS ) {
600                 return LDAP_CONSTRAINT_VIOLATION;
601         }
602         mod.sm_nvalues = NULL;
603
604         rc = modify_delete_values( e, &mod, 0, &text, textbuf, sizeof(textbuf) );
605
606         slapi_ch_free( (void **)&mod.sm_values );
607
608         return rc;
609 }
610
611 int
612 slapi_entry_delete_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
613 {
614         return slapi_entry_delete_values( e, type, vals );
615 }
616
617 int
618 slapi_entry_merge_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
619 {
620         return slapi_entry_attr_merge( e, (char *)type, vals );
621 }
622
623 int
624 slapi_entry_add_value(Slapi_Entry *e, const char *type, const Slapi_Value *value)
625 {
626         AttributeDescription    *ad = NULL;
627         int                     rc;
628         const char              *text;
629
630         rc = slap_str2ad( type, &ad, &text );
631         if ( rc != LDAP_SUCCESS ) {
632                 return -1;
633         }
634
635         rc = attr_merge_normalize_one( e, ad, (Slapi_Value *)value, NULL );
636         if ( rc != LDAP_SUCCESS ) {
637                 return -1;
638         }
639
640         return 0;
641 }
642
643 int
644 slapi_entry_add_string(Slapi_Entry *e, const char *type, const char *value)
645 {
646         Slapi_Value val;
647
648         val.bv_val = (char *)value;
649         val.bv_len = strlen( value );
650
651         return slapi_entry_add_value( e, type, &val );
652 }
653
654 int
655 slapi_entry_delete_string(Slapi_Entry *e, const char *type, const char *value)
656 {
657         Slapi_Value *vals[2];
658         Slapi_Value val;
659
660         val.bv_val = (char *)value;
661         val.bv_len = strlen( value );
662         vals[0] = &val;
663         vals[1] = NULL;
664
665         return slapi_entry_delete_values_sv( e, type, vals );   
666 }
667
668 int
669 slapi_entry_attr_merge_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
670 {
671         return slapi_entry_attr_merge( e, (char *)type, vals );
672 }
673
674 int
675 slapi_entry_first_attr( const Slapi_Entry *e, Slapi_Attr **attr )
676 {
677         if ( e == NULL ) {
678                 return -1;
679         }
680
681         *attr = e->e_attrs;
682
683         return ( *attr != NULL ) ? 0 : -1;
684 }
685
686 int
687 slapi_entry_next_attr( const Slapi_Entry *e, Slapi_Attr *prevattr, Slapi_Attr **attr )
688 {
689         if ( e == NULL ) {
690                 return -1;
691         }
692
693         if ( prevattr == NULL ) {
694                 return -1;
695         }
696
697         *attr = prevattr->a_next;
698
699         return ( *attr != NULL ) ? 0 : -1;
700 }
701
702 int
703 slapi_entry_attr_replace_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
704 {
705         AttributeDescription *ad = NULL;
706         const char *text;
707         int rc;
708         BerVarray bv;
709         
710         rc = slap_str2ad( type, &ad, &text );
711         if ( rc != LDAP_SUCCESS ) {
712                 return 0;
713         }
714
715         attr_delete( &e->e_attrs, ad );
716
717         rc = bvptr2obj( vals, &bv );
718         if ( rc != LDAP_SUCCESS ) {
719                 return -1;
720         }
721         
722         rc = attr_merge_normalize( e, ad, bv, NULL );
723         slapi_ch_free( (void **)&bv );
724         if ( rc != LDAP_SUCCESS ) {
725                 return -1;
726         }
727         
728         return 0;
729 }
730
731 /* 
732  * FIXME -- The caller must free the allocated memory. 
733  * In Netscape they do not have to.
734  */
735 int 
736 slapi_attr_get_values(
737         Slapi_Attr      *attr, 
738         struct berval   ***vals ) 
739 {
740         int             i, j;
741         struct berval   **bv;
742
743         if ( attr == NULL ) {
744                 return 1;
745         }
746
747         for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
748                 ; /* EMPTY */
749         }
750
751         bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
752         for ( j = 0; j < i; j++ ) {
753                 bv[j] = ber_dupbv( NULL, &attr->a_vals[j] );
754         }
755         bv[j] = NULL;
756         
757         *vals = (struct berval **)bv;
758
759         return 0;
760 }
761
762 char *
763 slapi_dn_normalize( char *dn ) 
764 {
765         struct berval   bdn;
766         struct berval   pdn;
767
768         assert( dn != NULL );
769         
770         bdn.bv_val = dn;
771         bdn.bv_len = strlen( dn );
772
773         if ( dnPretty( NULL, &bdn, &pdn, NULL ) != LDAP_SUCCESS ) {
774                 return NULL;
775         }
776
777         return pdn.bv_val;
778 }
779
780 char *
781 slapi_dn_normalize_case( char *dn ) 
782 {
783         struct berval   bdn;
784         struct berval   ndn;
785
786         assert( dn != NULL );
787         
788         bdn.bv_val = dn;
789         bdn.bv_len = strlen( dn );
790
791         if ( dnNormalize( 0, NULL, NULL, &bdn, &ndn, NULL ) != LDAP_SUCCESS ) {
792                 return NULL;
793         }
794
795         return ndn.bv_val;
796 }
797
798 int 
799 slapi_dn_issuffix(
800         char            *dn, 
801         char            *suffix )
802 {
803         struct berval   bdn, ndn;
804         struct berval   bsuffix, nsuffix;
805         int rc;
806
807         assert( dn != NULL );
808         assert( suffix != NULL );
809
810         bdn.bv_val = dn;
811         bdn.bv_len = strlen( dn );
812
813         bsuffix.bv_val = suffix;
814         bsuffix.bv_len = strlen( suffix );
815
816         if ( dnNormalize( 0, NULL, NULL, &bdn, &ndn, NULL ) != LDAP_SUCCESS ) {
817                 return 0;
818         }
819
820         if ( dnNormalize( 0, NULL, NULL, &bsuffix, &nsuffix, NULL )
821                 != LDAP_SUCCESS )
822         {
823                 slapi_ch_free( (void **)&ndn.bv_val );
824                 return 0;
825         }
826
827         rc = dnIsSuffix( &ndn, &nsuffix );
828
829         slapi_ch_free( (void **)&ndn.bv_val );
830         slapi_ch_free( (void **)&nsuffix.bv_val );
831
832         return rc;
833 }
834
835 int
836 slapi_dn_isparent(
837         const char      *parentdn,
838         const char      *childdn )
839 {
840         struct berval   assertedParentDN, normalizedAssertedParentDN;
841         struct berval   childDN, normalizedChildDN;
842         struct berval   normalizedParentDN;
843         int             match;
844
845         assert( parentdn != NULL );
846         assert( childdn != NULL );
847
848         assertedParentDN.bv_val = (char *)parentdn;
849         assertedParentDN.bv_len = strlen( parentdn );
850
851         if ( dnNormalize( 0, NULL, NULL, &assertedParentDN,
852                 &normalizedAssertedParentDN, NULL ) != LDAP_SUCCESS )
853         {
854                 return 0;
855         }
856
857         childDN.bv_val = (char *)childdn;
858         childDN.bv_len = strlen( childdn );
859
860         if ( dnNormalize( 0, NULL, NULL, &childDN,
861                 &normalizedChildDN, NULL ) != LDAP_SUCCESS )
862         {
863                 slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
864                 return 0;
865         }
866
867         dnParent( &normalizedChildDN, &normalizedParentDN );
868
869         if ( dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
870                 &normalizedParentDN, (void *)&normalizedAssertedParentDN ) != LDAP_SUCCESS )
871         {
872                 match = -1;
873         }
874
875         slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
876         slapi_ch_free( (void **)&normalizedChildDN.bv_val );
877
878         return ( match == 0 );
879 }
880
881 /*
882  * Returns DN of the parent entry, or NULL if the DN is
883  * an empty string or NULL, or has no parent.
884  */
885 char *
886 slapi_dn_parent( const char *_dn )
887 {
888         struct berval   dn, prettyDN;
889         struct berval   parentDN;
890
891         if ( _dn == NULL ) {
892                 return NULL;
893         }
894
895         dn.bv_val = (char *)_dn;
896         dn.bv_len = strlen( _dn );
897
898         if ( dn.bv_len == 0 ) {
899                 return NULL;
900         }
901
902         if ( dnPretty( NULL, &dn, &prettyDN, NULL ) != LDAP_SUCCESS ) {
903                 return NULL;
904         }
905
906         dnParent( &prettyDN, &parentDN ); /* in-place */
907
908         slapi_ch_free( (void **)&prettyDN.bv_val );
909
910         if ( parentDN.bv_len == 0 ) {
911                 return NULL;
912         }
913
914         return slapi_ch_strdup( parentDN.bv_val );
915 }
916
917 /*
918  * Returns DN of the parent entry; or NULL if the DN is
919  * an empty string, if the DN has no parent, or if the
920  * DN is the suffix of the backend database
921  */
922 char *slapi_dn_beparent( Slapi_PBlock *pb, const char *_dn )
923 {
924         Backend         *be;
925         struct berval   dn, prettyDN;
926         struct berval   normalizedDN, parentDN;
927
928         if ( pb == NULL || pb->pb_op == NULL )
929                 return NULL;
930
931         be = pb->pb_op->o_bd;
932
933         dn.bv_val = (char *)_dn;
934         dn.bv_len = strlen( _dn );
935
936         if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
937                 return NULL;
938         }
939
940         if ( be != NULL && be_issuffix( be, &normalizedDN ) ) {
941                 slapi_ch_free( (void **)&prettyDN.bv_val );
942                 slapi_ch_free( (void **)&normalizedDN.bv_val );
943                 return NULL;
944         }
945
946         dnParent( &prettyDN, &parentDN );
947
948         slapi_ch_free( (void **)&prettyDN.bv_val );
949         slapi_ch_free( (void **)&normalizedDN.bv_val );
950
951         if ( parentDN.bv_len == 0 ) {
952                 return NULL;
953         }
954
955         return slapi_ch_strdup( parentDN.bv_val );
956 }
957
958 char *
959 slapi_dn_ignore_case( char *dn )
960 {       
961         return slapi_dn_normalize_case( dn );
962 }
963
964 char *
965 slapi_ch_malloc( unsigned long size ) 
966 {
967         return ch_malloc( size );       
968 }
969
970 void 
971 slapi_ch_free( void **ptr ) 
972 {
973         if ( ptr == NULL || *ptr == NULL )
974                 return;
975         ch_free( *ptr );
976         *ptr = NULL;
977 }
978
979 void 
980 slapi_ch_free_string( char **ptr ) 
981 {
982         slapi_ch_free( (void **)ptr );
983 }
984
985 void
986 slapi_ch_array_free( char **arrayp )
987 {
988         char **p;
989
990         if ( arrayp != NULL ) {
991                 for ( p = arrayp; *p != NULL; p++ ) {
992                         slapi_ch_free( (void **)p );
993                 }
994                 slapi_ch_free( (void **)&arrayp );
995         }
996 }
997
998 struct berval *
999 slapi_ch_bvdup(const struct berval *v)
1000 {
1001         struct berval *bv;
1002
1003         bv = (struct berval *) slapi_ch_malloc( sizeof(struct berval) );
1004         bv->bv_len = v->bv_len;
1005         bv->bv_val = slapi_ch_malloc( bv->bv_len );
1006         AC_MEMCPY( bv->bv_val, v->bv_val, bv->bv_len );
1007
1008         return bv;
1009 }
1010
1011 struct berval **
1012 slapi_ch_bvecdup(const struct berval **v)
1013 {
1014         int i;
1015         struct berval **rv;
1016
1017         if ( v == NULL ) {
1018                 return NULL;
1019         }
1020
1021         for ( i = 0; v[i] != NULL; i++ )
1022                 ;
1023
1024         rv = (struct berval **) slapi_ch_malloc( (i + 1) * sizeof(struct berval *) );
1025
1026         for ( i = 0; v[i] != NULL; i++ ) {
1027                 rv[i] = slapi_ch_bvdup( v[i] );
1028         }
1029         rv[i] = NULL;
1030
1031         return rv;
1032 }
1033
1034 char *
1035 slapi_ch_calloc(
1036         unsigned long nelem, 
1037         unsigned long size ) 
1038 {
1039         return ch_calloc( nelem, size );
1040 }
1041
1042 char *
1043 slapi_ch_realloc(
1044         char *block, 
1045         unsigned long size ) 
1046 {
1047         return ch_realloc( block, size );
1048 }
1049
1050 char *
1051 slapi_ch_strdup( char *s ) 
1052 {
1053         return ch_strdup( (const char *)s );
1054 }
1055
1056 size_t
1057 slapi_ch_stlen( char *s ) 
1058 {
1059         return strlen( (const char *)s );
1060 }
1061
1062 int 
1063 slapi_control_present(
1064         LDAPControl     **controls, 
1065         char            *oid, 
1066         struct berval   **val, 
1067         int             *iscritical ) 
1068 {
1069         int             i;
1070         int             rc = 0;
1071
1072         if ( val ) {
1073                 *val = NULL;
1074         }
1075         
1076         if ( iscritical ) {
1077                 *iscritical = 0;
1078         }
1079         
1080         for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
1081                 if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
1082                         continue;
1083                 }
1084
1085                 rc = 1;
1086                 if ( controls[i]->ldctl_value.bv_len != 0 ) {
1087                         if ( val ) {
1088                                 *val = &controls[i]->ldctl_value;
1089                         }
1090                 }
1091
1092                 if ( iscritical ) {
1093                         *iscritical = controls[i]->ldctl_iscritical;
1094                 }
1095
1096                 break;
1097         }
1098
1099         return rc;
1100 }
1101
1102 static void
1103 slapControlMask2SlapiControlOp(slap_mask_t slap_mask,
1104         unsigned long *slapi_mask)
1105 {
1106         *slapi_mask = SLAPI_OPERATION_NONE;
1107
1108         if ( slap_mask & SLAP_CTRL_ABANDON ) 
1109                 *slapi_mask |= SLAPI_OPERATION_ABANDON;
1110
1111         if ( slap_mask & SLAP_CTRL_ADD )
1112                 *slapi_mask |= SLAPI_OPERATION_ADD;
1113
1114         if ( slap_mask & SLAP_CTRL_BIND )
1115                 *slapi_mask |= SLAPI_OPERATION_BIND;
1116
1117         if ( slap_mask & SLAP_CTRL_COMPARE )
1118                 *slapi_mask |= SLAPI_OPERATION_COMPARE;
1119
1120         if ( slap_mask & SLAP_CTRL_DELETE )
1121                 *slapi_mask |= SLAPI_OPERATION_DELETE;
1122
1123         if ( slap_mask & SLAP_CTRL_MODIFY )
1124                 *slapi_mask |= SLAPI_OPERATION_MODIFY;
1125
1126         if ( slap_mask & SLAP_CTRL_RENAME )
1127                 *slapi_mask |= SLAPI_OPERATION_MODDN;
1128
1129         if ( slap_mask & SLAP_CTRL_SEARCH )
1130                 *slapi_mask |= SLAPI_OPERATION_SEARCH;
1131
1132         if ( slap_mask & SLAP_CTRL_UNBIND )
1133                 *slapi_mask |= SLAPI_OPERATION_UNBIND;
1134 }
1135
1136 static void
1137 slapiControlOp2SlapControlMask(unsigned long slapi_mask,
1138         slap_mask_t *slap_mask)
1139 {
1140         *slap_mask = 0;
1141
1142         if ( slapi_mask & SLAPI_OPERATION_BIND )
1143                 *slap_mask |= SLAP_CTRL_BIND;
1144
1145         if ( slapi_mask & SLAPI_OPERATION_UNBIND )
1146                 *slap_mask |= SLAP_CTRL_UNBIND;
1147
1148         if ( slapi_mask & SLAPI_OPERATION_SEARCH )
1149                 *slap_mask |= SLAP_CTRL_SEARCH;
1150
1151         if ( slapi_mask & SLAPI_OPERATION_MODIFY )
1152                 *slap_mask |= SLAP_CTRL_MODIFY;
1153
1154         if ( slapi_mask & SLAPI_OPERATION_ADD )
1155                 *slap_mask |= SLAP_CTRL_ADD;
1156
1157         if ( slapi_mask & SLAPI_OPERATION_DELETE )
1158                 *slap_mask |= SLAP_CTRL_DELETE;
1159
1160         if ( slapi_mask & SLAPI_OPERATION_MODDN )
1161                 *slap_mask |= SLAP_CTRL_RENAME;
1162
1163         if ( slapi_mask & SLAPI_OPERATION_COMPARE )
1164                 *slap_mask |= SLAP_CTRL_COMPARE;
1165
1166         if ( slapi_mask & SLAPI_OPERATION_ABANDON )
1167                 *slap_mask |= SLAP_CTRL_ABANDON;
1168
1169         *slap_mask |= SLAP_CTRL_GLOBAL;
1170 }
1171
1172 static int
1173 slapi_int_parse_control(
1174         Operation *op,
1175         SlapReply *rs,
1176         LDAPControl *ctrl )
1177 {
1178         /* Plugins must deal with controls themselves. */
1179
1180         return LDAP_SUCCESS;
1181 }
1182
1183 void 
1184 slapi_register_supported_control(
1185         char            *controloid, 
1186         unsigned long   controlops )
1187 {
1188         slap_mask_t controlmask;
1189
1190         slapiControlOp2SlapControlMask( controlops, &controlmask );
1191
1192         register_supported_control( controloid, controlmask, NULL, slapi_int_parse_control, NULL );
1193 }
1194
1195 int 
1196 slapi_get_supported_controls(
1197         char            ***ctrloidsp, 
1198         unsigned long   **ctrlopsp ) 
1199 {
1200         int i, rc;
1201
1202         rc = get_supported_controls( ctrloidsp, (slap_mask_t **)ctrlopsp );
1203         if ( rc != LDAP_SUCCESS ) {
1204                 return rc;
1205         }
1206
1207         for ( i = 0; (*ctrloidsp)[i] != NULL; i++ ) {
1208                 /* In place, naughty. */
1209                 slapControlMask2SlapiControlOp( (*ctrlopsp)[i], &((*ctrlopsp)[i]) );
1210         }
1211
1212         return LDAP_SUCCESS;
1213 }
1214
1215 LDAPControl *
1216 slapi_dup_control( LDAPControl *ctrl )
1217 {
1218         LDAPControl *ret;
1219
1220         ret = (LDAPControl *)slapi_ch_malloc( sizeof(*ret) );
1221         ret->ldctl_oid = slapi_ch_strdup( ctrl->ldctl_oid );
1222         ber_dupbv( &ret->ldctl_value, &ctrl->ldctl_value );
1223         ret->ldctl_iscritical = ctrl->ldctl_iscritical;
1224
1225         return ret;
1226 }
1227
1228 void 
1229 slapi_register_supported_saslmechanism( char *mechanism )
1230 {
1231         /* FIXME -- can not add saslmechanism to OpenLDAP dynamically */
1232         slapi_log_error( SLAPI_LOG_FATAL, "slapi_register_supported_saslmechanism",
1233                         "OpenLDAP does not support dynamic registration of SASL mechanisms\n" );
1234 }
1235
1236 char **
1237 slapi_get_supported_saslmechanisms( void )
1238 {
1239         /* FIXME -- can not get the saslmechanism without a connection. */
1240         slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_supported_saslmechanisms",
1241                         "can not get the SASL mechanism list "
1242                         "without a connection\n" );
1243         return NULL;
1244 }
1245
1246 char **
1247 slapi_get_supported_extended_ops( void )
1248 {
1249         int             i, j, k;
1250         char            **ppExtOpOID = NULL;
1251         int             numExtOps = 0;
1252
1253         for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
1254                 ;
1255         }
1256         
1257         for ( j = 0; slapi_int_get_supported_extop( j ) != NULL; j++ ) {
1258                 ;
1259         }
1260
1261         numExtOps = i + j;
1262         if ( numExtOps == 0 ) {
1263                 return NULL;
1264         }
1265
1266         ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
1267         for ( k = 0; k < i; k++ ) {
1268                 struct berval   *bv;
1269
1270                 bv = get_supported_extop( k );
1271                 assert( bv != NULL );
1272
1273                 ppExtOpOID[ k ] = bv->bv_val;
1274         }
1275         
1276         for ( ; k < j; k++ ) {
1277                 struct berval   *bv;
1278
1279                 bv = slapi_int_get_supported_extop( k );
1280                 assert( bv != NULL );
1281
1282                 ppExtOpOID[ i + k ] = bv->bv_val;
1283         }
1284         ppExtOpOID[ i + k ] = NULL;
1285
1286         return ppExtOpOID;
1287 }
1288
1289 void 
1290 slapi_send_ldap_result(
1291         Slapi_PBlock    *pb, 
1292         int             err, 
1293         char            *matched, 
1294         char            *text, 
1295         int             nentries, 
1296         struct berval   **urls ) 
1297 {
1298         SlapReply       *rs;
1299
1300         assert( pb->pb_op != NULL );
1301
1302         rs = &pb->pb_rs;
1303
1304         rs->sr_err = err;
1305         rs->sr_matched = matched;
1306         rs->sr_text = text;
1307         rs->sr_ref = NULL;
1308
1309         if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
1310                 send_ldap_sasl( pb->pb_op, rs );
1311         } else if ( rs->sr_rspoid != NULL ) {
1312                 send_ldap_extended( pb->pb_op, rs );
1313         } else {
1314                 if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
1315                         rs->sr_nentries = nentries;
1316
1317                 send_ldap_result( pb->pb_op, rs );
1318         }
1319 }
1320
1321 int 
1322 slapi_send_ldap_search_entry(
1323         Slapi_PBlock    *pb, 
1324         Slapi_Entry     *e, 
1325         LDAPControl     **ectrls, 
1326         char            **attrs, 
1327         int             attrsonly )
1328 {
1329         SlapReply               rs = { REP_SEARCH };
1330         int                     i = 0;
1331         AttributeName           *an = NULL;
1332         const char              *text;
1333         int                     rc;
1334
1335         assert( pb->pb_op != NULL );
1336
1337         if ( attrs != NULL ) {
1338                 for ( i = 0; attrs[ i ] != NULL; i++ ) {
1339                         ; /* empty */
1340                 }
1341         }
1342
1343         if ( i ) {
1344                 an = (AttributeName *) slapi_ch_malloc( (i+1) * sizeof(AttributeName) );
1345                 for ( i = 0; attrs[i] != NULL; i++ ) {
1346                         an[i].an_name.bv_val = attrs[i];
1347                         an[i].an_name.bv_len = strlen( attrs[i] );
1348                         an[i].an_desc = NULL;
1349                         rs.sr_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );
1350                         if ( rs.sr_err != LDAP_SUCCESS) {
1351                                 slapi_ch_free( (void **)&an );
1352                                 return -1;
1353                         }
1354                 }
1355                 an[i].an_name.bv_len = 0;
1356                 an[i].an_name.bv_val = NULL;
1357         }
1358
1359         rs.sr_err = LDAP_SUCCESS;
1360         rs.sr_matched = NULL;
1361         rs.sr_text = NULL;
1362         rs.sr_ref = NULL;
1363         rs.sr_ctrls = ectrls;
1364         rs.sr_attrs = an;
1365         rs.sr_operational_attrs = NULL;
1366         rs.sr_entry = e;
1367         rs.sr_v2ref = NULL;
1368         rs.sr_flags = 0;
1369
1370         rc = send_search_entry( pb->pb_op, &rs );
1371
1372         slapi_ch_free( (void **)&an );
1373
1374         return rc;
1375 }
1376
1377 int 
1378 slapi_send_ldap_search_reference(
1379         Slapi_PBlock    *pb,
1380         Slapi_Entry     *e,
1381         struct berval   **references,
1382         LDAPControl     **ectrls, 
1383         struct berval   **v2refs
1384         )
1385 {
1386         SlapReply       rs = { REP_SEARCHREF };
1387         int             rc;
1388
1389         rs.sr_err = LDAP_SUCCESS;
1390         rs.sr_matched = NULL;
1391         rs.sr_text = NULL;
1392
1393         rc = bvptr2obj( references, &rs.sr_ref );
1394         if ( rc != LDAP_SUCCESS ) {
1395                 return rc;
1396         }
1397
1398         rs.sr_ctrls = ectrls;
1399         rs.sr_attrs = NULL;
1400         rs.sr_operational_attrs = NULL;
1401         rs.sr_entry = e;
1402
1403         if ( v2refs != NULL ) {
1404                 rc = bvptr2obj( v2refs, &rs.sr_v2ref );
1405                 if ( rc != LDAP_SUCCESS ) {
1406                         slapi_ch_free( (void **)&rs.sr_ref );
1407                         return rc;
1408                 }
1409         } else {
1410                 rs.sr_v2ref = NULL;
1411         }
1412
1413         rc = send_search_reference( pb->pb_op, &rs );
1414
1415         slapi_ch_free( (void **)&rs.sr_ref );
1416         slapi_ch_free( (void **)&rs.sr_v2ref );
1417
1418         return rc;
1419 }
1420
1421 Slapi_Filter *
1422 slapi_str2filter( char *str ) 
1423 {
1424         return str2filter( str );
1425 }
1426
1427 void 
1428 slapi_filter_free(
1429         Slapi_Filter    *f, 
1430         int             recurse ) 
1431 {
1432         filter_free( f );
1433 }
1434
1435 Slapi_Filter *
1436 slapi_filter_dup( Slapi_Filter *filter )
1437 {
1438         Filter *f;
1439
1440         f = (Filter *) slapi_ch_malloc( sizeof(Filter) );
1441         f->f_next = NULL;
1442         f->f_choice = filter->f_choice;
1443
1444         switch ( f->f_choice ) {
1445         case LDAP_FILTER_AND:
1446         case LDAP_FILTER_NOT:
1447         case LDAP_FILTER_OR: {
1448                 Filter *pFilter, **ppF;
1449
1450                 for ( pFilter = filter->f_list, ppF = &f->f_list;
1451                       pFilter != NULL;
1452                       pFilter = pFilter->f_next, ppF = &f->f_next )
1453                 {
1454                         *ppF = slapi_filter_dup( pFilter );
1455                         if ( *ppF == NULL )
1456                                 break;
1457                 }
1458                 break;
1459         }
1460         case LDAP_FILTER_PRESENT:
1461                 f->f_desc = filter->f_desc;
1462                 break;
1463         case LDAP_FILTER_EQUALITY:
1464         case LDAP_FILTER_GE:
1465         case LDAP_FILTER_LE:
1466         case LDAP_FILTER_APPROX:
1467                 f->f_ava = (AttributeAssertion *)slapi_ch_malloc( sizeof(AttributeAssertion) );
1468                 f->f_ava->aa_desc = filter->f_ava->aa_desc;
1469                 ber_dupbv( &f->f_ava->aa_value, &filter->f_ava->aa_value );
1470                 break;
1471         case LDAP_FILTER_EXT:
1472                 f->f_mra = (MatchingRuleAssertion *)slapi_ch_malloc( sizeof(MatchingRuleAssertion) );
1473                 f->f_mra->ma_rule = filter->f_mra->ma_rule;
1474                 f->f_mra->ma_rule_text = filter->f_mra->ma_rule_text; /* struct copy */
1475                 f->f_mra->ma_desc = filter->f_mra->ma_desc;
1476                 f->f_mra->ma_dnattrs = filter->f_mra->ma_dnattrs;
1477                 ber_dupbv( &f->f_mra->ma_value, &filter->f_mra->ma_value );
1478                 break;
1479         case LDAP_FILTER_SUBSTRINGS: {
1480                 int i;
1481
1482                 f->f_sub = (SubstringsAssertion *)slapi_ch_malloc( sizeof(SubstringsAssertion) );
1483                 f->f_sub->sa_desc = filter->f_sub->sa_desc;
1484                 ber_dupbv( &f->f_sub_initial, &filter->f_sub_initial );
1485                 if ( filter->f_sub_any != NULL ) {
1486                         for ( i = 0; filter->f_sub_any[i].bv_val != NULL; i++ )
1487                                 ;
1488                         f->f_sub_any = (BerVarray)slapi_ch_malloc( (i + 1) * (sizeof(struct berval)) );
1489                         for ( i = 0; filter->f_sub_any[i].bv_val != NULL; i++ ) {
1490                                 ber_dupbv( &f->f_sub_any[i], &filter->f_sub_any[i] );
1491                         }
1492                         f->f_sub_any[i].bv_val = NULL;
1493                 } else {
1494                         f->f_sub_any = NULL;
1495                 }
1496                 ber_dupbv( &f->f_sub_final, &filter->f_sub_final );
1497                 break;
1498         }
1499         case SLAPD_FILTER_COMPUTED:
1500                 f->f_result = filter->f_result;
1501                 break;
1502         default:
1503                 slapi_ch_free( (void **)&f );
1504                 f = NULL;
1505                 break;
1506         }
1507
1508         return f;
1509 }
1510
1511 int 
1512 slapi_filter_get_choice( Slapi_Filter *f )
1513 {
1514         int             rc;
1515
1516         if ( f != NULL ) {
1517                 rc = f->f_choice;
1518         } else {
1519                 rc = 0;
1520         }
1521
1522         return rc;
1523 }
1524
1525 int 
1526 slapi_filter_get_ava(
1527         Slapi_Filter    *f, 
1528         char            **type, 
1529         struct berval   **bval )
1530 {
1531         int             ftype;
1532         int             rc = LDAP_SUCCESS;
1533
1534         assert( type != NULL );
1535         assert( bval != NULL );
1536
1537         *type = NULL;
1538         *bval = NULL;
1539
1540         ftype = f->f_choice;
1541         if ( ftype == LDAP_FILTER_EQUALITY 
1542                         || ftype ==  LDAP_FILTER_GE 
1543                         || ftype == LDAP_FILTER_LE 
1544                         || ftype == LDAP_FILTER_APPROX ) {
1545                 /*
1546                  * According to the SLAPI Reference Manual these are
1547                  * not duplicated.
1548                  */
1549                 *type = f->f_un.f_un_ava->aa_desc->ad_cname.bv_val;
1550                 *bval = &f->f_un.f_un_ava->aa_value;
1551         } else { /* filter type not supported */
1552                 rc = -1;
1553         }
1554
1555         return rc;
1556 }
1557
1558 Slapi_Filter *
1559 slapi_filter_list_first( Slapi_Filter *f )
1560 {
1561         int             ftype;
1562
1563         if ( f == NULL ) {
1564                 return NULL;
1565         }
1566
1567         ftype = f->f_choice;
1568         if ( ftype == LDAP_FILTER_AND
1569                         || ftype == LDAP_FILTER_OR
1570                         || ftype == LDAP_FILTER_NOT ) {
1571                 return (Slapi_Filter *)f->f_list;
1572         } else {
1573                 return NULL;
1574         }
1575 }
1576
1577 Slapi_Filter *
1578 slapi_filter_list_next(
1579         Slapi_Filter    *f, 
1580         Slapi_Filter    *fprev )
1581 {
1582         int             ftype;
1583
1584         if ( f == NULL ) {
1585                 return NULL;
1586         }
1587
1588         ftype = f->f_choice;
1589         if ( ftype == LDAP_FILTER_AND
1590                         || ftype == LDAP_FILTER_OR
1591                         || ftype == LDAP_FILTER_NOT )
1592         {
1593                 return fprev->f_next;
1594         }
1595
1596         return NULL;
1597 }
1598
1599 int
1600 slapi_filter_get_attribute_type( Slapi_Filter *f, char **type )
1601 {
1602         if ( f == NULL ) {
1603                 return -1;
1604         }
1605
1606         switch ( f->f_choice ) {
1607         case LDAP_FILTER_GE:
1608         case LDAP_FILTER_LE:
1609         case LDAP_FILTER_EQUALITY:
1610         case LDAP_FILTER_APPROX:
1611                 *type = f->f_av_desc->ad_cname.bv_val;
1612                 break;
1613         case LDAP_FILTER_SUBSTRINGS:
1614                 *type = f->f_sub_desc->ad_cname.bv_val;
1615                 break;
1616         case LDAP_FILTER_PRESENT:
1617                 *type = f->f_desc->ad_cname.bv_val;
1618                 break;
1619         case LDAP_FILTER_EXT:
1620                 *type = f->f_mr_desc->ad_cname.bv_val;
1621                 break;
1622         default:
1623                 /* Complex filters need not apply. */
1624                 *type = NULL;
1625                 return -1;
1626         }
1627
1628         return 0;
1629 }
1630
1631 int
1632 slapi_x_filter_set_attribute_type( Slapi_Filter *f, const char *type )
1633 {
1634         AttributeDescription **adp, *ad = NULL;
1635         const char *text;
1636         int rc;
1637
1638         if ( f == NULL ) {
1639                 return -1;
1640         }
1641
1642         switch ( f->f_choice ) {
1643         case LDAP_FILTER_GE:
1644         case LDAP_FILTER_LE:
1645         case LDAP_FILTER_EQUALITY:
1646         case LDAP_FILTER_APPROX:
1647                 adp = &f->f_av_desc;
1648                 break;
1649         case LDAP_FILTER_SUBSTRINGS:
1650                 adp = &f->f_sub_desc;
1651                 break;
1652         case LDAP_FILTER_PRESENT:
1653                 adp = &f->f_desc;
1654                 break;
1655         case LDAP_FILTER_EXT:
1656                 adp = &f->f_mr_desc;
1657                 break;
1658         default:
1659                 /* Complex filters need not apply. */
1660                 return -1;
1661         }
1662
1663         rc = slap_str2ad( type, &ad, &text );
1664         if ( rc == LDAP_SUCCESS )
1665                 *adp = ad;
1666
1667         return ( rc == LDAP_SUCCESS ) ? 0 : -1;
1668 }
1669
1670 int
1671 slapi_filter_get_subfilt( Slapi_Filter *f, char **type, char **initial,
1672         char ***any, char **final )
1673 {
1674         int i;
1675
1676         if ( f->f_choice != LDAP_FILTER_SUBSTRINGS ) {
1677                 return -1;
1678         }
1679
1680         /*
1681          * The caller shouldn't free but we can't return an
1682          * array of char *s from an array of bervals without
1683          * allocating memory, so we may as well be consistent.
1684          * XXX
1685          */
1686         *type = f->f_sub_desc->ad_cname.bv_val;
1687         *initial = f->f_sub_initial.bv_val ? slapi_ch_strdup(f->f_sub_initial.bv_val) : NULL;
1688         if ( f->f_sub_any != NULL ) {
1689                 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ )
1690                         ;
1691                 *any = (char **)slapi_ch_malloc( (i + 1) * sizeof(char *) );
1692                 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
1693                         (*any)[i] = slapi_ch_strdup(f->f_sub_any[i].bv_val);
1694                 }
1695                 (*any)[i] = NULL;
1696         } else {
1697                 *any = NULL;
1698         }
1699         *final = f->f_sub_final.bv_val ? slapi_ch_strdup(f->f_sub_final.bv_val) : NULL;
1700
1701         return 0;
1702 }
1703
1704 Slapi_Filter *
1705 slapi_filter_join( int ftype, Slapi_Filter *f1, Slapi_Filter *f2 )
1706 {
1707         Slapi_Filter *f = NULL;
1708
1709         if ( ftype == LDAP_FILTER_AND ||
1710              ftype == LDAP_FILTER_OR ||
1711              ftype == LDAP_FILTER_NOT )
1712         {
1713                 f = (Slapi_Filter *)slapi_ch_malloc( sizeof(*f) );
1714                 f->f_choice = ftype;
1715                 f->f_list = f1;
1716                 f->f_list->f_next = f2;
1717                 f->f_next = NULL;
1718         }
1719
1720         return f;
1721 }
1722
1723 int
1724 slapi_x_filter_append( int ftype,
1725         Slapi_Filter **pContainingFilter, /* NULL on first call */
1726         Slapi_Filter **pNextFilter,
1727         Slapi_Filter *filterToAppend )
1728 {
1729         if ( ftype == LDAP_FILTER_AND ||
1730              ftype == LDAP_FILTER_OR ||
1731              ftype == LDAP_FILTER_NOT )
1732         {
1733                 if ( *pContainingFilter == NULL ) {
1734                         *pContainingFilter = (Slapi_Filter *)slapi_ch_malloc( sizeof(Slapi_Filter) );
1735                         (*pContainingFilter)->f_choice = ftype;
1736                         (*pContainingFilter)->f_list = filterToAppend;
1737                         (*pContainingFilter)->f_next = NULL;
1738                 } else {
1739                         if ( (*pContainingFilter)->f_choice != ftype ) {
1740                                 /* Sanity check */
1741                                 return -1;
1742                         }
1743                         (*pNextFilter)->f_next = filterToAppend;
1744                 }
1745                 *pNextFilter = filterToAppend;
1746
1747                 return 0;
1748         }
1749         return -1;
1750 }
1751
1752 int
1753 slapi_filter_test( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Filter *f,
1754         int verify_access )
1755 {
1756         Operation *op;
1757         int rc;
1758
1759         if ( f == NULL ) {
1760                 /* spec says return zero if no filter. */
1761                 return 0;
1762         }
1763
1764         if ( verify_access ) {
1765                 op = pb->pb_op;
1766                 if ( op == NULL )
1767                         return LDAP_PARAM_ERROR;
1768         } else {
1769                 op = NULL;
1770         }
1771
1772         /*
1773          * According to acl.c it is safe to call test_filter() with
1774          * NULL arguments...
1775          */
1776         rc = test_filter( op, e, f );
1777         switch (rc) {
1778         case LDAP_COMPARE_TRUE:
1779                 rc = 0;
1780                 break;
1781         case LDAP_COMPARE_FALSE:
1782                 break;
1783         case SLAPD_COMPARE_UNDEFINED:
1784                 rc = LDAP_OTHER;
1785                 break;
1786         case LDAP_PROTOCOL_ERROR:
1787                 /* filter type unknown: spec says return -1 */
1788                 rc = -1;
1789                 break;
1790         }
1791
1792         return rc;
1793 }
1794
1795 int
1796 slapi_filter_test_simple( Slapi_Entry *e, Slapi_Filter *f)
1797 {
1798         return slapi_filter_test( NULL, e, f, 0 );
1799 }
1800
1801 int
1802 slapi_filter_apply( Slapi_Filter *f, FILTER_APPLY_FN fn, void *arg, int *error_code )
1803 {
1804         switch ( f->f_choice ) {
1805         case LDAP_FILTER_AND:
1806         case LDAP_FILTER_NOT:
1807         case LDAP_FILTER_OR: {
1808                 int rc;
1809
1810                 /*
1811                  * FIXME: altering f; should we use a temporary?
1812                  */
1813                 for ( f = f->f_list; f != NULL; f = f->f_next ) {
1814                         rc = slapi_filter_apply( f, fn, arg, error_code );
1815                         if ( rc != 0 ) {
1816                                 return rc;
1817                         }
1818                         if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ) {
1819                                 break;
1820                         }
1821                 }
1822                 break;
1823         }
1824         case LDAP_FILTER_EQUALITY:
1825         case LDAP_FILTER_SUBSTRINGS:
1826         case LDAP_FILTER_GE:
1827         case LDAP_FILTER_LE:
1828         case LDAP_FILTER_PRESENT:
1829         case LDAP_FILTER_APPROX:
1830         case LDAP_FILTER_EXT:
1831                 *error_code = fn( f, arg );
1832                 break;
1833         default:
1834                 *error_code = SLAPI_FILTER_UNKNOWN_FILTER_TYPE;
1835         }
1836
1837         if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ||
1838              *error_code == SLAPI_FILTER_SCAN_CONTINUE ) {
1839                 return 0;
1840         }
1841
1842         return -1;
1843 }
1844
1845 int 
1846 slapi_pw_find(
1847         struct berval   **vals, 
1848         struct berval   *v ) 
1849 {
1850         /*
1851          * FIXME: what's the point?
1852          */
1853         return 1;
1854 }
1855
1856 #define MAX_HOSTNAME 512
1857
1858 char *
1859 slapi_get_hostname( void ) 
1860 {
1861         char            *hn = NULL;
1862         static int      been_here = 0;   
1863         static char     *static_hn = NULL;
1864
1865         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
1866         if ( !been_here ) {
1867                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
1868                 if ( static_hn == NULL) {
1869                         slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_hostname",
1870                                         "Cannot allocate memory for hostname\n" );
1871                         static_hn = NULL;
1872                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1873
1874                         return hn;
1875                         
1876                 } else { 
1877                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
1878                                 slapi_log_error( SLAPI_LOG_FATAL,
1879                                                 "SLAPI",
1880                                                 "can't get hostname\n" );
1881                                 slapi_ch_free( (void **)&static_hn );
1882                                 static_hn = NULL;
1883                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1884
1885                                 return hn;
1886
1887                         } else {
1888                                 been_here = 1;
1889                         }
1890                 }
1891         }
1892         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1893         
1894         hn = ch_strdup( static_hn );
1895
1896         return hn;
1897 }
1898
1899 /*
1900  * FIXME: this should go in an appropriate header ...
1901  */
1902 extern int slapi_int_log_error( int level, char *subsystem, char *fmt, va_list arglist );
1903
1904 int 
1905 slapi_log_error(
1906         int             severity, 
1907         char            *subsystem, 
1908         char            *fmt, 
1909         ... ) 
1910 {
1911         int             rc = LDAP_SUCCESS;
1912         va_list         arglist;
1913
1914         va_start( arglist, fmt );
1915         rc = slapi_int_log_error( severity, subsystem, fmt, arglist );
1916         va_end( arglist );
1917
1918         return rc;
1919 }
1920
1921
1922 unsigned long
1923 slapi_timer_current_time( void ) 
1924 {
1925         static int      first_time = 1;
1926 #if !defined (_WIN32)
1927         struct timeval  now;
1928         unsigned long   ret;
1929
1930         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1931         if (first_time) {
1932                 first_time = 0;
1933                 gettimeofday( &base_time, NULL );
1934         }
1935         gettimeofday( &now, NULL );
1936         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1937                         (now.tv_usec - base_time.tv_usec);
1938         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1939
1940         return ret;
1941
1942         /*
1943          * Ain't it better?
1944         return (slap_get_time() - starttime) * 1000000;
1945          */
1946 #else /* _WIN32 */
1947         LARGE_INTEGER now;
1948
1949         if ( first_time ) {
1950                 first_time = 0;
1951                 performance_counter_present = QueryPerformanceCounter( &base_time );
1952                 QueryPerformanceFrequency( &performance_freq );
1953         }
1954
1955         if ( !performance_counter_present )
1956              return 0;
1957
1958         QueryPerformanceCounter( &now );
1959         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1960 #endif /* _WIN32 */
1961 }
1962
1963 /*
1964  * FIXME ?
1965  */
1966 unsigned long
1967 slapi_timer_get_time( char *label ) 
1968 {
1969         unsigned long start = slapi_timer_current_time();
1970         printf("%10ld %10d usec %s\n", start, 0, label);
1971         return start;
1972 }
1973
1974 /*
1975  * FIXME ?
1976  */
1977 void
1978 slapi_timer_elapsed_time(
1979         char *label,
1980         unsigned long start ) 
1981 {
1982         unsigned long stop = slapi_timer_current_time();
1983         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1984 }
1985
1986 void
1987 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1988 {
1989         Slapi_Entry     **entries;
1990         int             k = 0, nEnt = 0;
1991
1992         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1993         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1994         if ( nEnt == 0 || entries == NULL ) {
1995                 return;
1996         }
1997
1998         for ( k = 0; k < nEnt; k++ ) {
1999                 slapi_entry_free( entries[k] );
2000                 entries[k] = NULL;
2001         }
2002         
2003         slapi_ch_free( (void **)&entries );
2004 }
2005
2006 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
2007 {
2008         if ( pb == NULL )
2009                 return LDAP_PARAM_ERROR;
2010
2011         if ( pb->pb_conn == NULL )
2012                 return LDAP_PARAM_ERROR;
2013
2014 #ifdef HAVE_TLS
2015         *isSSL = pb->pb_conn->c_is_tls;
2016 #else
2017         *isSSL = 0;
2018 #endif
2019
2020         return LDAP_SUCCESS;
2021 }
2022
2023 /*
2024  * DS 5.x compatability API follow
2025  */
2026
2027 int slapi_attr_get_flags( const Slapi_Attr *attr, unsigned long *flags )
2028 {
2029         AttributeType *at;
2030
2031         if ( attr == NULL )
2032                 return LDAP_PARAM_ERROR;
2033
2034         at = attr->a_desc->ad_type;
2035
2036         *flags = SLAPI_ATTR_FLAG_STD_ATTR;
2037
2038         if ( is_at_single_value( at ) )
2039                 *flags |= SLAPI_ATTR_FLAG_SINGLE;
2040         if ( is_at_operational( at ) )
2041                 *flags |= SLAPI_ATTR_FLAG_OPATTR;
2042         if ( is_at_obsolete( at ) )
2043                 *flags |= SLAPI_ATTR_FLAG_OBSOLETE;
2044         if ( is_at_collective( at ) )
2045                 *flags |= SLAPI_ATTR_FLAG_COLLECTIVE;
2046         if ( is_at_no_user_mod( at ) )
2047                 *flags |= SLAPI_ATTR_FLAG_NOUSERMOD;
2048
2049         return LDAP_SUCCESS;
2050 }
2051
2052 int slapi_attr_flag_is_set( const Slapi_Attr *attr, unsigned long flag )
2053 {
2054         unsigned long flags;
2055
2056         if ( slapi_attr_get_flags( attr, &flags ) != 0 )
2057                 return 0;
2058         return (flags & flag) ? 1 : 0;
2059 }
2060
2061 Slapi_Attr *slapi_attr_new( void )
2062 {
2063         Attribute *ad;
2064
2065         ad = (Attribute  *)slapi_ch_calloc( 1, sizeof(*ad) );
2066
2067         return ad;
2068 }
2069
2070 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type )
2071 {
2072         const char *text;
2073         AttributeDescription *ad = NULL;
2074
2075         if( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
2076                 return NULL;
2077         }
2078
2079         a->a_desc = ad;
2080         a->a_vals = NULL;
2081         a->a_nvals = NULL;
2082         a->a_next = NULL;
2083         a->a_flags = 0;
2084
2085         return a;
2086 }
2087
2088 void slapi_attr_free( Slapi_Attr **a )
2089 {
2090         attr_free( *a );
2091         *a = NULL;
2092 }
2093
2094 Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr )
2095 {
2096         return attr_dup( (Slapi_Attr *)attr );
2097 }
2098
2099 int slapi_attr_add_value( Slapi_Attr *a, const Slapi_Value *v )
2100 {
2101         struct berval nval;
2102         struct berval *nvalp;
2103         int rc;
2104         AttributeDescription *desc = a->a_desc;
2105
2106         if ( desc->ad_type->sat_equality &&
2107              desc->ad_type->sat_equality->smr_normalize ) {
2108                 rc = (*desc->ad_type->sat_equality->smr_normalize)(
2109                         SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
2110                         desc->ad_type->sat_syntax,
2111                         desc->ad_type->sat_equality,
2112                         (Slapi_Value *)v, &nval, NULL );
2113                 if ( rc != LDAP_SUCCESS ) {
2114                         return rc;
2115                 }
2116                 nvalp = &nval;
2117         } else {
2118                 nvalp = NULL;
2119         }
2120
2121         rc = value_add_one( &a->a_vals, (Slapi_Value *)v );
2122         if ( rc == 0 && nvalp != NULL ) {
2123                 rc = value_add_one( &a->a_nvals, nvalp );
2124         } else {
2125                 a->a_nvals = a->a_vals;
2126         }
2127
2128         if ( nvalp != NULL ) {
2129                 slapi_ch_free_string( &nval.bv_val );
2130         }
2131
2132         return rc;
2133 }
2134
2135 int slapi_attr_type2plugin( const char *type, void **pi )
2136 {
2137         *pi = NULL;
2138
2139         return LDAP_OTHER;
2140 }
2141
2142 int slapi_attr_get_type( const Slapi_Attr *attr, char **type )
2143 {
2144         if ( attr == NULL ) {
2145                 return LDAP_PARAM_ERROR;
2146         }
2147
2148         *type = attr->a_desc->ad_cname.bv_val;
2149
2150         return LDAP_SUCCESS;
2151 }
2152
2153 int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp )
2154 {
2155         if ( attr == NULL ) {
2156                 return LDAP_PARAM_ERROR;
2157         }
2158         *oidp = attr->a_desc->ad_type->sat_oid;
2159
2160         return LDAP_SUCCESS;
2161 }
2162
2163 int slapi_attr_value_cmp( const Slapi_Attr *a, const struct berval *v1, const struct berval *v2 )
2164 {
2165         MatchingRule *mr;
2166         int ret;
2167         int rc;
2168         const char *text;
2169
2170         mr = a->a_desc->ad_type->sat_equality;
2171         rc = value_match( &ret, a->a_desc, mr,
2172                         SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
2173                 (struct berval *)v1, (void *)v2, &text );
2174         if ( rc != LDAP_SUCCESS ) 
2175                 return -1;
2176
2177         return ( ret == 0 ) ? 0 : -1;
2178 }
2179
2180 int slapi_attr_value_find( const Slapi_Attr *a, struct berval *v )
2181 {
2182         MatchingRule *mr;
2183         struct berval *bv;
2184         int j;
2185         const char *text;
2186         int rc;
2187         int ret;
2188
2189         if ( a ->a_vals == NULL ) {
2190                 return -1;
2191         }
2192         mr = a->a_desc->ad_type->sat_equality;
2193         for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
2194                 rc = value_match( &ret, a->a_desc, mr,
2195                         SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, bv, v, &text );
2196                 if ( rc != LDAP_SUCCESS ) {
2197                         return -1;
2198                 }
2199                 if ( ret == 0 ) {
2200                         return 0;
2201                 }
2202         }
2203         return -1;
2204 }
2205
2206 int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
2207 {
2208         AttributeDescription *a1 = NULL;
2209         AttributeDescription *a2 = NULL;
2210         const char *text;
2211         int ret;
2212
2213         if ( slap_str2ad( t1, &a1, &text ) != LDAP_SUCCESS ) {
2214                 return -1;
2215         }
2216
2217         if ( slap_str2ad( t2, &a2, &text ) != LDAP_SUCCESS ) {
2218                 return 1;
2219         }
2220
2221 #define ad_base_cmp(l,r) (((l)->ad_type->sat_cname.bv_len < (r)->ad_type->sat_cname.bv_len) \
2222         ? -1 : (((l)->ad_type->sat_cname.bv_len > (r)->ad_type->sat_cname.bv_len) \
2223                 ? 1 : strcasecmp((l)->ad_type->sat_cname.bv_val, (r)->ad_type->sat_cname.bv_val )))
2224
2225         switch ( opt ) {
2226         case SLAPI_TYPE_CMP_EXACT:
2227                 ret = ad_cmp( a1, a2 );
2228                 break;
2229         case SLAPI_TYPE_CMP_BASE:
2230                 ret = ad_base_cmp( a1, a2 );
2231                 break;
2232         case SLAPI_TYPE_CMP_SUBTYPE:
2233                 ret = is_ad_subtype( a2, a2 );
2234                 break;
2235         default:
2236                 ret = -1;
2237                 break;
2238         }
2239
2240         return ret;
2241 }
2242
2243 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
2244 {
2245         return slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT );
2246 }
2247
2248 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
2249 {
2250         return slapi_valueset_first_value( &a->a_vals, v );
2251 }
2252
2253 int slapi_attr_next_value( Slapi_Attr *a, int hint, Slapi_Value **v )
2254 {
2255         return slapi_valueset_next_value( &a->a_vals, hint, v );
2256 }
2257
2258 int slapi_attr_get_numvalues( const Slapi_Attr *a, int *numValues )
2259 {
2260         *numValues = slapi_valueset_count( &a->a_vals );
2261
2262         return 0;
2263 }
2264
2265 int slapi_attr_get_valueset( const Slapi_Attr *a, Slapi_ValueSet **vs )
2266 {
2267         *vs = &((Slapi_Attr *)a)->a_vals;
2268
2269         return 0;
2270 }
2271
2272 int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals )
2273 {
2274         return slapi_attr_get_values( a, vals );
2275 }
2276
2277 char *slapi_attr_syntax_normalize( const char *s )
2278 {
2279         AttributeDescription *ad = NULL;
2280         const char *text;
2281
2282         if ( slap_str2ad( s, &ad, &text ) != LDAP_SUCCESS ) {
2283                 return NULL;
2284         }
2285
2286         return ad->ad_cname.bv_val;
2287 }
2288
2289 Slapi_Value *slapi_value_new( void )
2290 {
2291         struct berval *bv;
2292
2293         bv = (struct berval *)slapi_ch_malloc( sizeof(*bv) );
2294
2295         return bv;
2296 }
2297
2298 Slapi_Value *slapi_value_new_berval(const struct berval *bval)
2299 {
2300         return ber_dupbv( NULL, (struct berval *)bval );
2301 }
2302
2303 Slapi_Value *slapi_value_new_value(const Slapi_Value *v)
2304 {
2305         return slapi_value_new_berval( v );
2306 }
2307
2308 Slapi_Value *slapi_value_new_string(const char *s)
2309 {
2310         struct berval bv;
2311
2312         bv.bv_val = (char *)s;
2313         bv.bv_len = strlen( s );
2314
2315         return slapi_value_new_berval( &bv );
2316 }
2317
2318 Slapi_Value *slapi_value_init(Slapi_Value *val)
2319 {
2320         val->bv_val = NULL;
2321         val->bv_len = 0;
2322
2323         return val;
2324 }
2325
2326 Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
2327 {
2328         return ber_dupbv( v, bval );
2329 }
2330
2331 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
2332 {
2333         v->bv_val = slapi_ch_strdup( (char *)s );
2334         v->bv_len = strlen( s );
2335
2336         return v;
2337 }
2338
2339 Slapi_Value *slapi_value_dup(const Slapi_Value *v)
2340 {
2341         return slapi_value_new_value( v );
2342 }
2343
2344 void slapi_value_free(Slapi_Value **value)
2345 {
2346         if ( value == NULL ) {
2347                 return;
2348         }
2349
2350         if ( (*value) != NULL ) {
2351                 slapi_ch_free( (void **)&(*value)->bv_val );
2352                 slapi_ch_free( (void **)value );
2353         }
2354 }
2355
2356 const struct berval *slapi_value_get_berval( const Slapi_Value *value )
2357 {
2358         return value;
2359 }
2360
2361 Slapi_Value *slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
2362 {
2363         if ( value == NULL ) {
2364                 return NULL;
2365         }
2366         if ( value->bv_val != NULL ) {
2367                 slapi_ch_free( (void **)&value->bv_val );
2368         }
2369         slapi_value_init_berval( value, (struct berval *)bval );
2370
2371         return value;
2372 }
2373
2374 Slapi_Value *slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
2375 {
2376         if ( value == NULL ) {
2377                 return NULL;
2378         }
2379         return slapi_value_set_berval( value, vfrom );
2380 }
2381
2382 Slapi_Value *slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
2383 {
2384         if ( value == NULL ) {
2385                 return NULL;
2386         }
2387         if ( value->bv_val != NULL ) {
2388                 slapi_ch_free( (void **)&value->bv_val );
2389         }
2390         value->bv_val = slapi_ch_malloc( len );
2391         value->bv_len = len;
2392         AC_MEMCPY( value->bv_val, val, len );
2393
2394         return value;
2395 }
2396
2397 int slapi_value_set_string(Slapi_Value *value, const char *strVal)
2398 {
2399         if ( value == NULL ) {
2400                 return -1;
2401         }
2402         slapi_value_set( value, (void *)strVal, strlen( strVal ) );
2403         return 0;
2404 }
2405
2406 int slapi_value_set_int(Slapi_Value *value, int intVal)
2407 {
2408         char buf[64];
2409
2410         snprintf( buf, sizeof( buf ), "%d", intVal );
2411
2412         return slapi_value_set_string( value, buf );
2413 }
2414
2415 const char *slapi_value_get_string(const Slapi_Value *value)
2416 {
2417         if ( value == NULL ) return NULL;
2418         if ( value->bv_val == NULL ) return NULL;
2419         if ( !checkBVString( value ) ) return NULL;
2420
2421         return value->bv_val;
2422 }
2423
2424 int slapi_value_get_int(const Slapi_Value *value)
2425 {
2426         if ( value == NULL ) return 0;
2427         if ( value->bv_val == NULL ) return 0;
2428         if ( !checkBVString( value ) ) return 0;
2429
2430         return (int)strtol( value->bv_val, NULL, 10 );
2431 }
2432
2433 unsigned int slapi_value_get_uint(const Slapi_Value *value)
2434 {
2435         if ( value == NULL ) return 0;
2436         if ( value->bv_val == NULL ) return 0;
2437         if ( !checkBVString( value ) ) return 0;
2438
2439         return (unsigned int)strtoul( value->bv_val, NULL, 10 );
2440 }
2441
2442 long slapi_value_get_long(const Slapi_Value *value)
2443 {
2444         if ( value == NULL ) return 0;
2445         if ( value->bv_val == NULL ) return 0;
2446         if ( !checkBVString( value ) ) return 0;
2447
2448         return strtol( value->bv_val, NULL, 10 );
2449 }
2450
2451 unsigned long slapi_value_get_ulong(const Slapi_Value *value)
2452 {
2453         if ( value == NULL ) return 0;
2454         if ( value->bv_val == NULL ) return 0;
2455         if ( !checkBVString( value ) ) return 0;
2456
2457         return strtoul( value->bv_val, NULL, 10 );
2458 }
2459
2460 size_t slapi_value_get_length(const Slapi_Value *value)
2461 {
2462         if ( value == NULL )
2463                 return 0;
2464
2465         return (size_t) value->bv_len;
2466 }
2467
2468 int slapi_value_compare(const Slapi_Attr *a, const Slapi_Value *v1, const Slapi_Value *v2)
2469 {
2470         return slapi_attr_value_cmp( a, v1, v2 );
2471 }
2472
2473 /* A ValueSet is a container for a BerVarray. */
2474 Slapi_ValueSet *slapi_valueset_new( void )
2475 {
2476         Slapi_ValueSet *vs;
2477
2478         vs = (Slapi_ValueSet *)slapi_ch_malloc( sizeof( *vs ) );
2479         *vs = NULL;
2480
2481         return vs;
2482 }
2483
2484 void slapi_valueset_free(Slapi_ValueSet *vs)
2485 {
2486         if ( vs != NULL ) {
2487                 BerVarray vp = *vs;
2488
2489                 ber_bvarray_free( vp );
2490                 slapi_ch_free( (void **)&vp );
2491
2492                 *vs = NULL;
2493         }
2494 }
2495
2496 void slapi_valueset_init(Slapi_ValueSet *vs)
2497 {
2498         if ( vs != NULL && *vs == NULL ) {
2499                 *vs = (Slapi_ValueSet)slapi_ch_calloc( 1, sizeof(struct berval) );
2500                 (*vs)->bv_val = NULL;
2501                 (*vs)->bv_len = 0;
2502         }
2503 }
2504
2505 void slapi_valueset_done(Slapi_ValueSet *vs)
2506 {
2507         BerVarray vp;
2508
2509         if ( vs == NULL )
2510                 return;
2511
2512         for ( vp = *vs; vp->bv_val != NULL; vp++ ) {
2513                 vp->bv_len = 0;
2514                 slapi_ch_free( (void **)&vp->bv_val );
2515         }
2516         /* but don't free *vs or vs */
2517 }
2518
2519 void slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
2520 {
2521         struct berval bv;
2522
2523         ber_dupbv( &bv, (Slapi_Value *)addval );
2524         ber_bvarray_add( vs, &bv );
2525 }
2526
2527 int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
2528 {
2529         return slapi_valueset_next_value( vs, 0, v );
2530 }
2531
2532 int slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
2533 {
2534         int i;
2535         BerVarray vp;
2536
2537         if ( vs == NULL )
2538                 return -1;
2539
2540         vp = *vs;
2541
2542         for ( i = 0; vp[i].bv_val != NULL; i++ ) {
2543                 if ( i == index ) {
2544                         *v = &vp[i];
2545                         return index + 1;
2546                 }
2547         }
2548
2549         return -1;
2550 }
2551
2552 int slapi_valueset_count( const Slapi_ValueSet *vs )
2553 {
2554         int i;
2555         BerVarray vp;
2556
2557         if ( vs == NULL )
2558                 return 0;
2559
2560         vp = *vs;
2561
2562         for ( i = 0; vp[i].bv_val != NULL; i++ )
2563                 ;
2564
2565         return i;
2566
2567 }
2568
2569 void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
2570 {
2571         BerVarray vp;
2572
2573         for ( vp = *vs2; vp->bv_val != NULL; vp++ ) {
2574                 slapi_valueset_add_value( vs1, vp );
2575         }
2576 }
2577
2578 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
2579         struct berval *val, int access )
2580 {
2581         int rc;
2582         slap_access_t slap_access;
2583         AttributeDescription *ad = NULL;
2584         const char *text;
2585
2586         rc = slap_str2ad( attr, &ad, &text );
2587         if ( rc != LDAP_SUCCESS ) {
2588                 return rc;
2589         }
2590
2591         /*
2592          * Whilst the SLAPI access types are arranged as a bitmask, the
2593          * documentation indicates that they are to be used separately.
2594          */
2595         switch ( access & SLAPI_ACL_ALL ) {
2596         case SLAPI_ACL_COMPARE:
2597                 slap_access = ACL_COMPARE;
2598                 break;
2599         case SLAPI_ACL_SEARCH:
2600                 slap_access = ACL_SEARCH;
2601                 break;
2602         case SLAPI_ACL_READ:
2603                 slap_access = ACL_READ;
2604                 break;
2605         case SLAPI_ACL_WRITE:
2606                 slap_access = ACL_WRITE;
2607                 break;
2608         case SLAPI_ACL_DELETE:
2609                 slap_access = ACL_WDEL;
2610                 break;
2611         case SLAPI_ACL_ADD:
2612                 slap_access = ACL_WADD;
2613                 break;
2614         case SLAPI_ACL_SELF:  /* not documented */
2615         case SLAPI_ACL_PROXY: /* not documented */
2616         default:
2617                 return LDAP_INSUFFICIENT_ACCESS;
2618                 break;
2619         }
2620
2621         assert( pb->pb_op != NULL );
2622
2623         if ( access_allowed( pb->pb_op, e, ad, val, slap_access, NULL ) ) {
2624                 return LDAP_SUCCESS;
2625         }
2626
2627         return LDAP_INSUFFICIENT_ACCESS;
2628 }
2629
2630 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
2631 {
2632         int rc = LDAP_SUCCESS;
2633         Modifications *ml;
2634
2635         if ( pb == NULL || pb->pb_op == NULL )
2636                 return LDAP_PARAM_ERROR;
2637
2638         ml = slapi_int_ldapmods2modifications( mods, NULL );
2639         if ( ml == NULL ) {
2640                 return LDAP_OTHER;
2641         }
2642
2643         if ( rc == LDAP_SUCCESS ) {
2644                 rc = acl_check_modlist( pb->pb_op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2645         }
2646
2647         /* Careful when freeing the modlist because it has pointers into the mods array. */
2648         slapi_int_mods_free( ml );
2649
2650         return rc;
2651 }
2652
2653 /*
2654  * Synthesise an LDAPMod array from a Modifications list to pass
2655  * to SLAPI. This synthesis is destructive and as such the 
2656  * Modifications list may not be used after calling this 
2657  * function.
2658  * 
2659  * This function must also be called before slap_mods_check().
2660  */
2661 LDAPMod **slapi_int_modifications2ldapmods(
2662         Modifications **pmodlist,
2663         void *memctx
2664 )
2665 {
2666         Modifications *ml, *modlist;
2667         LDAPMod **mods, *modp;
2668         int i, j;
2669
2670         modlist = *pmodlist;
2671
2672         for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
2673                 ;
2674
2675         mods = (LDAPMod **)slap_sl_malloc( (i + 1) * sizeof(LDAPMod *), memctx );
2676
2677         for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
2678                 mods[i] = (LDAPMod *)slap_sl_malloc( sizeof(LDAPMod), memctx );
2679                 modp = mods[i];
2680                 modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
2681
2682                 /* Take ownership of original type. */
2683                 modp->mod_type = ml->sml_type.bv_val;
2684                 ml->sml_type.bv_val = NULL;
2685
2686                 if ( ml->sml_values != NULL ) {
2687                         for( j = 0; ml->sml_values[j].bv_val != NULL; j++ )
2688                                 ;
2689                         modp->mod_bvalues = (struct berval **)slap_sl_malloc( (j + 1) *
2690                                 sizeof(struct berval *), memctx );
2691                         for( j = 0; ml->sml_values[j].bv_val != NULL; j++ ) {
2692                                 /* Take ownership of original values. */
2693                                 modp->mod_bvalues[j] = (struct berval *)slap_sl_malloc(
2694                                                 sizeof(struct berval), memctx );
2695                                 modp->mod_bvalues[j]->bv_len = ml->sml_values[j].bv_len;
2696                                 modp->mod_bvalues[j]->bv_val = ml->sml_values[j].bv_val;
2697                                 ml->sml_values[j].bv_len = 0;
2698                                 ml->sml_values[j].bv_val = NULL;
2699                         }
2700                         modp->mod_bvalues[j] = NULL;
2701                 } else {
2702                         modp->mod_bvalues = NULL;
2703                 }
2704                 i++;
2705         }
2706
2707         mods[i] = NULL;
2708
2709         slap_mods_free( modlist );
2710         *pmodlist = NULL;
2711
2712         return mods;
2713 }
2714
2715 /*
2716  * Convert a potentially modified array of LDAPMods back to a
2717  * Modification list. 
2718  * 
2719  * The returned Modification list contains pointers into the
2720  * LDAPMods array; the latter MUST be freed with
2721  * slapi_int_free_ldapmods() (see below).
2722  */
2723 Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
2724 {
2725         Modifications *modlist = NULL, **modtail;
2726         LDAPMod **modp;
2727
2728         if ( mods == NULL ) {
2729                 return NULL;
2730         }
2731
2732         modtail = &modlist;
2733
2734         for( modp = mods; *modp != NULL; modp++ ) {
2735                 Modifications *mod;
2736                 int i;
2737                 char **p;
2738                 struct berval **bvp;
2739                 const char *text;
2740                 AttributeDescription *ad = NULL;
2741
2742                 /* Don't initialize attribute type if mods_check() is going to be called */
2743                 if ( slap_str2ad( (*modp)->mod_type, &ad, &text ) != LDAP_SUCCESS )
2744                         continue;
2745
2746                 mod = (Modifications *) slap_sl_malloc( sizeof(Modifications), memctx );
2747                 mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
2748                 mod->sml_flags = 0;
2749                 mod->sml_type.bv_val = (*modp)->mod_type;
2750                 mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
2751                 mod->sml_desc = ad;
2752                 mod->sml_next = NULL;
2753
2754                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2755                         for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ )
2756                                 ;
2757                 } else {
2758                         for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ )
2759                                 ;
2760                 }
2761
2762                 if ( i == 0 ) {
2763                         mod->sml_values = NULL;
2764                 } else {
2765                         mod->sml_values = (BerVarray) slap_sl_malloc( (i + 1) * sizeof(struct berval), memctx );
2766
2767                         /* NB: This implicitly trusts a plugin to return valid modifications. */
2768                         if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2769                                 for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ ) {
2770                                         mod->sml_values[i].bv_val = (*bvp)->bv_val;
2771                                         mod->sml_values[i].bv_len = (*bvp)->bv_len;
2772                                 }
2773                         } else {
2774                                 for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ ) {
2775                                         mod->sml_values[i].bv_val = *p;
2776                                         mod->sml_values[i].bv_len = strlen( *p );
2777                                 }
2778                         }
2779                         mod->sml_values[i].bv_val = NULL;
2780                         mod->sml_values[i].bv_len = 0;
2781                 }
2782                 mod->sml_nvalues = NULL;
2783
2784                 *modtail = mod;
2785                 modtail = &mod->sml_next;
2786         }
2787         
2788         return modlist;
2789 }
2790
2791 void
2792 slapi_int_mods_free( Modifications *ml )
2793 {
2794         Modifications           *next;
2795
2796         for ( ; ml != NULL; ml = next ) {
2797                 next = ml->sml_next;
2798
2799                 /* Don't free unnormalized values */
2800                 if ( ml->sml_nvalues != NULL ) {
2801                         ber_bvarray_free( ml->sml_nvalues );
2802                         ml->sml_nvalues = NULL;
2803                 }
2804                 slapi_ch_free((void **)&ml->sml_values);
2805                 slapi_ch_free((void **)&ml);
2806         }
2807 }
2808
2809 /*
2810  * This function only frees the parts of the mods array that
2811  * are not shared with the Modification list that was created
2812  * by slapi_int_ldapmods2modifications(). 
2813  *
2814  */
2815 void
2816 slapi_int_free_ldapmods ( LDAPMod **mods )
2817 {
2818         int i, j;
2819
2820         if (mods == NULL)
2821                 return;
2822
2823         for ( i = 0; mods[i] != NULL; i++ ) {
2824                 /*
2825                  * Don't free values themselves; they're owned by the
2826                  * Modification list. Do free the containing array.
2827                  */
2828                 if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
2829                         if ( mods[i]->mod_bvalues != NULL ) {
2830                                 for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ )
2831                                         slapi_ch_free( (void **)&mods[i]->mod_bvalues[j] );
2832                                 slapi_ch_free( (void **)&mods[i]->mod_bvalues );
2833                         }
2834                 } else {
2835                         slapi_ch_free( (void **)&mods[i]->mod_values );
2836                 }
2837                 /* Don't free type, for same reasons. */
2838                 slapi_ch_free( (void **)&mods[i] );
2839         }
2840         slapi_ch_free( (void **)&mods );
2841 }
2842
2843 /*
2844  * Sun ONE DS 5.x computed attribute support. Computed attributes
2845  * allow for dynamically generated operational attributes, a very
2846  * useful thing indeed.
2847  */
2848
2849 /*
2850  * For some reason Sun don't use the normal plugin mechanism
2851  * registration path to register an "evaluator" function (an
2852  * "evaluator" is responsible for adding computed attributes;
2853  * the nomenclature is somewhat confusing).
2854  *
2855  * As such slapi_compute_add_evaluator() registers the 
2856  * function directly.
2857  */
2858 int slapi_compute_add_evaluator(slapi_compute_callback_t function)
2859 {
2860         Slapi_PBlock *pPlugin = NULL;
2861         int rc;
2862         int type = SLAPI_PLUGIN_OBJECT;
2863
2864         pPlugin = slapi_pblock_new();
2865         if ( pPlugin == NULL ) {
2866                 rc = LDAP_NO_MEMORY;
2867                 goto done;
2868         }
2869
2870         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
2871         if ( rc != LDAP_SUCCESS ) {
2872                 goto done;
2873         }
2874
2875         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (void *)function );
2876         if ( rc != LDAP_SUCCESS ) {
2877                 goto done;
2878         }
2879
2880         rc = slapi_int_register_plugin( frontendDB, pPlugin );
2881         if ( rc != 0 ) {
2882                 rc = LDAP_OTHER;
2883                 goto done;
2884         }
2885
2886 done:
2887         if ( rc != LDAP_SUCCESS ) {
2888                 if ( pPlugin != NULL ) {
2889                         slapi_pblock_destroy( pPlugin );
2890                 }
2891                 return -1;
2892         }
2893
2894         return 0;
2895 }
2896
2897 /*
2898  * See notes above regarding slapi_compute_add_evaluator().
2899  */
2900 int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
2901 {
2902         Slapi_PBlock *pPlugin = NULL;
2903         int rc;
2904         int type = SLAPI_PLUGIN_OBJECT;
2905
2906         pPlugin = slapi_pblock_new();
2907         if ( pPlugin == NULL ) {
2908                 rc = LDAP_NO_MEMORY;
2909                 goto done;
2910         }
2911
2912         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
2913         if ( rc != LDAP_SUCCESS ) {
2914                 goto done;
2915         }
2916
2917         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, (void *)function );
2918         if ( rc != LDAP_SUCCESS ) {
2919                 goto done;
2920         }
2921
2922         rc = slapi_int_register_plugin( frontendDB, pPlugin );
2923         if ( rc != 0 ) {
2924                 rc = LDAP_OTHER;
2925                 goto done;
2926         }
2927
2928 done:
2929         if ( rc != LDAP_SUCCESS ) {
2930                 if ( pPlugin != NULL ) {
2931                         slapi_pblock_destroy( pPlugin );
2932                 }
2933                 return -1;
2934         }
2935
2936         return 0;
2937 }
2938
2939 /*
2940  * Call compute evaluators
2941  */
2942 int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn)
2943 {
2944         int rc = 0;
2945         slapi_compute_callback_t *pGetPlugin, *tmpPlugin;
2946
2947         rc = slapi_int_get_plugins( frontendDB, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (SLAPI_FUNC **)&tmpPlugin );
2948         if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
2949                 /* Nothing to do; front-end should ignore. */
2950                 return 0;
2951         }
2952
2953         for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
2954                 /*
2955                  * -1: no attribute matched requested type
2956                  *  0: one attribute matched
2957                  * >0: error happened
2958                  */
2959                 rc = (*pGetPlugin)( c, type, e, outputfn );
2960                 if ( rc > 0 ) {
2961                         break;
2962                 }
2963         }
2964
2965         slapi_ch_free( (void **)&tmpPlugin );
2966
2967         return rc;
2968 }
2969
2970 int
2971 compute_rewrite_search_filter( Slapi_PBlock *pb )
2972 {
2973         if ( pb == NULL || pb->pb_op == NULL )
2974                 return LDAP_PARAM_ERROR;
2975
2976         return slapi_int_call_plugins( pb->pb_op->o_bd, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
2977 }
2978
2979 /*
2980  * New API to provide the plugin with access to the search
2981  * pblock. Have informed Sun DS team.
2982  */
2983 int
2984 slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
2985 {
2986         if ( c == NULL )
2987                 return -1;
2988
2989         if ( c->cac_pb == NULL )
2990                 return -1;
2991
2992         *pb = c->cac_pb;
2993
2994         return 0;
2995 }
2996
2997 Slapi_Mutex *slapi_new_mutex( void )
2998 {
2999         Slapi_Mutex *m;
3000
3001         m = (Slapi_Mutex *)slapi_ch_malloc( sizeof(*m) );
3002         if ( ldap_pvt_thread_mutex_init( &m->mutex ) != 0 ) {
3003                 slapi_ch_free( (void **)&m );
3004                 return NULL;
3005         }
3006
3007         return m;
3008 }
3009
3010 void slapi_destroy_mutex( Slapi_Mutex *mutex )
3011 {
3012         if ( mutex != NULL ) {
3013                 ldap_pvt_thread_mutex_destroy( &mutex->mutex );
3014                 slapi_ch_free( (void **)&mutex);
3015         }
3016 }
3017
3018 void slapi_lock_mutex( Slapi_Mutex *mutex )
3019 {
3020         ldap_pvt_thread_mutex_lock( &mutex->mutex );
3021 }
3022
3023 int slapi_unlock_mutex( Slapi_Mutex *mutex )
3024 {
3025         return ldap_pvt_thread_mutex_unlock( &mutex->mutex );
3026 }
3027
3028 Slapi_CondVar *slapi_new_condvar( Slapi_Mutex *mutex )
3029 {
3030         Slapi_CondVar *cv;
3031
3032         if ( mutex == NULL ) {
3033                 return NULL;
3034         }
3035
3036         cv = (Slapi_CondVar *)slapi_ch_malloc( sizeof(*cv) );
3037         if ( ldap_pvt_thread_cond_init( &cv->cond ) != 0 ) {
3038                 slapi_ch_free( (void **)&cv );
3039                 return NULL;
3040         }
3041
3042         cv->mutex = mutex->mutex;
3043
3044         return cv;
3045 }
3046
3047 void slapi_destroy_condvar( Slapi_CondVar *cvar )
3048 {
3049         if ( cvar != NULL ) {
3050                 ldap_pvt_thread_cond_destroy( &cvar->cond );
3051                 slapi_ch_free( (void **)&cvar );
3052         }
3053 }
3054
3055 int slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout )
3056 {
3057         if ( cvar == NULL ) {
3058                 return -1;
3059         }
3060
3061         return ldap_pvt_thread_cond_wait( &cvar->cond, &cvar->mutex );
3062 }
3063
3064 int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
3065 {
3066         if ( cvar == NULL ) {
3067                 return -1;
3068         }
3069
3070         if ( notify_all ) {
3071                 return ldap_pvt_thread_cond_broadcast( &cvar->cond );
3072         }
3073
3074         return ldap_pvt_thread_cond_signal( &cvar->cond );
3075 }
3076
3077 int slapi_int_access_allowed( Operation *op,
3078         Entry *entry,
3079         AttributeDescription *desc,
3080         struct berval *val,
3081         slap_access_t access,
3082         AccessControlState *state )
3083 {
3084         int rc, slap_access = 0;
3085         slapi_acl_callback_t *pGetPlugin, *tmpPlugin;
3086         Slapi_PBlock *pb;
3087
3088         pb = SLAPI_OPERATION_PBLOCK( op );
3089         if ( pb == NULL ) {
3090                 /* internal operation */
3091                 return 1;
3092         }
3093
3094         switch ( access ) {
3095         case ACL_COMPARE:
3096                 slap_access |= SLAPI_ACL_COMPARE;
3097                 break;
3098         case ACL_SEARCH:
3099                 slap_access |= SLAPI_ACL_SEARCH;
3100                 break;
3101         case ACL_READ:
3102                 slap_access |= SLAPI_ACL_READ;
3103                 break;
3104         case ACL_WRITE:
3105                 slap_access |= SLAPI_ACL_WRITE;
3106                 break;
3107         case ACL_WDEL:
3108                 slap_access |= SLAPI_ACL_DELETE;
3109                 break;
3110         case ACL_WADD:
3111                 slap_access |= SLAPI_ACL_ADD;
3112                 break;
3113         default:
3114                 break;
3115         }
3116
3117         rc = slapi_int_get_plugins( op->o_bd, SLAPI_PLUGIN_ACL_ALLOW_ACCESS, (SLAPI_FUNC **)&tmpPlugin );
3118         if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
3119                 /* nothing to do; allowed access */
3120                 return 1;
3121         }
3122
3123         rc = 1; /* default allow policy */
3124
3125         for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
3126                 /*
3127                  * 0    access denied
3128                  * 1    access granted
3129                  */
3130                 rc = (*pGetPlugin)( pb, entry, desc->ad_cname.bv_val,
3131                                     val, slap_access, (void *)state );
3132                 if ( rc == 0 ) {
3133                         break;
3134                 }
3135         }
3136
3137         slapi_ch_free( (void **)&tmpPlugin );
3138
3139         return rc;
3140 }
3141
3142 /*
3143  * There is no documentation for this.
3144  */
3145 int slapi_rdn2typeval( char *rdn, char **type, struct berval *bv )
3146 {
3147         LDAPRDN lrdn;
3148         LDAPAVA *ava;
3149         int rc;
3150         char *p;
3151
3152         *type = NULL;
3153
3154         bv->bv_len = 0;
3155         bv->bv_val = NULL;
3156
3157         rc = ldap_str2rdn( rdn, &lrdn, &p, LDAP_DN_FORMAT_LDAPV3 );
3158         if ( rc != LDAP_SUCCESS ) {
3159                 return -1;
3160         }
3161
3162         if ( lrdn[1] != NULL ) {
3163                 return -1; /* not single valued */
3164         }
3165
3166         ava = lrdn[0];
3167
3168         *type = slapi_ch_strdup( ava->la_attr.bv_val );
3169         ber_dupbv( bv, &ava->la_value );
3170
3171         ldap_rdnfree(lrdn);
3172
3173         return 0;
3174 }
3175
3176 char *slapi_dn_plus_rdn( const char *dn, const char *rdn )
3177 {
3178         struct berval new_dn, parent_dn, newrdn;
3179
3180         new_dn.bv_val = NULL;
3181
3182         parent_dn.bv_val = (char *)dn;
3183         parent_dn.bv_len = strlen( dn );
3184
3185         newrdn.bv_val = (char *)rdn;
3186         newrdn.bv_len = strlen( rdn );
3187
3188         build_new_dn( &new_dn, &parent_dn, &newrdn, NULL );
3189
3190         return new_dn.bv_val;
3191 }
3192
3193 int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
3194 {
3195         Backend *be;
3196         const char *text;
3197         char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
3198         size_t textlen = sizeof textbuf;
3199         int rc = LDAP_SUCCESS;
3200
3201         be = select_backend( &e->e_nname, 0, 0 );
3202         if ( be != NULL )
3203                 rc = entry_schema_check( be, e, NULL, 0,
3204                         &text, textbuf, textlen );
3205
3206         return ( rc == LDAP_SUCCESS ) ? 0 : 1;
3207 }
3208
3209 int slapi_entry_rdn_values_present( const Slapi_Entry *e )
3210 {
3211         LDAPDN dn;
3212         int rc;
3213         int i = 0, match = 0;
3214
3215         rc = ldap_bv2dn( &((Entry *)e)->e_name, &dn, LDAP_DN_FORMAT_LDAPV3 );
3216         if ( rc != LDAP_SUCCESS ) {
3217                 return 0;
3218         }
3219
3220         if ( dn[0] != NULL ) {
3221                 LDAPRDN rdn = dn[0];
3222
3223                 for ( i = 0; rdn[i] != NULL; i++ ) {
3224                         LDAPAVA *ava = &rdn[0][i];
3225                         Slapi_Attr *a = NULL;
3226
3227                         if ( slapi_entry_attr_find( (Slapi_Entry *)e, ava->la_attr.bv_val, &a ) == 0 &&
3228                              slapi_attr_value_find( a, &ava->la_value ) == 0 )
3229                                 match++;
3230                 }
3231         }
3232
3233         ldap_dnfree( dn );
3234
3235         return ( i == match );
3236 }
3237
3238 int slapi_entry_add_rdn_values( Slapi_Entry *e )
3239 {
3240         LDAPDN dn;
3241         int i, rc;
3242
3243         rc = ldap_bv2dn( &e->e_name, &dn, LDAP_DN_FORMAT_LDAPV3 );
3244         if ( rc != LDAP_SUCCESS ) {
3245                 return rc;
3246         }
3247
3248         if ( dn[0] != NULL ) {
3249                 LDAPRDN rdn = dn[0];
3250                 struct berval *vals[2];
3251
3252                 for ( i = 0; rdn[i] != NULL; i++ ) {
3253                         LDAPAVA *ava = &rdn[0][i];
3254                         Slapi_Attr *a = NULL;
3255
3256                         if ( slapi_entry_attr_find( e, ava->la_attr.bv_val, &a ) == 0 &&
3257                              slapi_attr_value_find( a, &ava->la_value ) == 0 )
3258                                 continue;
3259
3260                         vals[0] = &ava->la_value;
3261                         vals[1] = NULL;
3262
3263                         slapi_entry_attr_merge( e, ava->la_attr.bv_val, vals );
3264                 }
3265         }
3266
3267         ldap_dnfree( dn );
3268
3269         return LDAP_SUCCESS;
3270 }
3271
3272 const char *slapi_entry_get_uniqueid( const Slapi_Entry *e )
3273 {
3274         Attribute *attr;
3275
3276         attr = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );
3277         if ( attr == NULL ) {
3278                 return NULL;
3279         }
3280
3281         if ( attr->a_vals != NULL && attr->a_vals[0].bv_len != 0 ) {
3282                 return slapi_value_get_string( &attr->a_vals[0] );
3283         }
3284
3285         return NULL;
3286 }
3287
3288 void slapi_entry_set_uniqueid( Slapi_Entry *e, char *uniqueid )
3289 {
3290         struct berval bv;
3291
3292         attr_delete ( &e->e_attrs, slap_schema.si_ad_entryUUID );
3293
3294         bv.bv_val = uniqueid;
3295         bv.bv_len = strlen( uniqueid );
3296         attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, &bv, NULL );
3297 }
3298
3299 LDAP *slapi_ldap_init( char *ldaphost, int ldapport, int secure, int shared )
3300 {
3301         LDAP *ld;
3302         char *url;
3303         size_t size;
3304         int rc;
3305
3306         size = sizeof("ldap:///");
3307         if ( secure )
3308                 size++;
3309         size += strlen( ldaphost );
3310         if ( ldapport != 0 )
3311                 size += 32;
3312
3313         url = slapi_ch_malloc( size );
3314
3315         if ( ldapport != 0 ) {
3316                 sprintf( url, "ldap%s://%s:%d/", ( secure ? "s" : "" ), ldaphost, ldapport );
3317         } else {
3318                 sprintf( url, "ldap%s://%s/", ( secure ? "s" : "" ), ldaphost );
3319         }
3320
3321         rc = ldap_initialize( &ld, url );
3322
3323         slapi_ch_free_string( &url );
3324
3325         return ( rc == LDAP_SUCCESS ) ? ld : NULL;
3326 }
3327
3328 void slapi_ldap_unbind( LDAP *ld )
3329 {
3330         ldap_unbind_ext_s( ld, NULL, NULL );
3331 }
3332
3333 int slapi_x_backend_get_flags( const Slapi_Backend *be, unsigned long *flags )
3334 {
3335         if ( be == NULL )
3336                 return LDAP_PARAM_ERROR;
3337
3338         *flags = SLAP_DBFLAGS(be);
3339
3340         return LDAP_SUCCESS;
3341 }
3342
3343 int
3344 slapi_int_count_controls( LDAPControl **ctrls )
3345 {
3346         size_t i;
3347
3348         if ( ctrls == NULL )
3349                 return 0;
3350
3351         for ( i = 0; ctrls[i] != NULL; i++ )
3352                 ;
3353
3354         return i;
3355 }
3356
3357 int
3358 slapi_op_abandoned( Slapi_PBlock *pb )
3359 {
3360         if ( pb->pb_op == NULL )
3361                 return 0;
3362
3363         return ( pb->pb_op->o_abandon );
3364 }
3365
3366 char *
3367 slapi_op_type_to_string(unsigned long type)
3368 {
3369         char *str;
3370
3371         switch (type) {
3372         case SLAPI_OPERATION_BIND:
3373                 str = "bind";
3374                 break;
3375         case SLAPI_OPERATION_UNBIND:
3376                 str = "unbind";
3377                 break;
3378         case SLAPI_OPERATION_SEARCH:
3379                 str = "search";
3380                 break;
3381         case SLAPI_OPERATION_MODIFY:
3382                 str = "modify";
3383                 break;
3384         case SLAPI_OPERATION_ADD:
3385                 str = "add";
3386                 break;
3387         case SLAPI_OPERATION_DELETE:
3388                 str = "delete";
3389                 break;
3390         case SLAPI_OPERATION_MODDN:
3391                 str = "modrdn";
3392                 break;
3393         case SLAPI_OPERATION_COMPARE:
3394                 str = "compare";
3395                 break;
3396         case SLAPI_OPERATION_ABANDON:
3397                 str = "abandon";
3398                 break;
3399         case SLAPI_OPERATION_EXTENDED:
3400                 str = "extended";
3401                 break;
3402         default:
3403                 str = "unknown operation type";
3404                 break;
3405         }
3406         return str;
3407 }
3408
3409 unsigned long
3410 slapi_op_get_type(Slapi_Operation * op)
3411 {
3412         unsigned long type;
3413
3414         switch ( op->o_tag ) {
3415         case LDAP_REQ_BIND:
3416                 type = SLAPI_OPERATION_BIND;
3417                 break;
3418         case LDAP_REQ_UNBIND:
3419                 type = SLAPI_OPERATION_UNBIND;
3420                 break;
3421         case LDAP_REQ_SEARCH:
3422                 type = SLAPI_OPERATION_SEARCH;
3423                 break;
3424         case LDAP_REQ_MODIFY:
3425                 type = SLAPI_OPERATION_MODIFY;
3426                 break;
3427         case LDAP_REQ_ADD:
3428                 type = SLAPI_OPERATION_ADD;
3429                 break;
3430         case LDAP_REQ_DELETE:
3431                 type = SLAPI_OPERATION_DELETE;
3432                 break;
3433         case LDAP_REQ_MODRDN:
3434                 type = SLAPI_OPERATION_MODDN;
3435                 break;
3436         case LDAP_REQ_COMPARE:
3437                 type = SLAPI_OPERATION_COMPARE;
3438                 break;
3439         case LDAP_REQ_ABANDON:
3440                 type = SLAPI_OPERATION_ABANDON;
3441                 break;
3442         case LDAP_REQ_EXTENDED:
3443                 type = SLAPI_OPERATION_EXTENDED;
3444                 break;
3445         default:
3446                 type = SLAPI_OPERATION_NONE;
3447                 break;
3448         }
3449         return type;
3450 }
3451
3452 #if 0
3453 void
3454 slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)
3455 {
3456 }
3457
3458 void
3459 slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag)
3460 {
3461 }
3462
3463 int
3464 slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag)
3465 {
3466 }
3467 #endif
3468
3469 #endif /* LDAP_SLAPI */
3470