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