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