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