]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
73e34e29bec1fd90e97bac1b9555a8408bfc92e4
[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  * (C) Copyright IBM Corp. 1997,2002
7  * Redistribution and use in source and binary forms are permitted
8  * provided that this notice is preserved and that due credit is 
9  * given to IBM Corporation. This software is provided ``as is'' 
10  * without express or implied warranty.
11  */
12 /*
13  * Portions (C) Copyright PADL Software Pty Ltd.
14  * Redistribution and use in source and binary forms are permitted
15  * provided that this notice is preserved and that due credit is 
16  * given to PADL Software Pty Ltd. This software is provided ``as is'' 
17  * without express or implied warranty.
18  */
19
20 #include "portable.h"
21 #include "slapi_common.h"
22
23 #include <ac/string.h>
24
25 #include <slap.h>
26 #include <slapi.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <unistd.h>
30 #include <ldap_pvt.h>
31
32 struct berval *ns_get_supported_extop( int );
33
34 #ifdef _SPARC  
35 #include <sys/systeminfo.h>
36 #endif
37
38 #include <netdb.h>
39
40 /*
41  * server start time (should we use a struct timeval also in slapd?
42  */
43 static struct                   timeval base_time;
44 ldap_pvt_thread_mutex_t         slapi_hn_mutex;
45 ldap_pvt_thread_mutex_t         slapi_time_mutex;
46
47 struct slapi_mutex {
48         ldap_pvt_thread_mutex_t mutex;
49 };
50
51 struct slapi_condvar {
52         ldap_pvt_thread_cond_t cond;
53         ldap_pvt_thread_mutex_t mutex;
54 };
55
56 /*
57  * This function converts an array of pointers to berval objects to
58  * an array of berval objects.
59  */
60
61 int
62 bvptr2obj(
63         struct berval   **bvptr, 
64         BerVarray       *bvobj )
65 {
66         int             rc = LDAP_SUCCESS;
67         int             i;
68         BerVarray       tmpberval;
69
70         if ( bvptr == NULL || *bvptr == NULL ) {
71                 return LDAP_OTHER;
72         }
73
74         for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
75                 ; /* EMPTY */
76         }
77
78         tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
79         if ( tmpberval == NULL ) {
80                 return LDAP_NO_MEMORY;
81         } 
82
83         for ( i = 0; bvptr[i] != NULL; i++ ) {
84                 tmpberval[i].bv_val = bvptr[i]->bv_val;
85                 tmpberval[i].bv_len = bvptr[i]->bv_len;
86         }
87
88         if ( rc == LDAP_SUCCESS ) {
89                 *bvobj = tmpberval;
90         }
91
92         return rc;
93 }
94
95 Slapi_Entry *
96 slapi_str2entry(
97         char            *s, 
98         int             check_dup )
99 {
100 #if defined(LDAP_SLAPI)
101         Slapi_Entry     *e = NULL;
102         char            *pTmpS;
103
104         pTmpS = slapi_ch_strdup( s );
105         if ( pTmpS != NULL ) {
106                 e = str2entry( pTmpS ); 
107                 slapi_ch_free( (void **)&pTmpS );
108         }
109
110         return e;
111 #else /* !defined(LDAP_SLAPI) */
112         return NULL;
113 #endif /* !defined(LDAP_SLAPI) */
114 }
115
116 char *
117 slapi_entry2str(
118         Slapi_Entry     *e, 
119         int             *len ) 
120 {
121 #if defined(LDAP_SLAPI)
122         char            *ret;
123
124         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
125         ret = entry2str( e, len );
126         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
127
128         return ret;
129 #else /* !defined(LDAP_SLAPI) */
130         return NULL;
131 #endif /* !defined(LDAP_SLAPI) */
132 }
133
134 char *
135 slapi_entry_get_dn( Slapi_Entry *e ) 
136 {
137 #if defined(LDAP_SLAPI)
138         return e->e_name.bv_val;
139 #else /* !defined(LDAP_SLAPI) */
140         return NULL;
141 #endif /* !defined(LDAP_SLAPI) */
142 }
143
144 int
145 slapi_x_entry_get_id( Slapi_Entry *e )
146 {
147 #if defined(LDAP_SLAPI)
148         return e->e_id;
149 #else
150         return NOID;
151 #endif /* !defined(LDAP_SLAPI) */
152 }
153
154 void 
155 slapi_entry_set_dn(
156         Slapi_Entry     *e, 
157         char            *ldn )
158 {
159 #if defined(LDAP_SLAPI)
160         struct berval   dn = { 0, NULL };
161
162         dn.bv_val = ldn;
163         dn.bv_len = strlen( ldn );
164
165         dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
166 #endif /* defined(LDAP_SLAPI) */
167 }
168
169 Slapi_Entry *
170 slapi_entry_dup( Slapi_Entry *e ) 
171 {
172 #if defined(LDAP_SLAPI)
173         char            *tmp = NULL;
174         Slapi_Entry     *tmpEnt;
175         int             len = 0;
176         
177         tmp = slapi_entry2str( e, &len );
178         if ( tmp == NULL ) {
179                 return (Slapi_Entry *)NULL;
180         }
181
182         tmpEnt = (Slapi_Entry *)str2entry( tmp );
183         if ( tmpEnt == NULL ) { 
184                 slapi_ch_free( (void **)&tmp );
185                 return (Slapi_Entry *)NULL;
186         }
187         
188         if (tmp != NULL) {
189                 slapi_ch_free( (void **)&tmp );
190         }
191
192         return tmpEnt;
193 #else /* !defined(LDAP_SLAPI) */
194         return NULL;
195 #endif /* !defined(LDAP_SLAPI) */
196 }
197
198 int 
199 slapi_entry_attr_delete(
200         Slapi_Entry     *e,             
201         char            *type ) 
202 {
203 #if defined(LDAP_SLAPI)
204         AttributeDescription    *ad = NULL;
205         const char              *text;
206
207         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
208                 return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
209         }
210
211         if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
212                 return 0;       /* attribute is deleted */
213         } else {
214                 return -1;      /* something went wrong */
215         }
216 #else /* !defined(LDAP_SLAPI) */
217         return -1;
218 #endif /* !defined(LDAP_SLAPI) */
219 }
220
221 Slapi_Entry *
222 slapi_entry_alloc( void ) 
223 {
224 #if defined(LDAP_SLAPI)
225         return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
226 #else /* !defined(LDAP_SLAPI) */
227         return NULL;
228 #endif /* !defined(LDAP_SLAPI) */
229 }
230
231 void 
232 slapi_entry_free( Slapi_Entry *e ) 
233 {
234 #if defined(LDAP_SLAPI)
235         entry_free( e );
236 #endif /* defined(LDAP_SLAPI) */
237 }
238
239 int 
240 slapi_entry_attr_merge(
241         Slapi_Entry     *e, 
242         char            *type, 
243         struct berval   **vals ) 
244 {
245 #if defined(LDAP_SLAPI)
246         AttributeDescription    *ad = NULL;
247         const char              *text;
248         BerVarray               bv;
249         int                     rc;
250
251         rc = bvptr2obj( vals, &bv );
252         if ( rc != LDAP_SUCCESS ) {
253                 return -1;
254         }
255         
256         rc = slap_str2ad( type, &ad, &text );
257         if ( rc != LDAP_SUCCESS ) {
258                 return -1;
259         }
260         
261         rc = attr_merge( e, ad, bv );
262         ch_free( bv );
263
264         return rc;
265 #else /* !defined(LDAP_SLAPI) */
266         return -1;
267 #endif /* !defined(LDAP_SLAPI) */
268 }
269
270 int
271 slapi_entry_attr_find(
272         Slapi_Entry     *e, 
273         char            *type, 
274         Slapi_Attr      **attr ) 
275 {
276 #if defined(LDAP_SLAPI)
277         AttributeDescription    *ad = NULL;
278         const char              *text;
279         int                     rc;
280
281         rc = slap_str2ad( type, &ad, &text );
282         if ( rc != LDAP_SUCCESS ) {
283                 return -1;
284         }
285
286         *attr = attr_find( e->e_attrs, ad );
287         if ( *attr == NULL ) {
288                 return -1;
289         }
290
291         return 0;
292 #else /* !defined(LDAP_SLAPI) */
293         return -1;
294 #endif /* !defined(LDAP_SLAPI) */
295 }
296
297 char *
298 slapi_entry_attr_get_charptr( const Slapi_Entry *e, const char *type )
299 {
300 #ifdef LDAP_SLAPI
301         AttributeDescription *ad = NULL;
302         const char *text;
303         int rc;
304         Attribute *attr;
305
306         rc = slap_str2ad( type, &ad, &text );
307         if ( rc != LDAP_SUCCESS ) {
308                 return NULL;
309         }
310
311         attr = attr_find( e->e_attrs, ad );
312         if ( attr == NULL ) {
313                 return NULL;
314         }
315
316         if ( attr->a_vals != NULL && attr->a_vals[0].bv_val != NULL ) {
317                 return slapi_ch_strdup( attr->a_vals[0].bv_val );
318         }
319
320         return NULL;
321 #else
322         return -1;
323 #endif
324 }
325
326 int
327 slapi_entry_attr_get_int( const Slapi_Entry *e, const char *type )
328 {
329 #ifdef LDAP_SLAPI
330         AttributeDescription *ad = NULL;
331         const char *text;
332         int rc;
333         Attribute *attr;
334
335         rc = slap_str2ad( type, &ad, &text );
336         if ( rc != LDAP_SUCCESS ) {
337                 return 0;
338         }
339
340         attr = attr_find( e->e_attrs, ad );
341         if ( attr == NULL ) {
342                 return 0;
343         }
344
345         return slapi_value_get_int( attr->a_vals );
346 #else
347         return 0;
348 #endif
349 }
350
351 int
352 slapi_entry_attr_get_long( const Slapi_Entry *e, const char *type )
353 {
354 #ifdef LDAP_SLAPI
355         AttributeDescription *ad = NULL;
356         const char *text;
357         int rc;
358         Attribute *attr;
359
360         rc = slap_str2ad( type, &ad, &text );
361         if ( rc != LDAP_SUCCESS ) {
362                 return 0;
363         }
364
365         attr = attr_find( e->e_attrs, ad );
366         if ( attr == NULL ) {
367                 return 0;
368         }
369
370         return slapi_value_get_long( attr->a_vals );
371 #else
372         return 0;
373 #endif
374 }
375
376 int
377 slapi_entry_attr_get_uint( const Slapi_Entry *e, const char *type )
378 {
379 #ifdef LDAP_SLAPI
380         AttributeDescription *ad = NULL;
381         const char *text;
382         int rc;
383         Attribute *attr;
384
385         rc = slap_str2ad( type, &ad, &text );
386         if ( rc != LDAP_SUCCESS ) {
387                 return 0;
388         }
389
390         attr = attr_find( e->e_attrs, ad );
391         if ( attr == NULL ) {
392                 return 0;
393         }
394
395         return slapi_value_get_uint( attr->a_vals );
396 #else
397         return 0;
398 #endif
399 }
400
401 int
402 slapi_entry_attr_get_ulong( const Slapi_Entry *e, const char *type )
403 {
404 #ifdef LDAP_SLAPI
405         AttributeDescription *ad = NULL;
406         const char *text;
407         int rc;
408         Attribute *attr;
409
410         rc = slap_str2ad( type, &ad, &text );
411         if ( rc != LDAP_SUCCESS ) {
412                 return 0;
413         }
414
415         attr = attr_find( e->e_attrs, ad );
416         if ( attr == NULL ) {
417                 return 0;
418         }
419
420         return slapi_value_get_ulong( attr->a_vals );
421 #else
422         return 0;
423 #endif
424 }
425
426 int
427 slapi_entry_attr_hasvalue( Slapi_Entry *e, const char *type, const char *value )
428 {
429 #ifdef LDAP_SLAPI
430         struct berval bv;
431         AttributeDescription *ad;
432         const char *text;
433         int rc;
434         Attribute *attr;
435         
436         rc = slap_str2ad( type, &ad, &text );
437         if ( rc != LDAP_SUCCESS ) {
438                 return 0;
439         }
440
441         attr = attr_find( e->e_attrs, ad );
442         if ( attr == NULL ) {
443                 return 0;
444         }
445
446         bv.bv_val = (char *)value;
447         bv.bv_len = strlen( value );
448
449         return slapi_attr_value_find( attr, &bv );
450 #else
451         return 0;
452 #endif
453 }
454
455 int
456 slapi_entry_attr_merge_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
457 {
458 #ifdef LDAP_SLAPI
459         return slapi_entry_attr_merge( e, (char *)type, vals );
460 #else
461         return -1;
462 #endif
463 }
464
465 int
466 slapi_entry_first_attr( const Slapi_Entry *e, Slapi_Attr **attr )
467 {
468 #ifdef LDAP_SLAPI
469         if ( e == NULL ) {
470                 return -1;
471         }
472
473         *attr = e->e_attrs;
474
475         return ( *attr != NULL ) ? 0 : -1;
476 #else
477         return -1;
478 #endif
479 }
480
481 int
482 slapi_entry_next_attr( const Slapi_Entry *e, Slapi_Attr *prevattr, Slapi_Attr **attr )
483 {
484 #ifdef LDAP_SLAPI
485         if ( e == NULL ) {
486                 return -1;
487         }
488
489         if ( prevattr == NULL ) {
490                 return -1;
491         }
492
493         *attr = prevattr->a_next;
494
495         return ( *attr != NULL ) ? 0 : -1;
496 #else
497         return -1;
498 #endif
499 }
500
501 int
502 slapi_entry_attr_replace_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
503 {
504 #ifdef LDAP_SLAPI
505         AttributeDescription *ad;
506         const char *text;
507         int rc;
508         BerVarray bv;
509         
510         rc = slap_str2ad( type, &ad, &text );
511         if ( rc != LDAP_SUCCESS ) {
512                 return 0;
513         }
514
515         attr_delete( &e->e_attrs, ad );
516
517         rc = bvptr2obj( vals, &bv );
518         if ( rc != LDAP_SUCCESS ) {
519                 return -1;
520         }
521         
522         rc = attr_merge( e, ad, bv );
523         slapi_ch_free( (void **)&bv );
524         if ( rc != LDAP_SUCCESS ) {
525                 return -1;
526         }
527         
528         return 0;
529 #else
530         return -1;
531 #endif /* LDAP_SLAPI */
532 }
533
534 /* 
535  * FIXME -- The caller must free the allocated memory. 
536  * In Netscape they do not have to.
537  */
538 int 
539 slapi_attr_get_values(
540         Slapi_Attr      *attr, 
541         struct berval   ***vals ) 
542 {
543 #if defined(LDAP_SLAPI)
544         int             i, j;
545         struct berval   **bv;
546
547         if ( attr == NULL ) {
548                 return 1;
549         }
550
551         for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
552                 ; /* EMPTY */
553         }
554
555         bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
556         for ( j = 0; j < i; j++ ) {
557                 bv[j] = ber_dupbv( NULL, &attr->a_vals[j] );
558         }
559         bv[j] = NULL;
560         
561         *vals = (struct berval **)bv;
562
563         return 0;
564 #else /* !defined(LDAP_SLAPI) */
565         return -1;
566 #endif /* !defined(LDAP_SLAPI) */
567 }
568
569 char *
570 slapi_dn_normalize( char *dn ) 
571 {
572 #if defined(LDAP_SLAPI)
573         struct berval   bdn;
574         struct berval   ndn;
575
576         assert( dn != NULL );
577         
578         bdn.bv_val = dn;
579         bdn.bv_len = strlen( dn );
580
581         dnNormalize2( NULL, &bdn, &ndn );
582
583         /*
584          * FIXME: ain't it safe to set dn = ndn.bv_val ?
585          */
586         dn = ch_strdup( ndn.bv_val );
587         ch_free( ndn.bv_val );
588         
589         return dn;
590 #else /* !defined(LDAP_SLAPI) */
591         return NULL;
592 #endif /* !defined(LDAP_SLAPI) */
593 }
594
595 /*
596  * FIXME: this function is dangerous and should be deprecated;
597  * DN normalization is a lot more than lower-casing, and BTW
598  * OpenLDAP's DN normalization for case insensitive attributes
599  * is already lower case
600  */
601 char *
602 slapi_dn_normalize_case( char *dn ) 
603 {
604 #if defined(LDAP_SLAPI)
605         slapi_dn_normalize( dn );
606         ldap_pvt_str2lower( dn );
607
608         return dn;
609 #else /* defined(LDAP_SLAPI) */
610         return NULL;
611 #endif /* defined(LDAP_SLAPI) */
612 }
613
614 int 
615 slapi_dn_issuffix(
616         char            *dn, 
617         char            *suffix )
618 {
619 #if defined(LDAP_SLAPI)
620         struct berval   bdn, ndn;
621         struct berval   bsuffix, nsuffix;
622
623         assert( dn != NULL );
624         assert( suffix != NULL );
625
626         bdn.bv_val = dn;
627         bdn.bv_len = strlen( dn );
628
629         bsuffix.bv_val = suffix;
630         bsuffix.bv_len = strlen( suffix );
631
632         dnNormalize2( NULL, &bdn, &ndn );
633         dnNormalize2( NULL, &bsuffix, &nsuffix );
634
635         return dnIsSuffix( &ndn, &nsuffix );
636 #else /* !defined(LDAP_SLAPI) */
637         return 0;
638 #endif /* !defined(LDAP_SLAPI) */
639 }
640
641 char *
642 slapi_dn_ignore_case( char *dn )
643 {       
644 #if defined(LDAP_SLAPI)
645         return slapi_dn_normalize_case( dn );
646 #else /* !defined(LDAP_SLAPI) */
647         return NULL;
648 #endif /* !defined(LDAP_SLAPI) */
649 }
650
651 char *
652 slapi_ch_malloc( unsigned long size ) 
653 {
654 #if defined(LDAP_SLAPI)
655         return ch_malloc( size );       
656 #else /* !defined(LDAP_SLAPI) */
657         return NULL;
658 #endif /* !defined(LDAP_SLAPI) */
659 }
660
661 void 
662 slapi_ch_free( void **ptr ) 
663 {
664 #if defined(LDAP_SLAPI)
665         ch_free( *ptr );
666         *ptr = NULL;
667 #endif /* defined(LDAP_SLAPI) */
668 }
669
670 void 
671 slapi_ch_free_string( char **ptr ) 
672 {
673 #if defined(LDAP_SLAPI)
674         slapi_ch_free( (void **)ptr );
675 #endif /* defined(LDAP_SLAPI) */
676 }
677
678 void
679 slapi_ch_array_free( char **arrayp )
680 {
681 #ifdef LDAP_SLAPI
682         char **p;
683
684         if ( arrayp != NULL ) {
685                 for ( p = arrayp; *p != NULL; p++ ) {
686                         slapi_ch_free( (void **)p );
687                 }
688                 slapi_ch_free( (void **)&arrayp );
689         }
690 #endif
691 }
692
693 struct berval *
694 slapi_ch_bvdup(const struct berval *v)
695 {
696 #ifdef LDAP_SLAPI
697         struct berval *bv;
698
699         bv = (struct berval *) slapi_ch_malloc( sizeof(struct berval) );
700         bv->bv_len = v->bv_len;
701         bv->bv_val = slapi_ch_malloc( bv->bv_len );
702         AC_MEMCPY( bv->bv_val, v->bv_val, bv->bv_len );
703
704         return bv;
705 #else
706         return NULL;
707 #endif
708 }
709
710 struct berval **
711 slapi_ch_bvecdup(const struct berval **v)
712 {
713 #ifdef LDAP_SLAPI
714         int i;
715         struct berval **rv;
716
717         if ( v == NULL ) {
718                 return NULL;
719         }
720
721         for ( i = 0; v[i] != NULL; i++ )
722                 ;
723
724         rv = (struct berval **) slapi_ch_malloc( (i + 1) * sizeof(struct berval *) );
725
726         for ( i = 0; v[i] != NULL; i++ ) {
727                 rv[i] = slapi_ch_bvdup( v[i] );
728         }
729         rv[i] = NULL;
730
731         return rv;
732 #else
733         return NULL;
734 #endif
735 }
736
737 char *
738 slapi_ch_calloc(
739         unsigned long nelem, 
740         unsigned long size ) 
741 {
742 #if defined(LDAP_SLAPI)
743         return ch_calloc( nelem, size );
744 #else /* !defined(LDAP_SLAPI) */
745         return NULL;
746 #endif /* !defined(LDAP_SLAPI) */
747 }
748
749 char *
750 slapi_ch_realloc(
751         char *block, 
752         unsigned long size ) 
753 {
754 #if defined(LDAP_SLAPI)
755         return ch_realloc( block, size );
756 #else /* !defined(LDAP_SLAPI) */
757         return NULL;
758 #endif /* !defined(LDAP_SLAPI) */
759 }
760
761 char *
762 slapi_ch_strdup( char *s ) 
763 {
764 #if defined(LDAP_SLAPI)
765         return ch_strdup( (const char *)s );
766 #else /* !defined(LDAP_SLAPI) */
767         return NULL;
768 #endif /* !defined(LDAP_SLAPI) */
769 }
770
771 size_t
772 slapi_ch_stlen( char *s ) 
773 {
774 #if defined(LDAP_SLAPI)
775         return strlen( (const char *)s );
776 #else /* !defined(LDAP_SLAPI) */
777         return 0;
778 #endif /* !defined(LDAP_SLAPI) */
779 }
780
781 int 
782 slapi_control_present(
783         LDAPControl     **controls, 
784         char            *oid, 
785         struct berval   **val, 
786         int             *iscritical ) 
787 {
788 #if defined(LDAP_SLAPI)
789         int             i;
790         int             rc = 0;
791
792         if ( val ) {
793                 *val = NULL;
794         }
795         
796         if ( iscritical ) {
797                 *iscritical = 0;
798         }
799         
800         for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
801                 if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
802                         continue;
803                 }
804
805                 rc = 1;
806                 if ( controls[i]->ldctl_value.bv_len != 0 ) {
807                         /*
808                          * FIXME: according to 6.1 specification,
809                          *    "The val output parameter is set
810                          *    to point into the controls array.
811                          *    A copy of the control value is
812                          *    not made."
813                          */
814 #if 0
815                         struct berval   *pTmpBval;
816
817                         pTmpBval = (struct berval *)slapi_ch_malloc( sizeof(struct berval));
818                         if ( pTmpBval == NULL ) {
819                                 rc = 0;
820                         } else {
821                                 pTmpBval->bv_len = controls[i]->ldctl_value.bv_len;
822                                 pTmpBval->bv_val = controls[i]->ldctl_value.bv_val;
823                                 if ( val ) {
824                                         *val = pTmpBval;
825                                 } else {
826                                         slapi_ch_free( (void **)&pTmpBval );
827                                         rc = 0;
828                                 }
829                         }
830 #endif /* 0 */
831                         if ( val ) {
832                                 *val = &controls[i]->ldctl_value;
833                         }
834                 }
835
836                 if ( iscritical ) {
837                         *iscritical = controls[i]->ldctl_iscritical;
838                 }
839
840                 break;
841         }
842
843         return rc;
844 #else /* !defined(LDAP_SLAPI) */
845         return 0;
846 #endif /* !defined(LDAP_SLAPI) */
847 }
848
849 void 
850 slapi_register_supported_control(
851         char            *controloid, 
852         unsigned long   controlops )
853 {
854 #if defined(LDAP_SLAPI)
855         /* FIXME -- can not add controls to openLDAP dynamically */
856         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_CONTROLS",
857                         "can not add controls to openLDAP dynamically\n" );
858 #endif /* defined(LDAP_SLAPI) */
859 }
860
861 int 
862 slapi_get_supported_controls(
863         char            ***ctrloidsp, 
864         unsigned long   **ctrlopsp ) 
865 {
866 #if defined(LDAP_SLAPI)
867         int             i, n;
868         int             rc = 1;
869         char            **oids = NULL;
870         unsigned long   *masks = NULL;
871
872         for (n = 0; get_supported_ctrl( n ) != NULL; n++) {
873                 ; /* count them */
874         }
875         
876         if ( n == 0 ) {
877                 /* no controls */
878                 *ctrloidsp = NULL;
879                 *ctrlopsp = NULL;
880                 return LDAP_SUCCESS;
881         }
882
883
884         oids = (char **)slapi_ch_malloc( (n + 1) * sizeof(char *) );
885         if ( oids == NULL ) {
886                 rc = LDAP_NO_MEMORY;
887                 goto error_return;
888         }
889
890         masks = (unsigned long *)slapi_ch_malloc( n * sizeof(int) );
891         if ( masks == NULL ) {
892                 rc = LDAP_NO_MEMORY;
893                 goto error_return;
894         }
895
896         for ( i = 0; i < n; i++ ) {
897                 /*
898                  * FIXME: Netscape's specification says nothing about
899                  * memory; should we copy the OIDs or return pointers
900                  * to internal values? In OpenLDAP the latter is safe
901                  * since we do not allow to register coltrols runtime
902                  */
903                 oids[ i ] = ch_strdup( get_supported_ctrl( i ) );
904                 if ( oids[ i ] == NULL ) {
905                         rc = LDAP_NO_MEMORY;
906                         goto error_return;
907                 }
908                 masks[ i ] = (unsigned long)get_supported_ctrl_mask( i );
909         }
910
911         *ctrloidsp = oids;
912         *ctrlopsp = masks;
913         return LDAP_SUCCESS;
914
915 error_return:
916         if ( rc != LDAP_SUCCESS ) {
917                 for ( i = 0; oids != NULL && oids[ i ] != NULL; i++ ) {
918                         ch_free( oids[ i ] );
919                 }
920                 ch_free( oids );
921                 ch_free( masks );
922         }
923
924         return rc;
925 #else /* !defined(LDAP_SLAPI) */
926         return 1;
927 #endif /* !defined(LDAP_SLAPI) */
928 }
929
930 void 
931 slapi_register_supported_saslmechanism( char *mechanism )
932 {
933 #if defined(LDAP_SLAPI)
934         /* FIXME -- can not add saslmechanism to openLDAP dynamically */
935         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
936                         "can not add saslmechanism to openLDAP dynamically\n" );
937 #endif /* defined(LDAP_SLAPI) */
938 }
939
940 char **
941 slapi_get_supported_saslmechanisms( void )
942 {
943 #if defined(LDAP_SLAPI)
944         /* FIXME -- can not get the saslmechanism wihtout a connection. */
945         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
946                         "can not get the saslmechanism "
947                         "wihtout a connection\n" );
948         return NULL;
949 #else /* defined(LDAP_SLAPI) */
950         return NULL;
951 #endif /* defined(LDAP_SLAPI) */
952 }
953
954 char **
955 slapi_get_supported_extended_ops( void )
956 {
957 #if defined(LDAP_SLAPI)
958         int             i, j, k;
959         char            **ppExtOpOID = NULL;
960         int             numExtOps = 0;
961
962         for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
963                 ;
964         }
965         
966         for ( j = 0; ns_get_supported_extop( j ) != NULL; j++ ) {
967                 ;
968         }
969
970         numExtOps = i + j;
971         if ( numExtOps == 0 ) {
972                 return NULL;
973         }
974
975         ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
976         for ( k = 0; k < i; k++ ) {
977                 struct berval   *bv;
978
979                 bv = get_supported_extop( k );
980                 assert( bv != NULL );
981
982                 ppExtOpOID[ k ] = bv->bv_val;
983         }
984         
985         for ( ; k < j; k++ ) {
986                 struct berval   *bv;
987
988                 bv = ns_get_supported_extop( k );
989                 assert( bv != NULL );
990
991                 ppExtOpOID[ i + k ] = bv->bv_val;
992         }
993         ppExtOpOID[ i + k ] = NULL;
994
995         return ppExtOpOID;
996 #else /* !defined(LDAP_SLAPI) */
997         return NULL;
998 #endif /* !defined(LDAP_SLAPI) */
999 }
1000
1001 void 
1002 slapi_send_ldap_result(
1003         Slapi_PBlock    *pb, 
1004         int             err, 
1005         char            *matched, 
1006         char            *text, 
1007         int             nentries, 
1008         struct berval   **urls ) 
1009 {
1010 #if defined(LDAP_SLAPI)
1011         Connection      *conn;
1012         Operation       *op;
1013         struct berval   *s;
1014         char            *extOID = NULL;
1015         struct berval   *extValue = NULL;
1016         int             rc;
1017
1018         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
1019         slapi_pblock_get( pb, SLAPI_OPERATION, &op );
1020         if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
1021                 slapi_pblock_get( pb, SLAPI_BIND_RET_SASLCREDS, &s );
1022                 rc = LDAP_SASL_BIND_IN_PROGRESS;
1023                 send_ldap_sasl( conn, op, rc, NULL, NULL, NULL, NULL, s );
1024                 return;
1025         }
1026
1027         slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID, &extOID );
1028         if ( extOID != NULL ) {
1029                 slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE, &extValue );
1030                 slapi_send_ldap_extended_response( conn, op, err, extOID,
1031                                 extValue );
1032                 return;
1033         }
1034
1035         send_ldap_result( conn, op, err, matched, text, NULL, NULL );
1036 #endif /* defined(LDAP_SLAPI) */
1037 }
1038
1039 int 
1040 slapi_send_ldap_search_entry(
1041         Slapi_PBlock    *pb, 
1042         Slapi_Entry     *e, 
1043         LDAPControl     **ectrls, 
1044         char            **attrs, 
1045         int             attrsonly )
1046 {
1047 #if defined(LDAP_SLAPI)
1048         Backend         *be;
1049         Connection      *pConn;
1050         Operation       *pOp;
1051         int             rc;
1052
1053         int             i;
1054         AttributeName   *an = NULL;
1055         const char      *text;
1056
1057         for ( i = 0; attrs[ i ] != NULL; i++ ) {
1058                 ; /* empty */
1059         }
1060
1061         if ( i > 0 ) {
1062                 an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
1063                 for ( i = 0; attrs[i] != NULL; i++ ) {
1064                         an[i].an_name.bv_val = ch_strdup( attrs[i] );
1065                         an[i].an_name.bv_len = strlen( attrs[i] );
1066                         an[i].an_desc = NULL;
1067                         if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
1068                                 return -1;
1069                 }
1070         }
1071
1072         if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
1073                         ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
1074                         ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
1075                 rc = LDAP_OTHER;
1076         } else {
1077                 rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
1078         }
1079
1080         return rc;
1081
1082 #else /* !defined(LDAP_SLAPI) */
1083         return -1;
1084 #endif /* !defined(LDAP_SLAPI) */
1085 }
1086
1087
1088 Slapi_Filter *
1089 slapi_str2filter( char *str ) 
1090 {
1091 #if defined(LDAP_SLAPI)
1092         return str2filter( str );
1093 #else /* !defined(LDAP_SLAPI) */
1094         return NULL;
1095 #endif /* !defined(LDAP_SLAPI) */
1096 }
1097
1098 void 
1099 slapi_filter_free(
1100         Slapi_Filter    *f, 
1101         int             recurse ) 
1102 {
1103 #if defined(LDAP_SLAPI)
1104         filter_free( f );
1105 #endif /* defined(LDAP_SLAPI) */
1106 }
1107
1108 int 
1109 slapi_filter_get_choice( Slapi_Filter *f )
1110 {
1111 #if defined(LDAP_SLAPI)
1112         int             rc;
1113
1114         if ( f != NULL ) {
1115                 rc = f->f_choice;
1116         } else {
1117                 rc = 0;
1118         }
1119
1120         return rc;
1121 #else /* !defined(LDAP_SLAPI) */
1122         return -1;              /* invalid filter type */
1123 #endif /* !defined(LDAP_SLAPI) */
1124 }
1125
1126 int 
1127 slapi_filter_get_ava(
1128         Slapi_Filter    *f, 
1129         char            **type, 
1130         struct berval   **bval )
1131 {
1132 #if defined(LDAP_SLAPI)
1133         int             ftype;
1134         int             rc = LDAP_SUCCESS;
1135
1136         assert( type != NULL );
1137         assert( bval != NULL );
1138
1139         *type = NULL;
1140         *bval = NULL;
1141
1142         ftype = f->f_choice;
1143         if ( ftype == LDAP_FILTER_EQUALITY 
1144                         || ftype ==  LDAP_FILTER_GE 
1145                         || ftype == LDAP_FILTER_LE 
1146                         || ftype == LDAP_FILTER_APPROX ) {
1147                 /*
1148                  * According to the SLAPI Reference Manual these are
1149                  * not duplicated.
1150                  */
1151                 *type = f->f_un.f_un_ava->aa_desc->ad_cname.bv_val;
1152                 *bval = &f->f_un.f_un_ava->aa_value;
1153         } else { /* filter type not supported */
1154                 rc = -1;
1155         }
1156
1157         return rc;
1158 #else /* !defined(LDAP_SLAPI) */
1159         return -1;
1160 #endif /* !defined(LDAP_SLAPI) */
1161 }
1162
1163 Slapi_Filter *
1164 slapi_filter_list_first( Slapi_Filter *f )
1165 {
1166 #if defined(LDAP_SLAPI)
1167         int             ftype;
1168
1169         if ( f == NULL ) {
1170                 return NULL;
1171         }
1172
1173         ftype = f->f_choice;
1174         if ( ftype == LDAP_FILTER_AND
1175                         || ftype == LDAP_FILTER_OR
1176                         || ftype == LDAP_FILTER_NOT ) {
1177                 return (Slapi_Filter *)f->f_and;
1178         } else {
1179                 return NULL;
1180         }
1181 #else /* !defined(LDAP_SLAPI) */
1182         return NULL;
1183 #endif /* !defined(LDAP_SLAPI) */
1184 }
1185
1186 Slapi_Filter *
1187 slapi_filter_list_next(
1188         Slapi_Filter    *f, 
1189         Slapi_Filter    *fprev )
1190 {
1191 #if defined(LDAP_SLAPI)
1192         int             ftype;
1193
1194         if ( f == NULL ) {
1195                 return NULL;
1196         }
1197
1198         ftype = f->f_choice;
1199         if ( ftype == LDAP_FILTER_AND
1200                         || ftype == LDAP_FILTER_OR
1201                         || ftype == LDAP_FILTER_NOT )
1202         {
1203                 return fprev->f_next;
1204         }
1205
1206         return NULL;
1207 #else /* !defined(LDAP_SLAPI) */
1208         return NULL;
1209 #endif /* !defined(LDAP_SLAPI) */
1210 }
1211
1212 int 
1213 slapi_send_ldap_extended_response(
1214         Connection      *conn, 
1215         Operation       *op,
1216         int             errornum, 
1217         char            *respName,
1218         struct berval   *response )
1219 {
1220 #if defined(LDAP_SLAPI)
1221         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
1222                         respName,response, NULL );
1223         return LDAP_SUCCESS;
1224 #else /* !defined(LDAP_SLAPI) */
1225         return -1;
1226 #endif /* !defined(LDAP_SLAPI) */
1227 }
1228
1229 int 
1230 slapi_pw_find(
1231         struct berval   **vals, 
1232         struct berval   *v ) 
1233 {
1234 #if defined(LDAP_SLAPI)
1235         /*
1236          * FIXME: what's the point?
1237          */
1238         return 1;
1239 #else /* !defined(LDAP_SLAPI) */
1240         return 1;
1241 #endif /* !defined(LDAP_SLAPI) */
1242 }
1243              
1244 char *
1245 slapi_get_hostname( void ) 
1246 {
1247 #if defined(LDAP_SLAPI)
1248         char            *hn = NULL;
1249
1250         /*
1251          * FIXME: I'd prefer a different check ...
1252          */
1253 #if defined _SPARC 
1254         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
1255         if ( hn == NULL) {
1256                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1257                                 "can't malloc memory for hostname\n" );
1258                 hn = NULL;
1259                 
1260         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
1261                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1262                                 "can't get hostname\n" );
1263                 slapi_ch_free( (void **)&hn );
1264                 hn = NULL;
1265         }
1266 #else /* !_SPARC */
1267         static int      been_here = 0;   
1268         static char     *static_hn = NULL;
1269
1270         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
1271         if ( !been_here ) {
1272                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
1273                 if ( static_hn == NULL) {
1274                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1275                                         "can't malloc memory for hostname\n" );
1276                         static_hn = NULL;
1277                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1278
1279                         return hn;
1280                         
1281                 } else { 
1282                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
1283                                 slapi_log_error( SLAPI_LOG_FATAL,
1284                                                 "SLAPI_SYSINFO",
1285                                                 "can't get hostname\n" );
1286                                 slapi_ch_free( (void **)&static_hn );
1287                                 static_hn = NULL;
1288                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1289
1290                                 return hn;
1291
1292                         } else {
1293                                 been_here = 1;
1294                         }
1295                 }
1296         }
1297         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1298         
1299         hn = ch_strdup( static_hn );
1300 #endif /* !_SPARC */
1301
1302         return hn;
1303 #else /* !defined(LDAP_SLAPI) */
1304         return NULL;
1305 #endif /* !defined(LDAP_SLAPI) */
1306 }
1307
1308 /*
1309  * FIXME: this should go in an appropriate header ...
1310  */
1311 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1312
1313 int 
1314 slapi_log_error(
1315         int             severity, 
1316         char            *subsystem, 
1317         char            *fmt, 
1318         ... ) 
1319 {
1320 #if defined(LDAP_SLAPI)
1321         int             rc = LDAP_SUCCESS;
1322         va_list         arglist;
1323
1324         va_start( arglist, fmt );
1325         rc = vLogError( severity, subsystem, fmt, arglist );
1326         va_end( arglist );
1327
1328         return rc;
1329 #else /* !defined(LDAP_SLAPI) */
1330         return -1;
1331 #endif /* !defined(LDAP_SLAPI) */
1332 }
1333
1334
1335 unsigned long
1336 slapi_timer_current_time( void ) 
1337 {
1338 #if defined(LDAP_SLAPI)
1339         static int      first_time = 1;
1340 #if !defined (_WIN32)
1341         struct timeval  now;
1342         unsigned long   ret;
1343
1344         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1345         if (first_time) {
1346                 first_time = 0;
1347                 gettimeofday( &base_time, NULL );
1348         }
1349         gettimeofday( &now, NULL );
1350         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1351                         (now.tv_usec - base_time.tv_usec);
1352         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1353
1354         return ret;
1355
1356         /*
1357          * Ain't it better?
1358         return (slap_get_time() - starttime) * 1000000;
1359          */
1360 #else /* _WIN32 */
1361         LARGE_INTEGER now;
1362
1363         if ( first_time ) {
1364                 first_time = 0;
1365                 performance_counter_present = QueryPerformanceCounter( &base_time );
1366                 QueryPerformanceFrequency( &performance_freq );
1367         }
1368
1369         if ( !performance_counter_present )
1370              return 0;
1371
1372         QueryPerformanceCounter( &now );
1373         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1374 #endif /* _WIN32 */
1375 #else /* !defined(LDAP_SLAPI) */
1376         return 0;
1377 #endif /* !defined(LDAP_SLAPI) */
1378 }
1379
1380 /*
1381  * FIXME ?
1382  */
1383 unsigned long
1384 slapi_timer_get_time( char *label ) 
1385 {
1386 #if defined(LDAP_SLAPI)
1387         unsigned long start = slapi_timer_current_time();
1388         printf("%10ld %10ld usec %s\n", start, 0, label);
1389         return start;
1390 #else /* !defined(LDAP_SLAPI) */
1391         return 0;
1392 #endif /* !defined(LDAP_SLAPI) */
1393 }
1394
1395 /*
1396  * FIXME ?
1397  */
1398 void
1399 slapi_timer_elapsed_time(
1400         char *label,
1401         unsigned long start ) 
1402 {
1403 #if defined(LDAP_SLAPI)
1404         unsigned long stop = slapi_timer_current_time();
1405         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1406 #endif /* defined(LDAP_SLAPI) */
1407 }
1408
1409 void
1410 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1411 {
1412 #if defined(LDAP_SLAPI)
1413         Slapi_Entry     **entries;
1414         int             k = 0, nEnt = 0;
1415
1416         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1417         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1418         if ( nEnt == 0 ) {
1419                 return;
1420         }
1421         
1422         if ( entries == NULL ) {
1423                 return;
1424         }
1425         
1426         for ( k = 0; k < nEnt; k++ ) {
1427                 slapi_entry_free( entries[k] );
1428         }
1429         
1430         slapi_ch_free( (void **)&entries );
1431 #endif /* defined(LDAP_SLAPI) */
1432 }
1433
1434 /*
1435  * Internal API to prime a Slapi_PBlock with a Backend.
1436  */
1437 int slapi_x_backend_set_pb( Slapi_PBlock *pb, Backend *be )
1438 {
1439 #if defined(LDAP_SLAPI)
1440         int rc;
1441         
1442         rc = slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
1443         if ( rc != LDAP_SUCCESS )
1444                 return rc;
1445         
1446         if ( be != NULL ) {
1447                 rc = slapi_pblock_set( pb, SLAPI_BE_TYPE, (void *)be->bd_info->bi_type );
1448                 if ( rc != LDAP_SUCCESS )
1449                         return rc;
1450         }
1451
1452         return LDAP_SUCCESS;
1453 #else
1454         return -1;
1455 #endif /* defined(LDAP_SLAPI) */
1456 }
1457
1458 #if defined(LDAP_SLAPI)
1459 /*
1460  * If oldStyle is TRUE, then a value suitable for setting to
1461  * the deprecated SLAPI_CONN_AUTHTYPE value is returned 
1462  * (pointer to static storage).
1463  *
1464  * If oldStyle is FALSE, then a value suitable for setting to
1465  * the new SLAPI_CONN_AUTHMETHOD will be returned, which is
1466  * a pointer to allocated memory and will include the SASL
1467  * mechanism (if any).
1468  */
1469 static char *Authorization2AuthType( AuthorizationInformation *authz, int is_tls, int oldStyle )
1470 {
1471         size_t len;
1472         char *authType;
1473
1474         switch ( authz->sai_method ) {
1475         case LDAP_AUTH_SASL:
1476                 if ( oldStyle ) {
1477                         authType = SLAPD_AUTH_SASL;
1478                 } else {
1479                         len = sizeof(SLAPD_AUTH_SASL) + authz->sai_mech.bv_len;
1480                         authType = slapi_ch_malloc( len );
1481                         snprintf( authType, len, "%s%s", SLAPD_AUTH_SASL, authz->sai_mech.bv_val );
1482                 }
1483                 break;
1484         case LDAP_AUTH_SIMPLE:
1485                 authType = oldStyle ? SLAPD_AUTH_SIMPLE : slapi_ch_strdup( SLAPD_AUTH_SIMPLE );
1486                 break;
1487         case LDAP_AUTH_NONE:
1488                 authType = oldStyle ? SLAPD_AUTH_NONE : slapi_ch_strdup( SLAPD_AUTH_NONE );
1489                 break;
1490         default:
1491                 authType = NULL;
1492                 break;
1493         }
1494         if ( is_tls && authType == NULL ) {
1495                 authType = oldStyle ? SLAPD_AUTH_SSL : slapi_ch_strdup( SLAPD_AUTH_SSL );
1496         }
1497
1498         return authType;
1499 }
1500 #endif
1501
1502 /*
1503  * Internal API to prime a Slapi_PBlock with a Connection.
1504  */
1505 int slapi_x_connection_set_pb( Slapi_PBlock *pb, Connection *conn )
1506 {
1507 #if defined(LDAP_SLAPI)
1508         char *connAuthType;
1509         int rc;
1510
1511         rc = slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
1512         if ( rc != LDAP_SUCCESS )
1513                 return rc;
1514
1515         if ( strncmp( conn->c_peer_name.bv_val, "IP=", 3 ) == 0 ) {
1516                 rc = slapi_pblock_set( pb, SLAPI_CONN_CLIENTIP, (void *)&conn->c_peer_name.bv_val[3] );
1517                 if ( rc != LDAP_SUCCESS )
1518                         return rc;
1519         } else if ( strncmp( conn->c_peer_name.bv_val, "PATH=", 5 ) == 0 ) {
1520                 rc = slapi_pblock_set( pb, SLAPI_X_CONN_CLIENTPATH, (void *)&conn->c_peer_name.bv_val[5] );
1521                 if ( rc != LDAP_SUCCESS )
1522                         return rc;
1523         }
1524
1525         if ( strncmp( conn->c_sock_name.bv_val, "IP=", 3 ) == 0 ) {
1526                 rc = slapi_pblock_set( pb, SLAPI_CONN_SERVERIP, (void *)&conn->c_sock_name.bv_val[3] );
1527                 if ( rc != LDAP_SUCCESS )
1528                         return rc;
1529         } else if ( strncmp( conn->c_sock_name.bv_val, "PATH=", 5 ) == 0 ) {
1530                 rc = slapi_pblock_set( pb, SLAPI_X_CONN_SERVERPATH, (void *)&conn->c_sock_name.bv_val[5] );
1531                 if ( rc != LDAP_SUCCESS )
1532                         return rc;
1533         }
1534
1535 #ifdef LDAP_CONNECTIONLESS
1536         rc = slapi_pblock_set( pb, SLAPI_X_CONN_IS_UDP, (void *)conn->c_is_udp );
1537         if ( rc != LDAP_SUCCESS )
1538                 return rc;
1539 #endif
1540
1541         rc = slapi_pblock_set( pb, SLAPI_CONN_ID, (void *)conn->c_connid );
1542         if ( rc != LDAP_SUCCESS )
1543                 return rc;
1544
1545         /* Returns pointer to static string */
1546         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 1 );
1547         if ( connAuthType != NULL ) {
1548                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
1549                 if ( rc != LDAP_SUCCESS )
1550                         return rc;
1551         }
1552
1553         /* Returns pointer to allocated string */
1554         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 0 );
1555         if ( connAuthType != NULL ) {
1556                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType);
1557                 if ( rc != LDAP_SUCCESS )
1558                         return rc;
1559         }
1560
1561         if ( conn->c_authz.sai_dn.bv_val != NULL ) {
1562                 char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
1563                 rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
1564                 if ( rc != LDAP_SUCCESS )
1565                         return rc;
1566         }
1567
1568         return rc;
1569 #else
1570         return -1;
1571 #endif /* defined(LDAP_SLAPI) */
1572 }
1573
1574 /*
1575  * Internal API to prime a Slapi_PBlock with an Operation.
1576  */
1577 int slapi_x_operation_set_pb( Slapi_PBlock *pb, Operation *op )
1578 {
1579 #if defined(LDAP_SLAPI)
1580         int isRoot = 0;
1581         int isUpdateDn = 0;
1582         int rc;
1583         Backend *be;
1584         char *opAuthType;
1585
1586         if ( slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
1587                 be = NULL;
1588         }
1589         if (be != NULL) {
1590                 isRoot = be_isroot( be, &op->o_ndn );
1591                 isUpdateDn = be_isupdate( be, &op->o_ndn );
1592         }
1593                 
1594         rc = slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
1595         if ( rc != LDAP_SUCCESS )
1596                 return rc;
1597
1598         rc = slapi_pblock_set( pb, SLAPI_OPINITIATED_TIME, (void *)op->o_time );
1599         if ( rc != LDAP_SUCCESS )
1600                 return rc;
1601
1602         rc = slapi_pblock_set( pb, SLAPI_OPERATION_ID, (void *)op->o_opid );
1603         if ( rc != LDAP_SUCCESS )
1604                 return rc;
1605
1606         rc = slapi_pblock_set( pb, SLAPI_OPERATION_TYPE, (void *)op->o_tag );
1607         if ( rc != LDAP_SUCCESS )
1608                 return rc;
1609
1610         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, (void *)isRoot );
1611         if ( rc != LDAP_SUCCESS )
1612                 return rc;
1613
1614         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISUPDATEDN, (void *)isUpdateDn );
1615         if ( rc != LDAP_SUCCESS )
1616                 return rc;
1617
1618         rc = slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
1619         if ( rc != LDAP_SUCCESS)
1620                 return rc;
1621
1622         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_DN, (void *)op->o_ndn.bv_val );
1623         if ( rc != LDAP_SUCCESS )
1624                 return rc;
1625
1626         rc = slapi_pblock_get( pb, SLAPI_CONN_AUTHMETHOD, (void *)&opAuthType );
1627         if ( rc == LDAP_SUCCESS && opAuthType != NULL ) {
1628                 /* Not quite sure what the point of this is. */
1629                 rc = slapi_pblock_set( pb, SLAPI_OPERATION_AUTHTYPE, (void *)opAuthType );
1630                 if ( rc != LDAP_SUCCESS )
1631                         return rc;
1632         }
1633
1634         return LDAP_SUCCESS;
1635 #else
1636         return -1;
1637 #endif
1638 }
1639
1640 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
1641 {
1642 #if defined( LDAP_SLAPI )
1643         Connection *conn;
1644
1645         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
1646         *isSSL = conn->c_is_tls;
1647
1648         return LDAP_SUCCESS;
1649 #else
1650         return -1;
1651 #endif /* defined(LDAP_SLAPI) */
1652 }
1653
1654 /*
1655  * DS 5.x compatability API follow
1656  */
1657
1658 int slapi_attr_get_flags( const Slapi_Attr *attr, unsigned long *flags )
1659 {
1660 #if defined( LDAP_SLAPI )
1661         AttributeType *at;
1662
1663         if ( attr == NULL )
1664                 return LDAP_PARAM_ERROR;
1665
1666         at = attr->a_desc->ad_type;
1667
1668         *flags = SLAPI_ATTR_FLAG_STD_ATTR;
1669
1670         if ( is_at_single_value( at ) )
1671                 *flags |= SLAPI_ATTR_FLAG_SINGLE;
1672         if ( is_at_operational( at ) )
1673                 *flags |= SLAPI_ATTR_FLAG_OPATTR;
1674         if ( is_at_obsolete( at ) )
1675                 *flags |= SLAPI_ATTR_FLAG_OBSOLETE;
1676         if ( is_at_collective( at ) )
1677                 *flags |= SLAPI_ATTR_FLAG_COLLECTIVE;
1678         if ( is_at_no_user_mod( at ) )
1679                 *flags |= SLAPI_ATTR_FLAG_NOUSERMOD;
1680
1681         return LDAP_SUCCESS;
1682 #else
1683         return -1;
1684 #endif /* defined(LDAP_SLAPI) */
1685 }
1686
1687 int slapi_attr_flag_is_set( const Slapi_Attr *attr, unsigned long flag )
1688 {
1689 #if defined( LDAP_SLAPI )
1690         unsigned long flags;
1691
1692         if ( slapi_attr_get_flags( attr, &flags ) != 0 )
1693                 return 0;
1694         return (flags & flag) ? 1 : 0;
1695 #else
1696         return 0;
1697 #endif /* defined(LDAP_SLAPI) */
1698 }
1699
1700 Slapi_Attr *slapi_attr_new( void )
1701 {
1702 #ifdef LDAP_SLAPI
1703         Attribute *ad;
1704
1705         ad = (Attribute  *)slapi_ch_calloc( 1, sizeof(*ad) );
1706
1707         return ad;
1708 #else
1709         return NULL;
1710 #endif
1711 }
1712
1713 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type )
1714 {
1715 #ifdef LDAP_SLAPI
1716         const char *text;
1717         AttributeDescription *ad = NULL;
1718
1719         if( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
1720                 return NULL;
1721         }
1722
1723         a->a_desc = ad;
1724         a->a_vals = NULL;
1725         a->a_next = NULL;
1726         a->a_flags = 0;
1727
1728         return a;
1729 #else
1730         return NULL;
1731 #endif
1732 }
1733
1734 void slapi_attr_free( Slapi_Attr **a )
1735 {
1736 #ifdef LDAP_SLAPI
1737         attr_free( *a );
1738         *a = NULL;
1739 #endif
1740 }
1741
1742 Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr )
1743 {
1744 #ifdef LDAP_SLAPI
1745         return attr_dup( (Slapi_Attr *)attr );
1746 #else
1747         return NULL;
1748 #endif
1749 }
1750
1751 int slapi_attr_add_value( Slapi_Attr *a, const Slapi_Value *v )
1752 {
1753 #ifdef LDAP_SLAPI
1754         return value_add_one( &a->a_vals, (Slapi_Value *)v );
1755 #else
1756         return -1;
1757 #endif
1758 }
1759
1760 int slapi_attr_type2plugin( const char *type, void **pi )
1761 {
1762         *pi = NULL;
1763
1764         return LDAP_OTHER;
1765 }
1766
1767 int slapi_attr_get_type( const Slapi_Attr *attr, char **type )
1768 {
1769 #ifdef LDAP_SLAPI
1770         if ( attr == NULL ) {
1771                 return LDAP_PARAM_ERROR;
1772         }
1773
1774         *type = attr->a_desc->ad_cname.bv_val;
1775
1776         return LDAP_SUCCESS;
1777 #else
1778         return -1;
1779 #endif
1780 }
1781
1782 int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp )
1783 {
1784 #ifdef LDAP_SLAPI
1785         if ( attr == NULL ) {
1786                 return LDAP_PARAM_ERROR;
1787         }
1788         *oidp = attr->a_desc->ad_type->sat_oid;
1789
1790         return LDAP_SUCCESS;
1791 #else
1792         return -1;
1793 #endif
1794 }
1795
1796 int slapi_attr_value_cmp( const Slapi_Attr *a, const struct berval *v1, const struct berval *v2 )
1797 {
1798 #ifdef LDAP_SLAPI
1799         MatchingRule *mr;
1800         int ret;
1801         int rc;
1802         const char *text;
1803
1804         mr = a->a_desc->ad_type->sat_equality;
1805         rc = value_match( &ret, a->a_desc, mr, SLAP_MR_ASSERTION_SYNTAX_MATCH,
1806                 (struct berval *)v1, (void *)v2, &text );
1807         if ( rc != LDAP_SUCCESS ) 
1808                 return -1;
1809
1810         return ( ret == 0 ) ? 0 : -1;
1811 #else
1812         return -1;
1813 #endif
1814 }
1815
1816 int slapi_attr_value_find( const Slapi_Attr *a, struct berval *v )
1817 {
1818 #ifdef LDAP_SLAPI
1819         MatchingRule *mr;
1820         struct berval *bv;
1821         int j;
1822         const char *text;
1823         int rc;
1824         int ret;
1825
1826         mr = a->a_desc->ad_type->sat_equality;
1827         for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
1828                 rc = value_match( &ret, a->a_desc, mr,
1829                         SLAP_MR_ASSERTION_SYNTAX_MATCH, bv, v, &text );
1830                 if ( rc != LDAP_SUCCESS ) {
1831                         return -1;
1832                 }
1833                 if ( ret == 0 ) {
1834                         return 0;
1835                 }
1836         }
1837 #endif
1838         return -1;
1839 }
1840
1841 int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
1842 {
1843 #ifdef LDAP_SLAPI
1844         AttributeDescription *a1 = NULL;
1845         AttributeDescription *a2 = NULL;
1846         const char *text;
1847         int ret;
1848
1849         if ( slap_str2ad( t1, &a1, &text ) != LDAP_SUCCESS ) {
1850                 return -1;
1851         }
1852
1853         if ( slap_str2ad( t2, &a2, &text ) != LDAP_SUCCESS ) {
1854                 return 1;
1855         }
1856
1857 #define ad_base_cmp(l,r) (((l)->ad_type->sat_cname.bv_len < (r)->ad_type->sat_cname.bv_len) \
1858         ? -1 : (((l)->ad_type->sat_cname.bv_len > (r)->ad_type->sat_cname.bv_len) \
1859                 ? 1 : strcasecmp((l)->ad_type->sat_cname.bv_val, (r)->ad_type->sat_cname.bv_val )))
1860
1861         switch ( opt ) {
1862         case SLAPI_TYPE_CMP_EXACT:
1863                 ret = ad_cmp( a1, a2 );
1864                 break;
1865         case SLAPI_TYPE_CMP_BASE:
1866                 ret = ad_base_cmp( a1, a2 );
1867                 break;
1868         case SLAPI_TYPE_CMP_SUBTYPE:
1869                 ret = is_ad_subtype( a2, a2 );
1870                 break;
1871         default:
1872                 ret = -1;
1873                 break;
1874         }
1875
1876         return ret;
1877 #else
1878         return -1;
1879 #endif
1880 }
1881
1882 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
1883 {
1884 #ifdef LDAP_SLAPI
1885         return slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT );
1886 #else
1887         return -1;
1888 #endif
1889 }
1890
1891 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
1892 {
1893 #ifdef LDAP_SLAPI
1894         return slapi_valueset_first_value( &a->a_vals, v );
1895 #else
1896         return -1;
1897 #endif
1898 }
1899
1900 int slapi_attr_next_value( Slapi_Attr *a, int hint, Slapi_Value **v )
1901 {
1902 #ifdef LDAP_SLAPI
1903         return slapi_valueset_next_value( &a->a_vals, hint, v );
1904 #else
1905         return -1;
1906 #endif
1907 }
1908
1909 int slapi_attr_get_numvalues( const Slapi_Attr *a, int *numValues )
1910 {
1911 #ifdef LDAP_SLAPI
1912         *numValues = slapi_valueset_count( &a->a_vals );
1913
1914         return 0;
1915 #else
1916         return -1;
1917 #endif
1918 }
1919
1920 int slapi_attr_get_valueset( const Slapi_Attr *a, Slapi_ValueSet **vs )
1921 {
1922 #ifdef LDAP_SLAPI
1923         *vs = &((Slapi_Attr *)a)->a_vals;
1924
1925         return 0;
1926 #else
1927         return -1;
1928 #endif
1929 }
1930
1931 int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals )
1932 {
1933 #ifdef LDAP_SLAPI
1934         return slapi_attr_get_values( a, vals );
1935 #else
1936         return -1;
1937 #endif
1938 }
1939
1940 char *slapi_attr_syntax_normalize( const char *s )
1941 {
1942 #ifdef LDAP_SLAPI
1943         AttributeDescription *ad = NULL;
1944         const char *text;
1945
1946         if ( slap_str2ad( s, &ad, &text ) != LDAP_SUCCESS ) {
1947                 return NULL;
1948         }
1949
1950         return ad->ad_cname.bv_val;
1951 #else
1952         return -1;
1953 #endif
1954 }
1955
1956 Slapi_Value *slapi_value_new( void )
1957 {
1958 #ifdef LDAP_SLAPI
1959         struct berval *bv;
1960
1961         bv = (struct berval *)slapi_ch_malloc( sizeof(*bv) );
1962
1963         return bv;
1964 #else
1965         return NULL;
1966 #endif
1967 }
1968
1969 Slapi_Value *slapi_value_new_berval(const struct berval *bval)
1970 {
1971 #ifdef LDAP_SLAPI
1972         return ber_dupbv( NULL, (struct berval *)bval );
1973 #else
1974         return NULL;
1975 #endif
1976 }
1977
1978 Slapi_Value *slapi_value_new_value(const Slapi_Value *v)
1979 {
1980 #ifdef LDAP_SLAPI
1981         return slapi_value_new_berval( v );
1982 #else
1983         return NULL;
1984 #endif
1985 }
1986
1987 Slapi_Value *slapi_value_new_string(const char *s)
1988 {
1989 #ifdef LDAP_SLAPI
1990         struct berval bv;
1991
1992         bv.bv_val = (char *)s;
1993         bv.bv_len = strlen( s );
1994
1995         return slapi_value_new_berval( &bv );
1996 #else
1997         return NULL;
1998 #endif
1999 }
2000
2001 Slapi_Value *slapi_value_init(Slapi_Value *val)
2002 {
2003 #ifdef LDAP_SLAPI
2004         val->bv_val = NULL;
2005         val->bv_len = 0;
2006
2007         return val;
2008 #else
2009         return NULL;
2010 #endif
2011 }
2012
2013 Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
2014 {
2015 #ifdef LDAP_SLAPI
2016         return ber_dupbv( v, bval );
2017 #else
2018         return NULL;
2019 #endif
2020 }
2021
2022 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
2023 {
2024 #ifdef LDAP_SLAPI
2025         v->bv_val = slapi_ch_strdup( (char *)s );
2026         v->bv_len = strlen( s );
2027
2028         return v;
2029 #else
2030         return NULL;
2031 #endif
2032 }
2033
2034 Slapi_Value *slapi_value_dup(const Slapi_Value *v)
2035 {
2036 #ifdef LDAP_SLAPI
2037         return slapi_value_new_value( v );
2038 #else
2039         return NULL;
2040 #endif
2041 }
2042
2043 void slapi_value_free(Slapi_Value **value)
2044 {
2045 #ifdef LDAP_SLAPI       
2046         if ( value == NULL ) {
2047                 return;
2048         }
2049
2050         if ( (*value) != NULL ) {
2051                 slapi_ch_free( (void **)&(*value)->bv_val );
2052                 slapi_ch_free( (void **)value );
2053         }
2054 #endif
2055 }
2056
2057 const struct berval *slapi_value_get_berval( const Slapi_Value *value )
2058 {
2059 #ifdef LDAP_SLAPI
2060         return value;
2061 #else
2062         return NULL;
2063 #endif
2064 }
2065
2066 Slapi_Value *slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
2067 {
2068 #ifdef LDAP_SLAPI
2069         if ( value == NULL ) {
2070                 return NULL;
2071         }
2072         if ( value->bv_val != NULL ) {
2073                 slapi_ch_free( (void **)&value->bv_val );
2074         }
2075         slapi_value_init_berval( value, (struct berval *)bval );
2076
2077         return value;
2078 #else
2079         return NULL;
2080 #endif
2081 }
2082
2083 Slapi_Value *slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
2084 {
2085 #ifdef LDAP_SLAPI
2086         if ( value == NULL ) {
2087                 return NULL;
2088         }
2089         return slapi_value_set_berval( value, vfrom );
2090 #else
2091         return NULL;
2092 #endif
2093 }
2094
2095 Slapi_Value *slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
2096 {
2097 #ifdef LDAP_SLAPI
2098         if ( value == NULL ) {
2099                 return NULL;
2100         }
2101         if ( value->bv_val != NULL ) {
2102                 slapi_ch_free( (void **)&value->bv_val );
2103         }
2104         value->bv_val = slapi_ch_malloc( len );
2105         value->bv_len = len;
2106         AC_MEMCPY( value->bv_val, val, len );
2107
2108         return value;
2109 #else
2110         return NULL;
2111 #endif
2112 }
2113
2114 int slapi_value_set_string(Slapi_Value *value, const char *strVal)
2115 {
2116 #ifdef LDAP_SLAPI
2117         if ( value == NULL ) {
2118                 return -1;
2119         }
2120         slapi_value_set( value, (void *)strVal, strlen( strVal ) );
2121         return 0;
2122 #else
2123         return NULL;
2124 #endif
2125 }
2126
2127 int slapi_value_set_int(Slapi_Value *value, int intVal)
2128 {
2129 #ifdef LDAP_SLAPI
2130         char buf[64];
2131
2132         snprintf( buf, sizeof( buf ), "%d", intVal );
2133
2134         return slapi_value_set_string( value, buf );
2135 #else
2136         return -1;
2137 #endif
2138 }
2139
2140 const char *slapi_value_get_string(const Slapi_Value *value)
2141 {
2142 #ifdef LDAP_SLAPI
2143         if ( value == NULL ) {
2144                 return NULL;
2145         }
2146         return value->bv_val;
2147 #else
2148         return NULL;
2149 #endif
2150 }
2151
2152 #ifdef LDAP_SLAPI
2153 static int checkBVString(const struct berval *bv)
2154 {
2155         int i;
2156
2157         for ( i = 0; i < bv->bv_len; i++ ) {
2158                 if ( bv->bv_val[i] == '\0' )
2159                         return 0;
2160         }
2161         if ( bv->bv_val[i] != '\0' )
2162                 return 0;
2163
2164         return 1;
2165 }
2166 #endif
2167
2168 int slapi_value_get_int(const Slapi_Value *value)
2169 {
2170 #ifdef LDAP_SLAPI
2171         if ( value == NULL ) return 0;
2172         if ( value->bv_val == NULL ) return 0;
2173         if ( !checkBVString( value ) ) return 0;
2174
2175         return (int)strtol( value->bv_val, NULL, 10 );
2176 #else
2177         return NULL;
2178 #endif
2179 }
2180
2181 unsigned int slapi_value_get_uint(const Slapi_Value *value)
2182 {
2183 #ifdef LDAP_SLAPI
2184         if ( value == NULL ) return 0;
2185         if ( value->bv_val == NULL ) return 0;
2186         if ( !checkBVString( value ) ) return 0;
2187
2188         return (unsigned int)strtoul( value->bv_val, NULL, 10 );
2189 #else
2190         return NULL;
2191 #endif
2192 }
2193
2194 long slapi_value_get_long(const Slapi_Value *value)
2195 {
2196 #ifdef LDAP_SLAPI
2197         if ( value == NULL ) return 0;
2198         if ( value->bv_val == NULL ) return 0;
2199         if ( !checkBVString( value ) ) return 0;
2200
2201         return strtol( value->bv_val, NULL, 10 );
2202 #else
2203         return NULL;
2204 #endif
2205 }
2206
2207 unsigned long slapi_value_get_ulong(const Slapi_Value *value)
2208 {
2209 #ifdef LDAP_SLAPI
2210         if ( value == NULL ) return 0;
2211         if ( value->bv_val == NULL ) return 0;
2212         if ( !checkBVString( value ) ) return 0;
2213
2214         return strtoul( value->bv_val, NULL, 10 );
2215 #else
2216         return NULL;
2217 #endif
2218 }
2219
2220 size_t slapi_value_get_length(const Slapi_Value *value)
2221 {
2222 #ifdef LDAP_SLAPI
2223         if ( value == NULL )
2224                 return 0;
2225
2226         return (size_t) value->bv_len;
2227 #else
2228         return 0;
2229 #endif
2230 }
2231
2232 int slapi_value_compare(const Slapi_Attr *a, const Slapi_Value *v1, const Slapi_Value *v2)
2233 {
2234 #ifdef LDAP_SLAPI
2235         return slapi_attr_value_cmp( a, v1, v2 );
2236 #else
2237         return -1;
2238 #endif
2239 }
2240
2241 /* A ValueSet is a container for a BerVarray. */
2242 Slapi_ValueSet *slapi_valueset_new( void )
2243 {
2244 #ifdef LDAP_SLAPI
2245         Slapi_ValueSet *vs;
2246
2247         vs = (Slapi_ValueSet *)slapi_ch_malloc( sizeof( *vs ) );
2248         *vs = NULL;
2249
2250         return vs;
2251 #else
2252         return NULL;
2253 #endif
2254 }
2255
2256 void slapi_valueset_free(Slapi_ValueSet *vs)
2257 {
2258 #ifdef LDAP_SLAPI
2259         if ( vs != NULL ) {
2260                 BerVarray vp = *vs;
2261
2262                 ber_bvarray_free( vp );
2263                 slapi_ch_free( (void **)&vp );
2264
2265                 *vs = NULL;
2266         }
2267 #endif
2268 }
2269
2270 void slapi_valueset_init(Slapi_ValueSet *vs)
2271 {
2272 #ifdef LDAP_SLAPI
2273         if ( vs != NULL && *vs == NULL ) {
2274                 *vs = (Slapi_ValueSet)slapi_ch_calloc( 1, sizeof(struct berval) );
2275                 (*vs)->bv_val = NULL;
2276                 (*vs)->bv_len = 0;
2277         }
2278 #endif
2279 }
2280
2281 void slapi_valueset_done(Slapi_ValueSet *vs)
2282 {
2283 #ifdef LDAP_SLAPI
2284         BerVarray vp;
2285
2286         if ( vs == NULL )
2287                 return;
2288
2289         for ( vp = *vs; vp->bv_val != NULL; vp++ ) {
2290                 vp->bv_len = 0;
2291                 slapi_ch_free( (void **)&vp->bv_val );
2292         }
2293         /* but don't free *vs or vs */
2294 #endif
2295 }
2296
2297 void slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
2298 {
2299 #ifdef LDAP_SLAPI
2300         struct berval bv;
2301
2302         ber_dupbv( &bv, (Slapi_Value *)addval );
2303         ber_bvarray_add( vs, &bv );
2304 #endif
2305 }
2306
2307 int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
2308 {
2309 #ifdef LDAP_SLAPI
2310         return slapi_valueset_next_value( vs, 0, v );
2311 #else
2312         return -1;
2313 #endif
2314 }
2315
2316 int slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
2317 {
2318 #ifdef LDAP_SLAPI
2319         int i;
2320         BerVarray vp;
2321
2322         if ( vs == NULL )
2323                 return -1;
2324
2325         vp = *vs;
2326
2327         for ( i = 0; vp[i].bv_val != NULL; i++ ) {
2328                 if ( i == index ) {
2329                         *v = &vp[i];
2330                         return index + 1;
2331                 }
2332         }
2333 #endif
2334
2335         return -1;
2336 }
2337
2338 int slapi_valueset_count( const Slapi_ValueSet *vs )
2339 {
2340 #ifdef LDAP_SLAPI
2341         int i;
2342         BerVarray vp;
2343
2344         if ( vs == NULL )
2345                 return 0;
2346
2347         vp = *vs;
2348
2349         for ( i = 0; vp[i].bv_val != NULL; i++ )
2350                 ;
2351
2352         return i;
2353 #else
2354         return 0;
2355 #endif
2356
2357 }
2358
2359 void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
2360 {
2361 #ifdef LDAP_SLAPI
2362         BerVarray vp;
2363
2364         for ( vp = *vs2; vp->bv_val != NULL; vp++ ) {
2365                 slapi_valueset_add_value( vs1, vp );
2366         }
2367 #endif
2368 }
2369
2370 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
2371         struct berval *val, int access )
2372 {
2373 #ifdef LDAPI_SLAPI
2374         Backend *be;
2375         Connection *conn;
2376         Operation *op;
2377         int ret;
2378         slap_access_t slap_access;
2379         AttributeDescription *ad = NULL;
2380         char *text;
2381
2382         ret = slap_str2ad( attr, &ad, &text );
2383         if ( ret != LDAP_SUCCESS ) {
2384                 return ret;
2385         }
2386
2387         switch ( access & SLAPI_ACL_ALL ) {
2388         case SLAPI_ACL_COMPARE:
2389                 slap_access = ACL_COMPARE;
2390                 break;
2391         case SLAPI_ACL_SEARCH:
2392                 slap_access = ACL_SEARCH;
2393                 break;
2394         case SLAPI_ACL_READ:
2395                 slap_access = ACL_READ;
2396                 break;
2397         case SLAPI_ACL_WRITE:
2398         case SLAPI_ACL_DELETE:
2399         case SLAPI_ACL_ADD:
2400         case SLAPI_ACL_SELF:
2401                 slap_access = ACL_WRITE;
2402                 break;
2403         default:
2404                 return LDAP_INSUFFICIENT_ACCESS;
2405                 break;
2406         }
2407
2408         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2409                 return LDAP_PARAM_ERROR;
2410         }
2411
2412         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
2413                 return LDAP_PARAM_ERROR;
2414         }
2415
2416         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
2417                 return LDAP_PARAM_ERROR;
2418         }
2419
2420         ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL );
2421
2422         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2423 #else
2424         return LDAP_UNWILLING_TO_PERFORM;
2425 #endif
2426 }
2427
2428 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
2429 {
2430 #ifdef LDAP_SLAPI
2431         Backend *be;
2432         Connection *conn;
2433         Operation *op;
2434         int ret;
2435         Modifications *ml;
2436         Modifications *next;
2437
2438         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2439                 return LDAP_PARAM_ERROR;
2440         }
2441
2442         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
2443                 return LDAP_PARAM_ERROR;
2444         }
2445
2446         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
2447                 return LDAP_PARAM_ERROR;
2448         }
2449
2450         ml = slapi_x_ldapmods2modifications( mods );
2451         if ( ml == NULL ) {
2452                 return LDAP_OTHER;
2453         }
2454
2455         ret = acl_check_modlist( be, conn, op, e, ml );
2456
2457         /* Careful when freeing the modlist because it has pointers into the mods array. */
2458         for ( ; ml != NULL; ml = next ) {
2459                 next = ml->sml_next;
2460
2461                 /* just free the containing array */
2462                 slapi_ch_free( (void **)&ml->sml_bvalues );
2463                 slapi_ch_free( (void **)&ml );
2464         }
2465
2466         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2467 #else
2468         return LDAP_UNWILLING_TO_PERFORM;
2469 #endif
2470 }
2471
2472 /*
2473  * Synthesise an LDAPMod array from a Modifications list to pass
2474  * to SLAPI. This synthesis is destructive and as such the 
2475  * Modifications list may not be used after calling this 
2476  * function.
2477  * 
2478  * This function must also be called before slap_mods_check().
2479  */
2480 LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
2481 {
2482 #ifdef LDAP_SLAPI
2483         Modifications *ml, *modlist;
2484         LDAPMod **mods, *modp;
2485         int i, j;
2486
2487         modlist = *pmodlist;
2488
2489         for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
2490                 ;
2491
2492         mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
2493
2494         for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
2495                 modp = mods[i];
2496                 modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
2497
2498                 /* Take ownership of original type. */
2499                 modp->mod_type = ml->sml_type.bv_val;
2500                 ml->sml_type.bv_val = NULL;
2501
2502                 if ( ml->sml_bvalues != NULL ) {
2503                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
2504                                 ;
2505                         modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
2506                                 sizeof(struct berval *) );
2507                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
2508                                 /* Take ownership of original values. */
2509                                 modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
2510                                 modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
2511                                 modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
2512                                 ml->sml_bvalues[j].bv_len = 0;
2513                                 ml->sml_bvalues[j].bv_val = NULL;
2514                         }
2515                         modp->mod_bvalues[j] = NULL;
2516                 } else {
2517                         modp->mod_bvalues = NULL;
2518                 }
2519                 i++;
2520         }
2521
2522         mods[i] = NULL;
2523
2524         slap_mods_free( modlist );
2525         *pmodlist = NULL;
2526
2527         return mods;
2528 #else
2529         return NULL;
2530 #endif
2531 }
2532
2533 /*
2534  * Convert a potentially modified array of LDAPMods back to a
2535  * Modification list. 
2536  * 
2537  * The returned Modification list contains pointers into the
2538  * LDAPMods array; the latter MUST be freed with
2539  * slapi_x_free_ldapmods() (see below).
2540  */
2541 Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
2542 {
2543 #ifdef LDAP_SLAPI
2544         Modifications *modlist, **modtail;
2545         LDAPMod **modp;
2546
2547         modtail = &modlist;
2548
2549         for( modp = mods; *modp != NULL; modp++ ) {
2550                 Modifications *mod;
2551                 int i;
2552                 char **p;
2553                 struct berval **bvp;
2554
2555                 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
2556                 mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
2557                 mod->sml_type.bv_val = (*modp)->mod_type;
2558                 mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
2559                 mod->sml_desc = NULL;
2560                 mod->sml_next = NULL;
2561
2562                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2563                         for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ )
2564                                 ;
2565                 } else {
2566                         for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ )
2567                                 ;
2568                 }
2569
2570                 mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
2571
2572                 /* NB: This implicitly trusts a plugin to return valid modifications. */
2573                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2574                         for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ ) {
2575                                 mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
2576                                 mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
2577                         }
2578                 } else {
2579                         for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ ) {
2580                                 mod->sml_bvalues[i].bv_val = *p;
2581                                 mod->sml_bvalues[i].bv_len = strlen( *p );
2582                         }
2583                 }
2584                 mod->sml_bvalues[i].bv_val = NULL;
2585
2586                 *modtail = mod;
2587                 modtail = &mod->sml_next;
2588         }
2589         
2590         return modlist;
2591 #else
2592         return NULL;
2593 #endif 
2594 }
2595
2596 /*
2597  * This function only frees the parts of the mods array that
2598  * are not shared with the Modification list that was created
2599  * by slapi_x_ldapmods2modifications(). 
2600  *
2601  */
2602 void slapi_x_free_ldapmods (LDAPMod **mods)
2603 {
2604 #ifdef LDAP_SLAPI
2605         int i, j;
2606
2607         if (mods == NULL)
2608                 return;
2609
2610         for ( i = 0; mods[i] != NULL; i++ ) {
2611                 /*
2612                  * Don't free values themselves; they're owned by the
2613                  * Modification list. Do free the containing array.
2614                  */
2615                 if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
2616                         for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ ) {
2617                                 ch_free( mods[i]->mod_bvalues[j] );
2618                         }
2619                         ch_free( mods[i]->mod_bvalues );
2620                 } else {
2621                         ch_free( mods[i]->mod_values );
2622                 }
2623                 /* Don't free type, for same reasons. */
2624                 ch_free( mods[i] );
2625         }
2626         ch_free( mods );
2627 #endif /* LDAP_SLAPI */
2628 }
2629
2630 /*
2631  * Sun ONE DS 5.x computed attribute support. Computed attributes
2632  * allow for dynamically generated operational attributes, a very
2633  * useful thing indeed.
2634  */
2635
2636 /*
2637  * Write the computed attribute to a BerElement. Complementary 
2638  * functions need to be defined for anything that replaces 
2639  * op->o_callback->sc_sendentry, if you wish to make computed
2640  * attributes available to it.
2641  */
2642 int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e)
2643 {
2644 #ifdef LDAP_SLAPI
2645         Backend *be = NULL;
2646         Connection *conn = NULL;
2647         Operation *op = NULL;
2648         BerElement *ber;
2649         AttributeDescription *desc;
2650         int rc;
2651         int i;
2652
2653         if ( c == NULL ) {
2654                 return 1;
2655         }
2656
2657         if ( a == NULL ) {
2658                 return 1;
2659         }
2660
2661         if ( e == NULL ) {
2662                 return 1;
2663         }
2664
2665         rc = slapi_pblock_get( c->cac_pb, SLAPI_BACKEND, (void *)&be );
2666         if ( rc != 0 ) {
2667                 be = NULL; /* no backend for root DSE */
2668         }
2669
2670         rc = slapi_pblock_get( c->cac_pb, SLAPI_CONNECTION, (void *)&conn );
2671         if ( rc != 0 || conn == NULL ) {
2672                 return rc;
2673         }
2674
2675         rc = slapi_pblock_get( c->cac_pb, SLAPI_OPERATION, (void *)&op );
2676         if ( rc != 0 || op == NULL ) {
2677                 return rc;
2678         }
2679
2680         ber = (BerElement *)c->cac_private;
2681         desc = a->a_desc;
2682
2683         if ( c->cac_attrs == NULL ) {
2684                 /* All attrs request, skip operational attributes */
2685                 if ( is_at_operational( desc->ad_type ) ) {
2686                         return 0;
2687                 }
2688         } else {
2689                 /* Specific attrs requested */
2690                 if ( is_at_operational( desc->ad_type ) ) {
2691                         if ( !c->cac_opattrs && !ad_inlist( desc, c->cac_attrs ) ) {
2692                                 return 0;
2693                         }
2694                 } else {
2695                         if ( !c->cac_userattrs && !ad_inlist( desc, c->cac_attrs ) ) {
2696                                 return 0;
2697                         }
2698                 }
2699         }
2700
2701         if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_READ, &c->cac_acl_state) ) {
2702                 slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
2703                         "acl: access to attribute %s not allowed\n",
2704                         desc->ad_cname.bv_val );
2705                 return 0;
2706         }
2707
2708         rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
2709         if (rc == -1 ) {
2710                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
2711                         "ber_printf failed\n");
2712                 return 1;
2713         }
2714
2715         if ( !c->cac_attrsonly ) {
2716                 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
2717                         if ( !access_allowed( be, conn, op, e,
2718                                 desc, &a->a_vals[i], ACL_READ, &c->cac_acl_state)) {
2719                                 slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
2720                                         "slapi_x_compute_output_ber: conn %lu "
2721                                         "acl: access to %s, value %d not allowed\n",
2722                                         op->o_connid, desc->ad_cname.bv_val, i  );
2723                                 continue;
2724                         }
2725         
2726                         if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
2727                                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
2728                                         "ber_printf failed\n");
2729                                 return 1;
2730                         }
2731                 }
2732         }
2733
2734         if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
2735                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
2736                         "ber_printf failed\n" );
2737                 return 1;
2738         }
2739
2740         return 0;
2741 #else
2742         return 1;
2743 #endif
2744 }
2745
2746 /*
2747  * For some reason Sun don't use the normal plugin mechanism
2748  * registration path to register an "evaluator" function (an
2749  * "evaluator" is responsible for adding computed attributes;
2750  * the nomenclature is somewhat confusing).
2751  *
2752  * As such slapi_compute_add_evaluator() registers the 
2753  * function directly.
2754  */
2755 int slapi_compute_add_evaluator(slapi_compute_callback_t function)
2756 {
2757 #ifdef LDAP_SLAPI
2758         Slapi_PBlock *pPlugin = NULL;
2759         int rc;
2760
2761         pPlugin = slapi_pblock_new();
2762         if ( pPlugin == NULL ) {
2763                 rc = LDAP_NO_MEMORY;
2764                 goto done;
2765         }
2766
2767         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
2768         if ( rc != LDAP_SUCCESS ) {
2769                 goto done;
2770         }
2771
2772         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (void *)function );
2773         if ( rc != LDAP_SUCCESS ) {
2774                 goto done;
2775         }
2776
2777         rc = insertPlugin( NULL, pPlugin );
2778         if ( rc != 0 ) {
2779                 rc = LDAP_OTHER;
2780                 goto done;
2781         }
2782
2783 done:
2784         if ( rc != LDAP_SUCCESS ) {
2785                 if ( pPlugin != NULL ) {
2786                         slapi_pblock_destroy( pPlugin );
2787                 }
2788                 return -1;
2789         }
2790
2791         return 0;
2792 #else
2793         return -1;
2794 #endif /* LDAP_SLAPI */
2795 }
2796
2797 /*
2798  * See notes above regarding slapi_compute_add_evaluator().
2799  */
2800 int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
2801 {
2802 #ifdef LDAP_SLAPI
2803         Slapi_PBlock *pPlugin = NULL;
2804         int rc;
2805
2806         pPlugin = slapi_pblock_new();
2807         if ( pPlugin == NULL ) {
2808                 rc = LDAP_NO_MEMORY;
2809                 goto done;
2810         }
2811
2812         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
2813         if ( rc != LDAP_SUCCESS ) {
2814                 goto done;
2815         }
2816
2817         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, (void *)function );
2818         if ( rc != LDAP_SUCCESS ) {
2819                 goto done;
2820         }
2821
2822         rc = insertPlugin( NULL, pPlugin );
2823         if ( rc != 0 ) {
2824                 rc = LDAP_OTHER;
2825                 goto done;
2826         }
2827
2828 done:
2829         if ( rc != LDAP_SUCCESS ) {
2830                 if ( pPlugin != NULL ) {
2831                         slapi_pblock_destroy( pPlugin );
2832                 }
2833                 return -1;
2834         }
2835
2836         return 0;
2837 #else
2838         return -1;
2839 #endif /* LDAP_SLAPI */
2840 }
2841
2842 /*
2843  * Call compute evaluators
2844  */
2845 int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn)
2846 {
2847 #ifdef LDAP_SLAPI
2848         int rc = 0;
2849         slapi_compute_callback_t *pGetPlugin, *tmpPlugin;
2850
2851         rc = getAllPluginFuncs( NULL, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (SLAPI_FUNC **)&tmpPlugin );
2852         if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
2853                 /* Nothing to do; front-end should ignore. */
2854                 return 0;
2855         }
2856
2857         for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
2858                 /*
2859                  * -1: no attribute matched requested type
2860                  *  0: one attribute matched
2861                  * >0: error happened
2862                  */
2863                 rc = (*pGetPlugin)( c, type, e, outputfn );
2864                 if ( rc > 0 ) {
2865                         break;
2866                 }
2867         }
2868
2869         slapi_ch_free( (void **)&tmpPlugin );
2870
2871         return rc;
2872 #else
2873         return 1;
2874 #endif /* LDAP_SLAPI */
2875 }
2876
2877 int compute_rewrite_search_filter(Slapi_PBlock *pb)
2878 {
2879 #ifdef LDAP_SLAPI
2880         Backend *be;
2881         int rc;
2882
2883         rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be );
2884         if ( rc != 0 ) {
2885                 return rc;
2886         }
2887
2888         return doPluginFNs( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
2889 #else
2890         return -1;
2891 #endif /* LDAP_SLAPI */
2892 }
2893
2894 /*
2895  * New API to provide the plugin with access to the search
2896  * pblock. Have informed Sun DS team.
2897  */
2898 int slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
2899 {
2900 #ifdef LDAP_SLAPI
2901         if ( c == NULL )
2902                 return -1;
2903
2904         if ( c->cac_pb == NULL )
2905                 return -1;
2906
2907         *pb = c->cac_pb;
2908
2909         return 0;
2910 #else
2911         return -1;
2912 #endif /* LDAP_SLAPI */
2913 }
2914
2915 Slapi_Mutex *slapi_new_mutex( void )
2916 {
2917 #ifdef LDAP_SLAPI
2918         Slapi_Mutex *m;
2919
2920         m = (Slapi_Mutex *)slapi_ch_malloc( sizeof(*m) );
2921         if ( ldap_pvt_thread_mutex_init( &m->mutex ) != 0 ) {
2922                 slapi_ch_free( (void **)&m );
2923                 return NULL;
2924         }
2925
2926         return m;
2927 #else
2928         return NULL;
2929 #endif
2930 }
2931
2932 void slapi_destroy_mutex( Slapi_Mutex *mutex )
2933 {
2934 #ifdef LDAP_SLAPI
2935         if ( mutex != NULL ) {
2936                 ldap_pvt_thread_mutex_destroy( &mutex->mutex );
2937                 slapi_ch_free( (void **)&mutex);
2938         }
2939 #endif
2940 }
2941
2942 void slapi_lock_mutex( Slapi_Mutex *mutex )
2943 {
2944 #ifdef LDAP_SLAPI
2945         ldap_pvt_thread_mutex_lock( &mutex->mutex );
2946 #endif
2947 }
2948
2949 int slapi_unlock_mutex( Slapi_Mutex *mutex )
2950 {
2951 #ifdef LDAP_SLAPI
2952         return ldap_pvt_thread_mutex_unlock( &mutex->mutex );
2953 #else
2954         return -1;
2955 #endif
2956 }
2957
2958 Slapi_CondVar *slapi_new_condvar( Slapi_Mutex *mutex )
2959 {
2960 #ifdef LDAP_SLAPI
2961         Slapi_CondVar *cv;
2962
2963         if ( mutex == NULL ) {
2964                 return NULL;
2965         }
2966
2967         cv = (Slapi_CondVar *)slapi_ch_malloc( sizeof(*cv) );
2968         if ( ldap_pvt_thread_cond_init( &cv->cond ) != 0 ) {
2969                 slapi_ch_free( (void **)&cv );
2970                 return NULL;
2971         }
2972
2973         /* XXX struct copy */
2974         cv->mutex = mutex->mutex;
2975
2976         return cv;
2977 #else   
2978         return NULL;
2979 #endif
2980 }
2981
2982 void slapi_destroy_condvar( Slapi_CondVar *cvar )
2983 {
2984 #ifdef LDAP_SLAPI
2985         if ( cvar != NULL ) {
2986                 ldap_pvt_thread_cond_destroy( &cvar->cond );
2987                 slapi_ch_free( (void **)&cvar );
2988         }
2989 #endif
2990 }
2991
2992 int slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout )
2993 {
2994 #ifdef LDAP_SLAPI
2995         if ( cvar == NULL ) {
2996                 return -1;
2997         }
2998
2999         return ldap_pvt_thread_cond_wait( &cvar->cond, &cvar->mutex );
3000 #else
3001         return -1;
3002 #endif
3003 }
3004
3005 int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
3006 {
3007 #ifdef LDAP_SLAPI
3008         if ( cvar == NULL ) {
3009                 return -1;
3010         }
3011
3012         if ( notify_all ) {
3013                 return ldap_pvt_thread_cond_broadcast( &cvar->cond );
3014         }
3015
3016         return ldap_pvt_thread_cond_signal( &cvar->cond );
3017 #else
3018         return -1;
3019 #endif
3020 }
3021