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