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