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