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