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