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