]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
a89cf6db8915023c46408f10c9d16541d73da44a
[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. 2003
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
22 #include <ac/string.h>
23 #include <ac/stdarg.h>
24 #include <ac/ctype.h>
25 #include <ac/unistd.h>
26 #include <ldap_pvt.h>
27
28 #include <slap.h>
29 #include <slapi.h>
30
31 struct berval *ns_get_supported_extop( int );
32
33 #ifdef _SPARC  
34 #include <sys/systeminfo.h>
35 #endif
36
37 #include <netdb.h>
38
39 /*
40  * server start time (should we use a struct timeval also in slapd?
41  */
42 static struct                   timeval base_time;
43 ldap_pvt_thread_mutex_t         slapi_hn_mutex;
44 ldap_pvt_thread_mutex_t         slapi_time_mutex;
45
46 struct slapi_mutex {
47         ldap_pvt_thread_mutex_t mutex;
48 };
49
50 struct slapi_condvar {
51         ldap_pvt_thread_cond_t cond;
52         ldap_pvt_thread_mutex_t mutex;
53 };
54
55 /*
56  * This function converts an array of pointers to berval objects to
57  * an array of berval objects.
58  */
59
60 int
61 bvptr2obj(
62         struct berval   **bvptr, 
63         BerVarray       *bvobj )
64 {
65         int             rc = LDAP_SUCCESS;
66         int             i;
67         BerVarray       tmpberval;
68
69         if ( bvptr == NULL || *bvptr == NULL ) {
70                 return LDAP_OTHER;
71         }
72
73         for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
74                 ; /* EMPTY */
75         }
76
77         tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
78         if ( tmpberval == NULL ) {
79                 return LDAP_NO_MEMORY;
80         } 
81
82         for ( i = 0; bvptr[i] != NULL; i++ ) {
83                 tmpberval[i].bv_val = bvptr[i]->bv_val;
84                 tmpberval[i].bv_len = bvptr[i]->bv_len;
85         }
86         tmpberval[i].bv_val = NULL;
87         tmpberval[i].bv_len = 0;
88
89         if ( rc == LDAP_SUCCESS ) {
90                 *bvobj = tmpberval;
91         }
92
93         return rc;
94 }
95
96 Slapi_Entry *
97 slapi_str2entry(
98         char            *s, 
99         int             check_dup )
100 {
101 #ifdef LDAP_SLAPI
102         Slapi_Entry     *e = NULL;
103         char            *pTmpS;
104
105         pTmpS = slapi_ch_strdup( s );
106         if ( pTmpS != NULL ) {
107                 e = str2entry( pTmpS ); 
108                 slapi_ch_free( (void **)&pTmpS );
109         }
110
111         return e;
112 #else
113         return NULL;
114 #endif /* LDAP_SLAPI */
115 }
116
117 char *
118 slapi_entry2str(
119         Slapi_Entry     *e, 
120         int             *len ) 
121 {
122 #ifdef LDAP_SLAPI
123         char            *ret;
124
125         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
126         ret = entry2str( e, len );
127         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
128
129         return ret;
130 #else /* LDAP_SLAPI */
131         return NULL;
132 #endif /* LDAP_SLAPI */
133 }
134
135 char *
136 slapi_entry_get_dn( Slapi_Entry *e ) 
137 {
138 #ifdef LDAP_SLAPI
139         return e->e_name.bv_val;
140 #else /* LDAP_SLAPI */
141         return NULL;
142 #endif /* LDAP_SLAPI */
143 }
144
145 int
146 slapi_x_entry_get_id( Slapi_Entry *e )
147 {
148 #ifdef LDAP_SLAPI
149         return e->e_id;
150 #else
151         return NOID;
152 #endif /* LDAP_SLAPI */
153 }
154
155 void 
156 slapi_entry_set_dn(
157         Slapi_Entry     *e, 
158         char            *ldn )
159 {
160 #ifdef LDAP_SLAPI
161         struct berval   dn = { 0, NULL };
162
163         dn.bv_val = ldn;
164         dn.bv_len = strlen( ldn );
165
166         dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
167 #endif /* LDAP_SLAPI */
168 }
169
170 Slapi_Entry *
171 slapi_entry_dup( Slapi_Entry *e ) 
172 {
173 #ifdef LDAP_SLAPI
174         char            *tmp = NULL;
175         Slapi_Entry     *tmpEnt;
176         int             len = 0;
177         
178         tmp = slapi_entry2str( e, &len );
179         if ( tmp == NULL ) {
180                 return (Slapi_Entry *)NULL;
181         }
182
183         tmpEnt = (Slapi_Entry *)str2entry( tmp );
184         if ( tmpEnt == NULL ) { 
185                 slapi_ch_free( (void **)&tmp );
186                 return (Slapi_Entry *)NULL;
187         }
188         
189         if (tmp != NULL) {
190                 slapi_ch_free( (void **)&tmp );
191         }
192
193         return tmpEnt;
194 #else /* LDAP_SLAPI */
195         return NULL;
196 #endif /* LDAP_SLAPI */
197 }
198
199 int 
200 slapi_entry_attr_delete(
201         Slapi_Entry     *e,             
202         char            *type ) 
203 {
204 #ifdef LDAP_SLAPI
205         AttributeDescription    *ad = NULL;
206         const char              *text;
207
208         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
209                 return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
210         }
211
212         if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
213                 return 0;       /* attribute is deleted */
214         } else {
215                 return -1;      /* something went wrong */
216         }
217 #else /* LDAP_SLAPI */
218         return -1;
219 #endif /* LDAP_SLAPI */
220 }
221
222 Slapi_Entry *
223 slapi_entry_alloc( void ) 
224 {
225 #ifdef LDAP_SLAPI
226         return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
227 #else /* LDAP_SLAPI */
228         return NULL;
229 #endif /* LDAP_SLAPI */
230 }
231
232 void 
233 slapi_entry_free( Slapi_Entry *e ) 
234 {
235 #ifdef LDAP_SLAPI
236         entry_free( e );
237 #endif /* LDAP_SLAPI */
238 }
239
240 int 
241 slapi_entry_attr_merge(
242         Slapi_Entry     *e, 
243         char            *type, 
244         struct berval   **vals ) 
245 {
246 #ifdef LDAP_SLAPI
247         AttributeDescription    *ad = NULL;
248         const char              *text;
249         BerVarray               bv;
250         int                     rc;
251
252         rc = bvptr2obj( vals, &bv );
253         if ( rc != LDAP_SUCCESS ) {
254                 return -1;
255         }
256         
257         rc = slap_str2ad( type, &ad, &text );
258         if ( rc != LDAP_SUCCESS ) {
259                 return -1;
260         }
261         
262         rc = attr_merge( e, ad, bv );
263         ch_free( bv );
264
265         return rc;
266 #else /* LDAP_SLAPI */
267         return -1;
268 #endif /* LDAP_SLAPI */
269 }
270
271 int
272 slapi_entry_attr_find(
273         Slapi_Entry     *e, 
274         char            *type, 
275         Slapi_Attr      **attr ) 
276 {
277 #ifdef LDAP_SLAPI
278         AttributeDescription    *ad = NULL;
279         const char              *text;
280         int                     rc;
281
282         rc = slap_str2ad( type, &ad, &text );
283         if ( rc != LDAP_SUCCESS ) {
284                 return -1;
285         }
286
287         *attr = attr_find( e->e_attrs, ad );
288         if ( *attr == NULL ) {
289                 return -1;
290         }
291
292         return 0;
293 #else /* LDAP_SLAPI */
294         return -1;
295 #endif /* LDAP_SLAPI */
296 }
297
298 char *
299 slapi_entry_attr_get_charptr( const Slapi_Entry *e, const char *type )
300 {
301 #ifdef LDAP_SLAPI
302         AttributeDescription *ad = NULL;
303         const char *text;
304         int rc;
305         Attribute *attr;
306
307         rc = slap_str2ad( type, &ad, &text );
308         if ( rc != LDAP_SUCCESS ) {
309                 return NULL;
310         }
311
312         attr = attr_find( e->e_attrs, ad );
313         if ( attr == NULL ) {
314                 return NULL;
315         }
316
317         if ( attr->a_vals != NULL && attr->a_vals[0].bv_val != NULL ) {
318                 return slapi_ch_strdup( attr->a_vals[0].bv_val );
319         }
320
321         return NULL;
322 #else
323         return -1;
324 #endif
325 }
326
327 int
328 slapi_entry_attr_get_int( const Slapi_Entry *e, const char *type )
329 {
330 #ifdef LDAP_SLAPI
331         AttributeDescription *ad = NULL;
332         const char *text;
333         int rc;
334         Attribute *attr;
335
336         rc = slap_str2ad( type, &ad, &text );
337         if ( rc != LDAP_SUCCESS ) {
338                 return 0;
339         }
340
341         attr = attr_find( e->e_attrs, ad );
342         if ( attr == NULL ) {
343                 return 0;
344         }
345
346         return slapi_value_get_int( attr->a_vals );
347 #else
348         return 0;
349 #endif
350 }
351
352 int
353 slapi_entry_attr_get_long( const Slapi_Entry *e, const char *type )
354 {
355 #ifdef LDAP_SLAPI
356         AttributeDescription *ad = NULL;
357         const char *text;
358         int rc;
359         Attribute *attr;
360
361         rc = slap_str2ad( type, &ad, &text );
362         if ( rc != LDAP_SUCCESS ) {
363                 return 0;
364         }
365
366         attr = attr_find( e->e_attrs, ad );
367         if ( attr == NULL ) {
368                 return 0;
369         }
370
371         return slapi_value_get_long( attr->a_vals );
372 #else
373         return 0;
374 #endif
375 }
376
377 int
378 slapi_entry_attr_get_uint( const Slapi_Entry *e, const char *type )
379 {
380 #ifdef LDAP_SLAPI
381         AttributeDescription *ad = NULL;
382         const char *text;
383         int rc;
384         Attribute *attr;
385
386         rc = slap_str2ad( type, &ad, &text );
387         if ( rc != LDAP_SUCCESS ) {
388                 return 0;
389         }
390
391         attr = attr_find( e->e_attrs, ad );
392         if ( attr == NULL ) {
393                 return 0;
394         }
395
396         return slapi_value_get_uint( attr->a_vals );
397 #else
398         return 0;
399 #endif
400 }
401
402 int
403 slapi_entry_attr_get_ulong( const Slapi_Entry *e, const char *type )
404 {
405 #ifdef LDAP_SLAPI
406         AttributeDescription *ad = NULL;
407         const char *text;
408         int rc;
409         Attribute *attr;
410
411         rc = slap_str2ad( type, &ad, &text );
412         if ( rc != LDAP_SUCCESS ) {
413                 return 0;
414         }
415
416         attr = attr_find( e->e_attrs, ad );
417         if ( attr == NULL ) {
418                 return 0;
419         }
420
421         return slapi_value_get_ulong( attr->a_vals );
422 #else
423         return 0;
424 #endif
425 }
426
427 int
428 slapi_entry_attr_hasvalue( Slapi_Entry *e, const char *type, const char *value )
429 {
430 #ifdef LDAP_SLAPI
431         struct berval bv;
432         AttributeDescription *ad = NULL;
433         const char *text;
434         int rc;
435         Attribute *attr;
436         
437         rc = slap_str2ad( type, &ad, &text );
438         if ( rc != LDAP_SUCCESS ) {
439                 return 0;
440         }
441
442         attr = attr_find( e->e_attrs, ad );
443         if ( attr == NULL ) {
444                 return 0;
445         }
446
447         bv.bv_val = (char *)value;
448         bv.bv_len = strlen( value );
449
450         return ( slapi_attr_value_find( attr, &bv ) != -1 );
451 #else
452         return 0;
453 #endif
454 }
455
456 void
457 slapi_entry_attr_set_charptr(Slapi_Entry* e, const char *type, const char *value)
458 {
459 #ifdef LDAP_SLAPI
460         AttributeDescription    *ad = NULL;
461         const char              *text;
462         int                     rc;
463         struct berval           bv;
464         
465         rc = slap_str2ad( type, &ad, &text );
466         if ( rc != LDAP_SUCCESS ) {
467                 return;
468         }
469         
470         attr_delete ( &e->e_attrs, ad );
471         if ( value != NULL ) {
472                 bv.bv_val = (char *)value;
473                 bv.bv_len = strlen(value);
474                 attr_merge_one ( e, ad, &bv );
475         }
476 #endif /* LDAP_SLAPI */
477 }
478
479 void
480 slapi_entry_attr_set_int( Slapi_Entry* e, const char *type, int l)
481 {
482 #ifdef LDAP_SLAPI
483         char buf[64];
484
485         snprintf( buf, sizeof( buf ), "%d", l );
486         slapi_entry_attr_set_charptr( e, type, buf );
487 #endif /* LDAP_SLAPI */
488 }
489
490 void
491 slapi_entry_attr_set_uint( Slapi_Entry* e, const char *type, unsigned int l)
492 {
493 #ifdef LDAP_SLAPI
494         char buf[64];
495
496         snprintf( buf, sizeof( buf ), "%u", l );
497         slapi_entry_attr_set_charptr( e, type, buf );
498 #endif /* LDAP_SLAPI */
499 }
500
501 void
502 slapi_entry_attr_set_long(Slapi_Entry* e, const char *type, long l)
503 {
504 #ifdef LDAP_SLAPI
505         char buf[64];
506
507         snprintf( buf, sizeof( buf ), "%ld", l );
508         slapi_entry_attr_set_charptr( e, type, buf );
509 #endif /* LDAP_SLAPI */
510 }
511
512 void
513 slapi_entry_attr_set_ulong(Slapi_Entry* e, const char *type, unsigned long l)
514 {
515 #ifdef LDAP_SLAPI
516         char buf[64];
517
518         snprintf( buf, sizeof( buf ), "%lu", l );
519         slapi_entry_attr_set_charptr( e, type, buf );
520 #endif /* LDAP_SLAPI */
521 }
522
523 int
524 slapi_is_rootdse( const char *dn )
525 {
526 #ifdef LDAP_SLAPI
527         return ( dn == NULL || dn[0] == '\0' );
528 #else
529         return 0;
530 #endif
531 }
532
533 /*
534  * Add values to entry.
535  *
536  * Returns:
537  *      LDAP_SUCCESS                    Values added to entry
538  *      LDAP_TYPE_OR_VALUE_EXISTS       One or more values exist in entry already
539  *      LDAP_CONSTRAINT_VIOLATION       Any other error (odd, but it's the spec)
540  */
541 int
542 slapi_entry_add_values( Slapi_Entry *e, const char *type, struct berval **vals )
543 {
544 #ifdef LDAP_SLAPI
545         Modification            mod;
546         const char              *text;
547         int                     rc;
548         char                    textbuf[SLAP_TEXT_BUFLEN];
549
550         mod.sm_op = LDAP_MOD_ADD;
551         mod.sm_desc = NULL;
552         mod.sm_type.bv_val = (char *)type;
553         mod.sm_type.bv_len = strlen( type );
554
555         rc = slap_str2ad( type, &mod.sm_desc, &text );
556         if ( rc != LDAP_SUCCESS ) {
557                 return rc;
558         }
559
560         if ( vals == NULL ) {
561                 /* Apparently vals can be NULL */ 
562                 mod.sm_bvalues = (BerVarray)ch_malloc( sizeof(struct berval) );
563                 mod.sm_bvalues->bv_val = NULL;
564         } else {
565                 rc = bvptr2obj( vals, &mod.sm_bvalues );
566                 if ( rc != LDAP_SUCCESS ) {
567                         return LDAP_CONSTRAINT_VIOLATION;
568                 }
569         }
570
571         rc = modify_add_values( e, &mod, 0, &text, textbuf, sizeof(textbuf) );
572
573         ch_free( mod.sm_bvalues );
574
575         return (rc == LDAP_SUCCESS) ? LDAP_SUCCESS : LDAP_CONSTRAINT_VIOLATION;
576 #else
577         return -1;
578 #endif /* LDAP_SLAPI */
579 }
580
581 int
582 slapi_entry_add_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
583 {
584 #ifdef LDAP_SLAPI
585         return slapi_entry_add_values( e, type, vals );
586 #else
587         return -1;
588 #endif /* LDAP_SLAPI */
589 }
590
591 int
592 slapi_entry_add_valueset(Slapi_Entry *e, const char *type, Slapi_ValueSet *vs)
593 {
594 #ifdef LDAP_SLAPI
595         AttributeDescription    *ad = NULL;
596         const char              *text;
597         int                     rc;
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 = NULL;
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 #ifdef 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 /* LDAP_SLAPI */
842         return -1;
843 #endif /* LDAP_SLAPI */
844 }
845
846 char *
847 slapi_dn_normalize( char *dn ) 
848 {
849 #ifdef 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 /* LDAP_SLAPI */
868         return NULL;
869 #endif /* 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 #ifdef LDAP_SLAPI
882         slapi_dn_normalize( dn );
883         ldap_pvt_str2lower( dn );
884
885         return dn;
886 #else /* LDAP_SLAPI */
887         return NULL;
888 #endif /* LDAP_SLAPI */
889 }
890
891 int 
892 slapi_dn_issuffix(
893         char            *dn, 
894         char            *suffix )
895 {
896 #ifdef 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 /* LDAP_SLAPI */
914         return 0;
915 #endif /* LDAP_SLAPI */
916 }
917
918 char *
919 slapi_dn_ignore_case( char *dn )
920 {       
921 #ifdef LDAP_SLAPI
922         return slapi_dn_normalize_case( dn );
923 #else /* LDAP_SLAPI */
924         return NULL;
925 #endif /* LDAP_SLAPI */
926 }
927
928 char *
929 slapi_ch_malloc( unsigned long size ) 
930 {
931 #ifdef LDAP_SLAPI
932         return ch_malloc( size );       
933 #else /* LDAP_SLAPI */
934         return NULL;
935 #endif /* LDAP_SLAPI */
936 }
937
938 void 
939 slapi_ch_free( void **ptr ) 
940 {
941 #ifdef LDAP_SLAPI
942         ch_free( *ptr );
943         *ptr = NULL;
944 #endif /* LDAP_SLAPI */
945 }
946
947 void 
948 slapi_ch_free_string( char **ptr ) 
949 {
950 #ifdef LDAP_SLAPI
951         slapi_ch_free( (void **)ptr );
952 #endif /* 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 #ifdef LDAP_SLAPI
1020         return ch_calloc( nelem, size );
1021 #else /* LDAP_SLAPI */
1022         return NULL;
1023 #endif /* LDAP_SLAPI */
1024 }
1025
1026 char *
1027 slapi_ch_realloc(
1028         char *block, 
1029         unsigned long size ) 
1030 {
1031 #ifdef LDAP_SLAPI
1032         return ch_realloc( block, size );
1033 #else /* LDAP_SLAPI */
1034         return NULL;
1035 #endif /* LDAP_SLAPI */
1036 }
1037
1038 char *
1039 slapi_ch_strdup( char *s ) 
1040 {
1041 #ifdef LDAP_SLAPI
1042         return ch_strdup( (const char *)s );
1043 #else /* LDAP_SLAPI */
1044         return NULL;
1045 #endif /* LDAP_SLAPI */
1046 }
1047
1048 size_t
1049 slapi_ch_stlen( char *s ) 
1050 {
1051 #ifdef LDAP_SLAPI
1052         return strlen( (const char *)s );
1053 #else /* LDAP_SLAPI */
1054         return 0;
1055 #endif /* 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 #ifdef 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 /* LDAP_SLAPI */
1122         return 0;
1123 #endif /* LDAP_SLAPI */
1124 }
1125
1126 void 
1127 slapi_register_supported_control(
1128         char            *controloid, 
1129         unsigned long   controlops )
1130 {
1131 #ifdef 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 /* LDAP_SLAPI */
1136 }
1137
1138 int 
1139 slapi_get_supported_controls(
1140         char            ***ctrloidsp, 
1141         unsigned long   **ctrlopsp ) 
1142 {
1143 #ifdef 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 /* LDAP_SLAPI */
1203         return 1;
1204 #endif /* LDAP_SLAPI */
1205 }
1206
1207 void 
1208 slapi_register_supported_saslmechanism( char *mechanism )
1209 {
1210 #ifdef 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 /* LDAP_SLAPI */
1215 }
1216
1217 char **
1218 slapi_get_supported_saslmechanisms( void )
1219 {
1220 #ifdef 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 /* LDAP_SLAPI */
1227         return NULL;
1228 #endif /* LDAP_SLAPI */
1229 }
1230
1231 char **
1232 slapi_get_supported_extended_ops( void )
1233 {
1234 #ifdef 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 /* LDAP_SLAPI */
1274         return NULL;
1275 #endif /* 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 #ifdef 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 /* 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 #ifdef 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 /* LDAP_SLAPI */
1360         return -1;
1361 #endif /* LDAP_SLAPI */
1362 }
1363
1364
1365 Slapi_Filter *
1366 slapi_str2filter( char *str ) 
1367 {
1368 #ifdef LDAP_SLAPI
1369         return str2filter( str );
1370 #else /* LDAP_SLAPI */
1371         return NULL;
1372 #endif /* LDAP_SLAPI */
1373 }
1374
1375 void 
1376 slapi_filter_free(
1377         Slapi_Filter    *f, 
1378         int             recurse ) 
1379 {
1380 #ifdef LDAP_SLAPI
1381         filter_free( f );
1382 #endif /* LDAP_SLAPI */
1383 }
1384
1385 Slapi_Filter *
1386 slapi_filter_dup( Slapi_Filter *filter )
1387 {
1388 #ifdef LDAP_SLAPI
1389         Filter *f;
1390
1391         f = (Filter *) slapi_ch_malloc( sizeof(Filter) );
1392         f->f_next = NULL;
1393         f->f_choice = filter->f_choice;
1394
1395         switch ( f->f_choice ) {
1396         case LDAP_FILTER_AND:
1397         case LDAP_FILTER_NOT:
1398         case LDAP_FILTER_OR: {
1399                 Filter *pFilter, **ppF;
1400
1401                 for ( pFilter = filter->f_list, ppF = &f->f_list;
1402                       pFilter != NULL;
1403                       pFilter = pFilter->f_next, ppF = &f->f_next )
1404                 {
1405                         *ppF = slapi_filter_dup( pFilter );
1406                         if ( *ppF == NULL )
1407                                 break;
1408                 }
1409                 break;
1410         }
1411         case LDAP_FILTER_PRESENT:
1412                 f->f_desc = filter->f_desc;
1413                 break;
1414         case LDAP_FILTER_EQUALITY:
1415         case LDAP_FILTER_GE:
1416         case LDAP_FILTER_LE:
1417         case LDAP_FILTER_APPROX:
1418                 f->f_ava = (AttributeAssertion *)slapi_ch_malloc( sizeof(AttributeAssertion) );
1419                 f->f_ava->aa_desc = filter->f_ava->aa_desc;
1420                 ber_dupbv( &f->f_ava->aa_value, &filter->f_ava->aa_value );
1421                 break;
1422         case LDAP_FILTER_EXT:
1423                 f->f_mra = (MatchingRuleAssertion *)slapi_ch_malloc( sizeof(MatchingRuleAssertion) );
1424                 f->f_mra->ma_rule = filter->f_mra->ma_rule;
1425                 f->f_mra->ma_rule_text = filter->f_mra->ma_rule_text; /* struct copy */
1426                 f->f_mra->ma_desc = filter->f_mra->ma_desc;
1427                 f->f_mra->ma_dnattrs = filter->f_mra->ma_dnattrs;
1428                 ber_dupbv( &f->f_mra->ma_value, &filter->f_mra->ma_value );
1429         case LDAP_FILTER_SUBSTRINGS: {
1430                 int i;
1431
1432                 f->f_sub = (SubstringsAssertion *)slapi_ch_malloc( sizeof(SubstringsAssertion) );
1433                 ber_dupbv( &f->f_sub_initial, &filter->f_sub_initial );
1434                 for ( i = 0; filter->f_sub_any[i].bv_val != NULL; i++ )
1435                         ;
1436                 f->f_sub_any = (BerVarray)slapi_ch_malloc( (i + 1) * (sizeof(struct berval)) );
1437                 for ( i = 0; filter->f_sub_any[i].bv_val != NULL; i++ ) {
1438                         ber_dupbv( &f->f_sub_any[i], &filter->f_sub_any[i] );
1439                 }
1440                 f->f_sub_any[i].bv_val = NULL;
1441                 ber_dupbv( &f->f_sub_final, &filter->f_sub_final );
1442                 break;
1443         }
1444         case SLAPD_FILTER_COMPUTED:
1445                 f->f_result = filter->f_result;
1446                 break;
1447         default:
1448                 slapi_ch_free( (void **)&f );
1449                 f = NULL;
1450                 break;
1451         }
1452
1453         return f;
1454 #else
1455         return NULL;
1456 #endif /* LDAP_SLAPI */
1457 }
1458
1459 int 
1460 slapi_filter_get_choice( Slapi_Filter *f )
1461 {
1462 #ifdef LDAP_SLAPI
1463         int             rc;
1464
1465         if ( f != NULL ) {
1466                 rc = f->f_choice;
1467         } else {
1468                 rc = 0;
1469         }
1470
1471         return rc;
1472 #else /* LDAP_SLAPI */
1473         return -1;              /* invalid filter type */
1474 #endif /* LDAP_SLAPI */
1475 }
1476
1477 int 
1478 slapi_filter_get_ava(
1479         Slapi_Filter    *f, 
1480         char            **type, 
1481         struct berval   **bval )
1482 {
1483 #ifdef LDAP_SLAPI
1484         int             ftype;
1485         int             rc = LDAP_SUCCESS;
1486
1487         assert( type != NULL );
1488         assert( bval != NULL );
1489
1490         *type = NULL;
1491         *bval = NULL;
1492
1493         ftype = f->f_choice;
1494         if ( ftype == LDAP_FILTER_EQUALITY 
1495                         || ftype ==  LDAP_FILTER_GE 
1496                         || ftype == LDAP_FILTER_LE 
1497                         || ftype == LDAP_FILTER_APPROX ) {
1498                 /*
1499                  * According to the SLAPI Reference Manual these are
1500                  * not duplicated.
1501                  */
1502                 *type = f->f_un.f_un_ava->aa_desc->ad_cname.bv_val;
1503                 *bval = &f->f_un.f_un_ava->aa_value;
1504         } else { /* filter type not supported */
1505                 rc = -1;
1506         }
1507
1508         return rc;
1509 #else /* LDAP_SLAPI */
1510         return -1;
1511 #endif /* LDAP_SLAPI */
1512 }
1513
1514 Slapi_Filter *
1515 slapi_filter_list_first( Slapi_Filter *f )
1516 {
1517 #ifdef LDAP_SLAPI
1518         int             ftype;
1519
1520         if ( f == NULL ) {
1521                 return NULL;
1522         }
1523
1524         ftype = f->f_choice;
1525         if ( ftype == LDAP_FILTER_AND
1526                         || ftype == LDAP_FILTER_OR
1527                         || ftype == LDAP_FILTER_NOT ) {
1528                 return (Slapi_Filter *)f->f_and;
1529         } else {
1530                 return NULL;
1531         }
1532 #else /* LDAP_SLAPI */
1533         return NULL;
1534 #endif /* LDAP_SLAPI */
1535 }
1536
1537 Slapi_Filter *
1538 slapi_filter_list_next(
1539         Slapi_Filter    *f, 
1540         Slapi_Filter    *fprev )
1541 {
1542 #ifdef LDAP_SLAPI
1543         int             ftype;
1544
1545         if ( f == NULL ) {
1546                 return NULL;
1547         }
1548
1549         ftype = f->f_choice;
1550         if ( ftype == LDAP_FILTER_AND
1551                         || ftype == LDAP_FILTER_OR
1552                         || ftype == LDAP_FILTER_NOT )
1553         {
1554                 return fprev->f_next;
1555         }
1556
1557         return NULL;
1558 #else /* LDAP_SLAPI */
1559         return NULL;
1560 #endif /* LDAP_SLAPI */
1561 }
1562
1563 int
1564 slapi_filter_get_attribute_type( Slapi_Filter *f, char **type )
1565 {
1566 #ifdef LDAP_SLAPI
1567         if ( f == NULL ) {
1568                 return -1;
1569         }
1570
1571         switch ( f->f_choice ) {
1572         case LDAP_FILTER_GE:
1573         case LDAP_FILTER_LE:
1574         case LDAP_FILTER_EQUALITY:
1575         case LDAP_FILTER_APPROX:
1576                 *type = f->f_av_desc->ad_cname.bv_val;
1577                 break;
1578         case LDAP_FILTER_SUBSTRINGS:
1579                 *type = f->f_sub_desc->ad_cname.bv_val;
1580                 break;
1581         case LDAP_FILTER_PRESENT:
1582                 *type = f->f_desc->ad_cname.bv_val;
1583                 break;
1584         case LDAP_FILTER_EXT:
1585                 *type = f->f_mr_desc->ad_cname.bv_val;
1586                 break;
1587         default:
1588                 /* Complex filters need not apply. */
1589                 *type = NULL;
1590                 return -1;
1591         }
1592
1593         return 0;
1594 #else
1595         return -1;
1596 #endif /* LDAP_SLAPI */
1597 }
1598
1599 int
1600 slapi_filter_get_subfilt( Slapi_Filter *f, char **type, char **initial,
1601         char ***any, char **final )
1602 {
1603 #ifdef LDAP_SLAPI
1604         int i;
1605
1606         if ( f->f_choice != LDAP_FILTER_SUBSTRINGS ) {
1607                 return -1;
1608         }
1609
1610         /*
1611          * The caller shouldn't free but we can't return an
1612          * array of char *s from an array of bervals without
1613          * allocating memory, so we may as well be consistent.
1614          * XXX
1615          */
1616         *type = f->f_sub_desc->ad_cname.bv_val;
1617         *initial = f->f_sub_initial.bv_val ? slapi_ch_strdup(f->f_sub_initial.bv_val) : NULL;
1618         for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ )
1619                 ;
1620         *any = (char **)slapi_ch_malloc( (i + 1) * sizeof(char *) );
1621         for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
1622                 (*any)[i] = slapi_ch_strdup(f->f_sub_any[i].bv_val);
1623         }
1624         (*any)[i] = NULL;
1625         *final = f->f_sub_final.bv_val ? slapi_ch_strdup(f->f_sub_final.bv_val) : NULL;
1626
1627         return 0;
1628 #else
1629         return -1;
1630 #endif /* LDAP_SLAPI */
1631 }
1632
1633 Slapi_Filter *
1634 slapi_filter_join( int ftype, Slapi_Filter *f1, Slapi_Filter *f2)
1635 {
1636 #ifdef LDAP_SLAPI
1637         Slapi_Filter *f = NULL;
1638
1639         if ( ftype == LDAP_FILTER_AND ||
1640              ftype == LDAP_FILTER_OR ||
1641              ftype == LDAP_FILTER_NOT )
1642         {
1643                 f = (Slapi_Filter *)slapi_ch_malloc( sizeof(*f) );
1644                 f->f_choice = ftype;
1645                 f->f_list = f1;
1646                 f->f_next = f2;
1647         }
1648
1649         return f;
1650 #else
1651         return NULL;
1652 #endif /* LDAP_SLAPI */
1653 }
1654
1655 int
1656 slapi_filter_test( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Filter *f,
1657         int verify_access )
1658 {
1659 #ifdef LDAP_SLAPI
1660         Backend *be = NULL;
1661         Connection *conn;
1662         Operation *op;
1663         int rc;
1664
1665         if ( f == NULL ) {
1666                 /* spec says return zero if no filter. */
1667                 return 0;
1668         }
1669
1670         if ( verify_access ) {
1671                 (void) slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be);
1672                 rc = slapi_pblock_get(pb, SLAPI_CONNECTION, (void *)&conn);
1673                 if ( rc != 0 ) {
1674                         return LDAP_PARAM_ERROR;
1675                 }
1676                 rc = slapi_pblock_get(pb, SLAPI_OPERATION, (void *)&op);
1677                 if ( rc != 0 ) {
1678                         return LDAP_PARAM_ERROR;
1679                 }
1680         } else {
1681                 conn = NULL;
1682                 op = NULL;
1683         }
1684         /*
1685          * According to acl.c it is safe to call test_filter() with
1686          * NULL arguments...
1687          */
1688         rc = test_filter( be, conn, op, e, f );
1689         switch (rc) {
1690         case LDAP_COMPARE_TRUE:
1691                 rc = 0;
1692                 break;
1693         case LDAP_COMPARE_FALSE:
1694                 break;
1695         case SLAPD_COMPARE_UNDEFINED:
1696                 rc = LDAP_OTHER;
1697                 break;
1698         case LDAP_PROTOCOL_ERROR:
1699                 /* filter type unknown: spec says return -1 */
1700                 rc = -1;
1701                 break;
1702         }
1703
1704         return rc;
1705 #else
1706         return -1;
1707 #endif /* LDAP_SLAPI */
1708 }
1709
1710 int
1711 slapi_filter_test_simple( Slapi_Entry *e, Slapi_Filter *f)
1712 {
1713 #ifdef LDAP_SLAPI
1714         return slapi_filter_test( NULL, e, f, 0 );
1715 #else
1716         return -1;
1717 #endif
1718 }
1719
1720 int
1721 slapi_filter_apply( Slapi_Filter *f, FILTER_APPLY_FN fn, void *arg, int *error_code )
1722 {
1723 #ifdef LDAP_SLAPI
1724         switch ( f->f_choice ) {
1725         case LDAP_FILTER_AND:
1726         case LDAP_FILTER_NOT:
1727         case LDAP_FILTER_OR: {
1728                 int rc;
1729
1730                 /*
1731                  * FIXME: altering f; should we use a temporary?
1732                  */
1733                 for ( f = f->f_list; f != NULL; f = f->f_next ) {
1734                         rc = slapi_filter_apply( f, fn, arg, error_code );
1735                         if ( rc != 0 ) {
1736                                 return rc;
1737                         }
1738                         if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ) {
1739                                 break;
1740                         }
1741                 }
1742                 break;
1743         }
1744         case LDAP_FILTER_EQUALITY:
1745         case LDAP_FILTER_SUBSTRINGS:
1746         case LDAP_FILTER_GE:
1747         case LDAP_FILTER_LE:
1748         case LDAP_FILTER_PRESENT:
1749         case LDAP_FILTER_APPROX:
1750         case LDAP_FILTER_EXT:
1751                 *error_code = fn( f, arg );
1752                 break;
1753         default:
1754                 *error_code = SLAPI_FILTER_UNKNOWN_FILTER_TYPE;
1755         }
1756
1757         if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ||
1758              *error_code == SLAPI_FILTER_SCAN_CONTINUE ) {
1759                 return 0;
1760         }
1761
1762         return -1;
1763 #else
1764         *error_code = SLAPI_FILTER_UNKNOWN_FILTER_TYPE;
1765         return -1;
1766 #endif /* LDAP_SLAPI */
1767 }
1768
1769 int 
1770 slapi_send_ldap_extended_response(
1771         Connection      *conn, 
1772         Operation       *op,
1773         int             errornum, 
1774         char            *respName,
1775         struct berval   *response )
1776 {
1777 #ifdef LDAP_SLAPI
1778         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
1779                         respName,response, NULL );
1780         return LDAP_SUCCESS;
1781 #else /* LDAP_SLAPI */
1782         return -1;
1783 #endif /* LDAP_SLAPI */
1784 }
1785
1786 int 
1787 slapi_pw_find(
1788         struct berval   **vals, 
1789         struct berval   *v ) 
1790 {
1791 #ifdef LDAP_SLAPI
1792         /*
1793          * FIXME: what's the point?
1794          */
1795         return 1;
1796 #else /* LDAP_SLAPI */
1797         return 1;
1798 #endif /* LDAP_SLAPI */
1799 }
1800
1801 #define MAX_HOSTNAME 512
1802
1803 char *
1804 slapi_get_hostname( void ) 
1805 {
1806 #ifdef LDAP_SLAPI
1807         char            *hn = NULL;
1808
1809         /*
1810          * FIXME: I'd prefer a different check ...
1811          */
1812 #if defined _SPARC 
1813         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
1814         if ( hn == NULL) {
1815                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1816                                 "can't malloc memory for hostname\n" );
1817                 hn = NULL;
1818                 
1819         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
1820                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1821                                 "can't get hostname\n" );
1822                 slapi_ch_free( (void **)&hn );
1823                 hn = NULL;
1824         }
1825 #else /* !_SPARC */
1826         static int      been_here = 0;   
1827         static char     *static_hn = NULL;
1828
1829         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
1830         if ( !been_here ) {
1831                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
1832                 if ( static_hn == NULL) {
1833                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
1834                                         "can't malloc memory for hostname\n" );
1835                         static_hn = NULL;
1836                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1837
1838                         return hn;
1839                         
1840                 } else { 
1841                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
1842                                 slapi_log_error( SLAPI_LOG_FATAL,
1843                                                 "SLAPI_SYSINFO",
1844                                                 "can't get hostname\n" );
1845                                 slapi_ch_free( (void **)&static_hn );
1846                                 static_hn = NULL;
1847                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1848
1849                                 return hn;
1850
1851                         } else {
1852                                 been_here = 1;
1853                         }
1854                 }
1855         }
1856         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1857         
1858         hn = ch_strdup( static_hn );
1859 #endif /* !_SPARC */
1860
1861         return hn;
1862 #else /* LDAP_SLAPI */
1863         return NULL;
1864 #endif /* LDAP_SLAPI */
1865 }
1866
1867 /*
1868  * FIXME: this should go in an appropriate header ...
1869  */
1870 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1871
1872 int 
1873 slapi_log_error(
1874         int             severity, 
1875         char            *subsystem, 
1876         char            *fmt, 
1877         ... ) 
1878 {
1879 #ifdef LDAP_SLAPI
1880         int             rc = LDAP_SUCCESS;
1881         va_list         arglist;
1882
1883         va_start( arglist, fmt );
1884         rc = vLogError( severity, subsystem, fmt, arglist );
1885         va_end( arglist );
1886
1887         return rc;
1888 #else /* LDAP_SLAPI */
1889         return -1;
1890 #endif /* LDAP_SLAPI */
1891 }
1892
1893
1894 unsigned long
1895 slapi_timer_current_time( void ) 
1896 {
1897 #ifdef LDAP_SLAPI
1898         static int      first_time = 1;
1899 #if !defined (_WIN32)
1900         struct timeval  now;
1901         unsigned long   ret;
1902
1903         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1904         if (first_time) {
1905                 first_time = 0;
1906                 gettimeofday( &base_time, NULL );
1907         }
1908         gettimeofday( &now, NULL );
1909         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1910                         (now.tv_usec - base_time.tv_usec);
1911         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1912
1913         return ret;
1914
1915         /*
1916          * Ain't it better?
1917         return (slap_get_time() - starttime) * 1000000;
1918          */
1919 #else /* _WIN32 */
1920         LARGE_INTEGER now;
1921
1922         if ( first_time ) {
1923                 first_time = 0;
1924                 performance_counter_present = QueryPerformanceCounter( &base_time );
1925                 QueryPerformanceFrequency( &performance_freq );
1926         }
1927
1928         if ( !performance_counter_present )
1929              return 0;
1930
1931         QueryPerformanceCounter( &now );
1932         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1933 #endif /* _WIN32 */
1934 #else /* LDAP_SLAPI */
1935         return 0;
1936 #endif /* LDAP_SLAPI */
1937 }
1938
1939 /*
1940  * FIXME ?
1941  */
1942 unsigned long
1943 slapi_timer_get_time( char *label ) 
1944 {
1945 #ifdef LDAP_SLAPI
1946         unsigned long start = slapi_timer_current_time();
1947         printf("%10ld %10ld usec %s\n", start, 0, label);
1948         return start;
1949 #else /* LDAP_SLAPI */
1950         return 0;
1951 #endif /* LDAP_SLAPI */
1952 }
1953
1954 /*
1955  * FIXME ?
1956  */
1957 void
1958 slapi_timer_elapsed_time(
1959         char *label,
1960         unsigned long start ) 
1961 {
1962 #ifdef LDAP_SLAPI
1963         unsigned long stop = slapi_timer_current_time();
1964         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1965 #endif /* LDAP_SLAPI */
1966 }
1967
1968 void
1969 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1970 {
1971 #ifdef LDAP_SLAPI
1972         Slapi_Entry     **entries;
1973         int             k = 0, nEnt = 0;
1974
1975         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1976         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1977         if ( nEnt == 0 ) {
1978                 return;
1979         }
1980         
1981         if ( entries == NULL ) {
1982                 return;
1983         }
1984         
1985         for ( k = 0; k < nEnt; k++ ) {
1986                 slapi_entry_free( entries[k] );
1987         }
1988         
1989         slapi_ch_free( (void **)&entries );
1990 #endif /* LDAP_SLAPI */
1991 }
1992
1993 /*
1994  * Internal API to prime a Slapi_PBlock with a Backend.
1995  */
1996 int slapi_x_backend_set_pb( Slapi_PBlock *pb, Backend *be )
1997 {
1998 #ifdef LDAP_SLAPI
1999         int rc;
2000         
2001         rc = slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
2002         if ( rc != LDAP_SUCCESS )
2003                 return rc;
2004         
2005         if ( be != NULL ) {
2006                 rc = slapi_pblock_set( pb, SLAPI_BE_TYPE, (void *)be->bd_info->bi_type );
2007                 if ( rc != LDAP_SUCCESS )
2008                         return rc;
2009         }
2010
2011         return LDAP_SUCCESS;
2012 #else
2013         return -1;
2014 #endif /* LDAP_SLAPI */
2015 }
2016
2017 #ifdef LDAP_SLAPI
2018 /*
2019  * If oldStyle is TRUE, then a value suitable for setting to
2020  * the deprecated SLAPI_CONN_AUTHTYPE value is returned 
2021  * (pointer to static storage).
2022  *
2023  * If oldStyle is FALSE, then a value suitable for setting to
2024  * the new SLAPI_CONN_AUTHMETHOD will be returned, which is
2025  * a pointer to allocated memory and will include the SASL
2026  * mechanism (if any).
2027  */
2028 static char *Authorization2AuthType( AuthorizationInformation *authz, int is_tls, int oldStyle )
2029 {
2030         size_t len;
2031         char *authType;
2032
2033         switch ( authz->sai_method ) {
2034         case LDAP_AUTH_SASL:
2035                 if ( oldStyle ) {
2036                         authType = SLAPD_AUTH_SASL;
2037                 } else {
2038                         len = sizeof(SLAPD_AUTH_SASL) + authz->sai_mech.bv_len;
2039                         authType = slapi_ch_malloc( len );
2040                         snprintf( authType, len, "%s%s", SLAPD_AUTH_SASL, authz->sai_mech.bv_val );
2041                 }
2042                 break;
2043         case LDAP_AUTH_SIMPLE:
2044                 authType = oldStyle ? SLAPD_AUTH_SIMPLE : slapi_ch_strdup( SLAPD_AUTH_SIMPLE );
2045                 break;
2046         case LDAP_AUTH_NONE:
2047                 authType = oldStyle ? SLAPD_AUTH_NONE : slapi_ch_strdup( SLAPD_AUTH_NONE );
2048                 break;
2049         default:
2050                 authType = NULL;
2051                 break;
2052         }
2053         if ( is_tls && authType == NULL ) {
2054                 authType = oldStyle ? SLAPD_AUTH_SSL : slapi_ch_strdup( SLAPD_AUTH_SSL );
2055         }
2056
2057         return authType;
2058 }
2059 #endif
2060
2061 /*
2062  * Internal API to prime a Slapi_PBlock with a Connection.
2063  */
2064 int slapi_x_connection_set_pb( Slapi_PBlock *pb, Connection *conn )
2065 {
2066 #ifdef LDAP_SLAPI
2067         char *connAuthType;
2068         int rc;
2069
2070         rc = slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
2071         if ( rc != LDAP_SUCCESS )
2072                 return rc;
2073
2074         if ( strncmp( conn->c_peer_name.bv_val, "IP=", 3 ) == 0 ) {
2075                 rc = slapi_pblock_set( pb, SLAPI_CONN_CLIENTIP, (void *)&conn->c_peer_name.bv_val[3] );
2076                 if ( rc != LDAP_SUCCESS )
2077                         return rc;
2078         } else if ( strncmp( conn->c_peer_name.bv_val, "PATH=", 5 ) == 0 ) {
2079                 rc = slapi_pblock_set( pb, SLAPI_X_CONN_CLIENTPATH, (void *)&conn->c_peer_name.bv_val[5] );
2080                 if ( rc != LDAP_SUCCESS )
2081                         return rc;
2082         }
2083
2084         if ( strncmp( conn->c_sock_name.bv_val, "IP=", 3 ) == 0 ) {
2085                 rc = slapi_pblock_set( pb, SLAPI_CONN_SERVERIP, (void *)&conn->c_sock_name.bv_val[3] );
2086                 if ( rc != LDAP_SUCCESS )
2087                         return rc;
2088         } else if ( strncmp( conn->c_sock_name.bv_val, "PATH=", 5 ) == 0 ) {
2089                 rc = slapi_pblock_set( pb, SLAPI_X_CONN_SERVERPATH, (void *)&conn->c_sock_name.bv_val[5] );
2090                 if ( rc != LDAP_SUCCESS )
2091                         return rc;
2092         }
2093
2094 #ifdef LDAP_CONNECTIONLESS
2095         rc = slapi_pblock_set( pb, SLAPI_X_CONN_IS_UDP, (void *)conn->c_is_udp );
2096         if ( rc != LDAP_SUCCESS )
2097                 return rc;
2098 #endif
2099
2100         rc = slapi_pblock_set( pb, SLAPI_CONN_ID, (void *)conn->c_connid );
2101         if ( rc != LDAP_SUCCESS )
2102                 return rc;
2103
2104         /* Returns pointer to static string */
2105         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 1 );
2106         if ( connAuthType != NULL ) {
2107                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
2108                 if ( rc != LDAP_SUCCESS )
2109                         return rc;
2110         }
2111
2112         /* Returns pointer to allocated string */
2113         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 0 );
2114         if ( connAuthType != NULL ) {
2115                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType);
2116                 if ( rc != LDAP_SUCCESS )
2117                         return rc;
2118         }
2119
2120         if ( conn->c_authz.sai_dn.bv_val != NULL ) {
2121                 char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
2122                 rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
2123                 if ( rc != LDAP_SUCCESS )
2124                         return rc;
2125         }
2126
2127         return rc;
2128 #else
2129         return -1;
2130 #endif /* LDAP_SLAPI */
2131 }
2132
2133 /*
2134  * Internal API to prime a Slapi_PBlock with an Operation.
2135  */
2136 int slapi_x_operation_set_pb( Slapi_PBlock *pb, Operation *op )
2137 {
2138 #ifdef LDAP_SLAPI
2139         int isRoot = 0;
2140         int isUpdateDn = 0;
2141         int rc;
2142         Backend *be;
2143         char *opAuthType;
2144
2145         if ( slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2146                 be = NULL;
2147         }
2148         if (be != NULL) {
2149                 isRoot = be_isroot( be, &op->o_ndn );
2150                 isUpdateDn = be_isupdate( be, &op->o_ndn );
2151         }
2152                 
2153         rc = slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
2154         if ( rc != LDAP_SUCCESS )
2155                 return rc;
2156
2157         rc = slapi_pblock_set( pb, SLAPI_OPINITIATED_TIME, (void *)op->o_time );
2158         if ( rc != LDAP_SUCCESS )
2159                 return rc;
2160
2161         rc = slapi_pblock_set( pb, SLAPI_OPERATION_ID, (void *)op->o_opid );
2162         if ( rc != LDAP_SUCCESS )
2163                 return rc;
2164
2165         rc = slapi_pblock_set( pb, SLAPI_OPERATION_TYPE, (void *)op->o_tag );
2166         if ( rc != LDAP_SUCCESS )
2167                 return rc;
2168
2169         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, (void *)isRoot );
2170         if ( rc != LDAP_SUCCESS )
2171                 return rc;
2172
2173         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISUPDATEDN, (void *)isUpdateDn );
2174         if ( rc != LDAP_SUCCESS )
2175                 return rc;
2176
2177         rc = slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
2178         if ( rc != LDAP_SUCCESS)
2179                 return rc;
2180
2181         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_DN, (void *)op->o_ndn.bv_val );
2182         if ( rc != LDAP_SUCCESS )
2183                 return rc;
2184
2185         rc = slapi_pblock_get( pb, SLAPI_CONN_AUTHMETHOD, (void *)&opAuthType );
2186         if ( rc == LDAP_SUCCESS && opAuthType != NULL ) {
2187                 /* Not quite sure what the point of this is. */
2188                 rc = slapi_pblock_set( pb, SLAPI_OPERATION_AUTHTYPE, (void *)opAuthType );
2189                 if ( rc != LDAP_SUCCESS )
2190                         return rc;
2191         }
2192
2193         return LDAP_SUCCESS;
2194 #else
2195         return -1;
2196 #endif
2197 }
2198
2199 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
2200 {
2201 #ifdef LDAP_SLAPI
2202         Connection *conn;
2203
2204         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
2205         *isSSL = conn->c_is_tls;
2206
2207         return LDAP_SUCCESS;
2208 #else
2209         return -1;
2210 #endif /* LDAP_SLAPI */
2211 }
2212
2213 /*
2214  * DS 5.x compatability API follow
2215  */
2216
2217 int slapi_attr_get_flags( const Slapi_Attr *attr, unsigned long *flags )
2218 {
2219 #ifdef LDAP_SLAPI
2220         AttributeType *at;
2221
2222         if ( attr == NULL )
2223                 return LDAP_PARAM_ERROR;
2224
2225         at = attr->a_desc->ad_type;
2226
2227         *flags = SLAPI_ATTR_FLAG_STD_ATTR;
2228
2229         if ( is_at_single_value( at ) )
2230                 *flags |= SLAPI_ATTR_FLAG_SINGLE;
2231         if ( is_at_operational( at ) )
2232                 *flags |= SLAPI_ATTR_FLAG_OPATTR;
2233         if ( is_at_obsolete( at ) )
2234                 *flags |= SLAPI_ATTR_FLAG_OBSOLETE;
2235         if ( is_at_collective( at ) )
2236                 *flags |= SLAPI_ATTR_FLAG_COLLECTIVE;
2237         if ( is_at_no_user_mod( at ) )
2238                 *flags |= SLAPI_ATTR_FLAG_NOUSERMOD;
2239
2240         return LDAP_SUCCESS;
2241 #else
2242         return -1;
2243 #endif /* LDAP_SLAPI */
2244 }
2245
2246 int slapi_attr_flag_is_set( const Slapi_Attr *attr, unsigned long flag )
2247 {
2248 #ifdef LDAP_SLAPI
2249         unsigned long flags;
2250
2251         if ( slapi_attr_get_flags( attr, &flags ) != 0 )
2252                 return 0;
2253         return (flags & flag) ? 1 : 0;
2254 #else
2255         return 0;
2256 #endif /* LDAP_SLAPI */
2257 }
2258
2259 Slapi_Attr *slapi_attr_new( void )
2260 {
2261 #ifdef LDAP_SLAPI
2262         Attribute *ad;
2263
2264         ad = (Attribute  *)slapi_ch_calloc( 1, sizeof(*ad) );
2265
2266         return ad;
2267 #else
2268         return NULL;
2269 #endif
2270 }
2271
2272 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type )
2273 {
2274 #ifdef LDAP_SLAPI
2275         const char *text;
2276         AttributeDescription *ad = NULL;
2277
2278         if( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
2279                 return NULL;
2280         }
2281
2282         a->a_desc = ad;
2283         a->a_vals = NULL;
2284         a->a_next = NULL;
2285         a->a_flags = 0;
2286
2287         return a;
2288 #else
2289         return NULL;
2290 #endif
2291 }
2292
2293 void slapi_attr_free( Slapi_Attr **a )
2294 {
2295 #ifdef LDAP_SLAPI
2296         attr_free( *a );
2297         *a = NULL;
2298 #endif
2299 }
2300
2301 Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr )
2302 {
2303 #ifdef LDAP_SLAPI
2304         return attr_dup( (Slapi_Attr *)attr );
2305 #else
2306         return NULL;
2307 #endif
2308 }
2309
2310 int slapi_attr_add_value( Slapi_Attr *a, const Slapi_Value *v )
2311 {
2312 #ifdef LDAP_SLAPI
2313         return value_add_one( &a->a_vals, (Slapi_Value *)v );
2314 #else
2315         return -1;
2316 #endif
2317 }
2318
2319 int slapi_attr_type2plugin( const char *type, void **pi )
2320 {
2321         *pi = NULL;
2322
2323         return LDAP_OTHER;
2324 }
2325
2326 int slapi_attr_get_type( const Slapi_Attr *attr, char **type )
2327 {
2328 #ifdef LDAP_SLAPI
2329         if ( attr == NULL ) {
2330                 return LDAP_PARAM_ERROR;
2331         }
2332
2333         *type = attr->a_desc->ad_cname.bv_val;
2334
2335         return LDAP_SUCCESS;
2336 #else
2337         return -1;
2338 #endif
2339 }
2340
2341 int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp )
2342 {
2343 #ifdef LDAP_SLAPI
2344         if ( attr == NULL ) {
2345                 return LDAP_PARAM_ERROR;
2346         }
2347         *oidp = attr->a_desc->ad_type->sat_oid;
2348
2349         return LDAP_SUCCESS;
2350 #else
2351         return -1;
2352 #endif
2353 }
2354
2355 int slapi_attr_value_cmp( const Slapi_Attr *a, const struct berval *v1, const struct berval *v2 )
2356 {
2357 #ifdef LDAP_SLAPI
2358         MatchingRule *mr;
2359         int ret;
2360         int rc;
2361         const char *text;
2362
2363         mr = a->a_desc->ad_type->sat_equality;
2364         rc = value_match( &ret, a->a_desc, mr, SLAP_MR_ASSERTION_SYNTAX_MATCH,
2365                 (struct berval *)v1, (void *)v2, &text );
2366         if ( rc != LDAP_SUCCESS ) 
2367                 return -1;
2368
2369         return ( ret == 0 ) ? 0 : -1;
2370 #else
2371         return -1;
2372 #endif
2373 }
2374
2375 int slapi_attr_value_find( const Slapi_Attr *a, struct berval *v )
2376 {
2377 #ifdef LDAP_SLAPI
2378         MatchingRule *mr;
2379         struct berval *bv;
2380         int j;
2381         const char *text;
2382         int rc;
2383         int ret;
2384
2385         mr = a->a_desc->ad_type->sat_equality;
2386         for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
2387                 rc = value_match( &ret, a->a_desc, mr,
2388                         SLAP_MR_ASSERTION_SYNTAX_MATCH, bv, v, &text );
2389                 if ( rc != LDAP_SUCCESS ) {
2390                         return -1;
2391                 }
2392                 if ( ret == 0 ) {
2393                         return 0;
2394                 }
2395         }
2396 #endif
2397         return -1;
2398 }
2399
2400 int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
2401 {
2402 #ifdef LDAP_SLAPI
2403         AttributeDescription *a1 = NULL;
2404         AttributeDescription *a2 = NULL;
2405         const char *text;
2406         int ret;
2407
2408         if ( slap_str2ad( t1, &a1, &text ) != LDAP_SUCCESS ) {
2409                 return -1;
2410         }
2411
2412         if ( slap_str2ad( t2, &a2, &text ) != LDAP_SUCCESS ) {
2413                 return 1;
2414         }
2415
2416 #define ad_base_cmp(l,r) (((l)->ad_type->sat_cname.bv_len < (r)->ad_type->sat_cname.bv_len) \
2417         ? -1 : (((l)->ad_type->sat_cname.bv_len > (r)->ad_type->sat_cname.bv_len) \
2418                 ? 1 : strcasecmp((l)->ad_type->sat_cname.bv_val, (r)->ad_type->sat_cname.bv_val )))
2419
2420         switch ( opt ) {
2421         case SLAPI_TYPE_CMP_EXACT:
2422                 ret = ad_cmp( a1, a2 );
2423                 break;
2424         case SLAPI_TYPE_CMP_BASE:
2425                 ret = ad_base_cmp( a1, a2 );
2426                 break;
2427         case SLAPI_TYPE_CMP_SUBTYPE:
2428                 ret = is_ad_subtype( a2, a2 );
2429                 break;
2430         default:
2431                 ret = -1;
2432                 break;
2433         }
2434
2435         return ret;
2436 #else
2437         return -1;
2438 #endif
2439 }
2440
2441 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
2442 {
2443 #ifdef LDAP_SLAPI
2444         return slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT );
2445 #else
2446         return -1;
2447 #endif
2448 }
2449
2450 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
2451 {
2452 #ifdef LDAP_SLAPI
2453         return slapi_valueset_first_value( &a->a_vals, v );
2454 #else
2455         return -1;
2456 #endif
2457 }
2458
2459 int slapi_attr_next_value( Slapi_Attr *a, int hint, Slapi_Value **v )
2460 {
2461 #ifdef LDAP_SLAPI
2462         return slapi_valueset_next_value( &a->a_vals, hint, v );
2463 #else
2464         return -1;
2465 #endif
2466 }
2467
2468 int slapi_attr_get_numvalues( const Slapi_Attr *a, int *numValues )
2469 {
2470 #ifdef LDAP_SLAPI
2471         *numValues = slapi_valueset_count( &a->a_vals );
2472
2473         return 0;
2474 #else
2475         return -1;
2476 #endif
2477 }
2478
2479 int slapi_attr_get_valueset( const Slapi_Attr *a, Slapi_ValueSet **vs )
2480 {
2481 #ifdef LDAP_SLAPI
2482         *vs = &((Slapi_Attr *)a)->a_vals;
2483
2484         return 0;
2485 #else
2486         return -1;
2487 #endif
2488 }
2489
2490 int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals )
2491 {
2492 #ifdef LDAP_SLAPI
2493         return slapi_attr_get_values( a, vals );
2494 #else
2495         return -1;
2496 #endif
2497 }
2498
2499 char *slapi_attr_syntax_normalize( const char *s )
2500 {
2501 #ifdef LDAP_SLAPI
2502         AttributeDescription *ad = NULL;
2503         const char *text;
2504
2505         if ( slap_str2ad( s, &ad, &text ) != LDAP_SUCCESS ) {
2506                 return NULL;
2507         }
2508
2509         return ad->ad_cname.bv_val;
2510 #else
2511         return -1;
2512 #endif
2513 }
2514
2515 Slapi_Value *slapi_value_new( void )
2516 {
2517 #ifdef LDAP_SLAPI
2518         struct berval *bv;
2519
2520         bv = (struct berval *)slapi_ch_malloc( sizeof(*bv) );
2521
2522         return bv;
2523 #else
2524         return NULL;
2525 #endif
2526 }
2527
2528 Slapi_Value *slapi_value_new_berval(const struct berval *bval)
2529 {
2530 #ifdef LDAP_SLAPI
2531         return ber_dupbv( NULL, (struct berval *)bval );
2532 #else
2533         return NULL;
2534 #endif
2535 }
2536
2537 Slapi_Value *slapi_value_new_value(const Slapi_Value *v)
2538 {
2539 #ifdef LDAP_SLAPI
2540         return slapi_value_new_berval( v );
2541 #else
2542         return NULL;
2543 #endif
2544 }
2545
2546 Slapi_Value *slapi_value_new_string(const char *s)
2547 {
2548 #ifdef LDAP_SLAPI
2549         struct berval bv;
2550
2551         bv.bv_val = (char *)s;
2552         bv.bv_len = strlen( s );
2553
2554         return slapi_value_new_berval( &bv );
2555 #else
2556         return NULL;
2557 #endif
2558 }
2559
2560 Slapi_Value *slapi_value_init(Slapi_Value *val)
2561 {
2562 #ifdef LDAP_SLAPI
2563         val->bv_val = NULL;
2564         val->bv_len = 0;
2565
2566         return val;
2567 #else
2568         return NULL;
2569 #endif
2570 }
2571
2572 Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
2573 {
2574 #ifdef LDAP_SLAPI
2575         return ber_dupbv( v, bval );
2576 #else
2577         return NULL;
2578 #endif
2579 }
2580
2581 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
2582 {
2583 #ifdef LDAP_SLAPI
2584         v->bv_val = slapi_ch_strdup( (char *)s );
2585         v->bv_len = strlen( s );
2586
2587         return v;
2588 #else
2589         return NULL;
2590 #endif
2591 }
2592
2593 Slapi_Value *slapi_value_dup(const Slapi_Value *v)
2594 {
2595 #ifdef LDAP_SLAPI
2596         return slapi_value_new_value( v );
2597 #else
2598         return NULL;
2599 #endif
2600 }
2601
2602 void slapi_value_free(Slapi_Value **value)
2603 {
2604 #ifdef LDAP_SLAPI       
2605         if ( value == NULL ) {
2606                 return;
2607         }
2608
2609         if ( (*value) != NULL ) {
2610                 slapi_ch_free( (void **)&(*value)->bv_val );
2611                 slapi_ch_free( (void **)value );
2612         }
2613 #endif
2614 }
2615
2616 const struct berval *slapi_value_get_berval( const Slapi_Value *value )
2617 {
2618 #ifdef LDAP_SLAPI
2619         return value;
2620 #else
2621         return NULL;
2622 #endif
2623 }
2624
2625 Slapi_Value *slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
2626 {
2627 #ifdef LDAP_SLAPI
2628         if ( value == NULL ) {
2629                 return NULL;
2630         }
2631         if ( value->bv_val != NULL ) {
2632                 slapi_ch_free( (void **)&value->bv_val );
2633         }
2634         slapi_value_init_berval( value, (struct berval *)bval );
2635
2636         return value;
2637 #else
2638         return NULL;
2639 #endif
2640 }
2641
2642 Slapi_Value *slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
2643 {
2644 #ifdef LDAP_SLAPI
2645         if ( value == NULL ) {
2646                 return NULL;
2647         }
2648         return slapi_value_set_berval( value, vfrom );
2649 #else
2650         return NULL;
2651 #endif
2652 }
2653
2654 Slapi_Value *slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
2655 {
2656 #ifdef LDAP_SLAPI
2657         if ( value == NULL ) {
2658                 return NULL;
2659         }
2660         if ( value->bv_val != NULL ) {
2661                 slapi_ch_free( (void **)&value->bv_val );
2662         }
2663         value->bv_val = slapi_ch_malloc( len );
2664         value->bv_len = len;
2665         AC_MEMCPY( value->bv_val, val, len );
2666
2667         return value;
2668 #else
2669         return NULL;
2670 #endif
2671 }
2672
2673 int slapi_value_set_string(Slapi_Value *value, const char *strVal)
2674 {
2675 #ifdef LDAP_SLAPI
2676         if ( value == NULL ) {
2677                 return -1;
2678         }
2679         slapi_value_set( value, (void *)strVal, strlen( strVal ) );
2680         return 0;
2681 #else
2682         return NULL;
2683 #endif
2684 }
2685
2686 int slapi_value_set_int(Slapi_Value *value, int intVal)
2687 {
2688 #ifdef LDAP_SLAPI
2689         char buf[64];
2690
2691         snprintf( buf, sizeof( buf ), "%d", intVal );
2692
2693         return slapi_value_set_string( value, buf );
2694 #else
2695         return -1;
2696 #endif
2697 }
2698
2699 const char *slapi_value_get_string(const Slapi_Value *value)
2700 {
2701 #ifdef LDAP_SLAPI
2702         if ( value == NULL ) {
2703                 return NULL;
2704         }
2705         return value->bv_val;
2706 #else
2707         return NULL;
2708 #endif
2709 }
2710
2711 #ifdef LDAP_SLAPI
2712 static int checkBVString(const struct berval *bv)
2713 {
2714         int i;
2715
2716         for ( i = 0; i < bv->bv_len; i++ ) {
2717                 if ( bv->bv_val[i] == '\0' )
2718                         return 0;
2719         }
2720         if ( bv->bv_val[i] != '\0' )
2721                 return 0;
2722
2723         return 1;
2724 }
2725 #endif
2726
2727 int slapi_value_get_int(const Slapi_Value *value)
2728 {
2729 #ifdef LDAP_SLAPI
2730         if ( value == NULL ) return 0;
2731         if ( value->bv_val == NULL ) return 0;
2732         if ( !checkBVString( value ) ) return 0;
2733
2734         return (int)strtol( value->bv_val, NULL, 10 );
2735 #else
2736         return NULL;
2737 #endif
2738 }
2739
2740 unsigned int slapi_value_get_uint(const Slapi_Value *value)
2741 {
2742 #ifdef LDAP_SLAPI
2743         if ( value == NULL ) return 0;
2744         if ( value->bv_val == NULL ) return 0;
2745         if ( !checkBVString( value ) ) return 0;
2746
2747         return (unsigned int)strtoul( value->bv_val, NULL, 10 );
2748 #else
2749         return NULL;
2750 #endif
2751 }
2752
2753 long slapi_value_get_long(const Slapi_Value *value)
2754 {
2755 #ifdef LDAP_SLAPI
2756         if ( value == NULL ) return 0;
2757         if ( value->bv_val == NULL ) return 0;
2758         if ( !checkBVString( value ) ) return 0;
2759
2760         return strtol( value->bv_val, NULL, 10 );
2761 #else
2762         return NULL;
2763 #endif
2764 }
2765
2766 unsigned long slapi_value_get_ulong(const Slapi_Value *value)
2767 {
2768 #ifdef LDAP_SLAPI
2769         if ( value == NULL ) return 0;
2770         if ( value->bv_val == NULL ) return 0;
2771         if ( !checkBVString( value ) ) return 0;
2772
2773         return strtoul( value->bv_val, NULL, 10 );
2774 #else
2775         return NULL;
2776 #endif
2777 }
2778
2779 size_t slapi_value_get_length(const Slapi_Value *value)
2780 {
2781 #ifdef LDAP_SLAPI
2782         if ( value == NULL )
2783                 return 0;
2784
2785         return (size_t) value->bv_len;
2786 #else
2787         return 0;
2788 #endif
2789 }
2790
2791 int slapi_value_compare(const Slapi_Attr *a, const Slapi_Value *v1, const Slapi_Value *v2)
2792 {
2793 #ifdef LDAP_SLAPI
2794         return slapi_attr_value_cmp( a, v1, v2 );
2795 #else
2796         return -1;
2797 #endif
2798 }
2799
2800 /* A ValueSet is a container for a BerVarray. */
2801 Slapi_ValueSet *slapi_valueset_new( void )
2802 {
2803 #ifdef LDAP_SLAPI
2804         Slapi_ValueSet *vs;
2805
2806         vs = (Slapi_ValueSet *)slapi_ch_malloc( sizeof( *vs ) );
2807         *vs = NULL;
2808
2809         return vs;
2810 #else
2811         return NULL;
2812 #endif
2813 }
2814
2815 void slapi_valueset_free(Slapi_ValueSet *vs)
2816 {
2817 #ifdef LDAP_SLAPI
2818         if ( vs != NULL ) {
2819                 BerVarray vp = *vs;
2820
2821                 ber_bvarray_free( vp );
2822                 slapi_ch_free( (void **)&vp );
2823
2824                 *vs = NULL;
2825         }
2826 #endif
2827 }
2828
2829 void slapi_valueset_init(Slapi_ValueSet *vs)
2830 {
2831 #ifdef LDAP_SLAPI
2832         if ( vs != NULL && *vs == NULL ) {
2833                 *vs = (Slapi_ValueSet)slapi_ch_calloc( 1, sizeof(struct berval) );
2834                 (*vs)->bv_val = NULL;
2835                 (*vs)->bv_len = 0;
2836         }
2837 #endif
2838 }
2839
2840 void slapi_valueset_done(Slapi_ValueSet *vs)
2841 {
2842 #ifdef LDAP_SLAPI
2843         BerVarray vp;
2844
2845         if ( vs == NULL )
2846                 return;
2847
2848         for ( vp = *vs; vp->bv_val != NULL; vp++ ) {
2849                 vp->bv_len = 0;
2850                 slapi_ch_free( (void **)&vp->bv_val );
2851         }
2852         /* but don't free *vs or vs */
2853 #endif
2854 }
2855
2856 void slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
2857 {
2858 #ifdef LDAP_SLAPI
2859         struct berval bv;
2860
2861         ber_dupbv( &bv, (Slapi_Value *)addval );
2862         ber_bvarray_add( vs, &bv );
2863 #endif
2864 }
2865
2866 int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
2867 {
2868 #ifdef LDAP_SLAPI
2869         return slapi_valueset_next_value( vs, 0, v );
2870 #else
2871         return -1;
2872 #endif
2873 }
2874
2875 int slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
2876 {
2877 #ifdef LDAP_SLAPI
2878         int i;
2879         BerVarray vp;
2880
2881         if ( vs == NULL )
2882                 return -1;
2883
2884         vp = *vs;
2885
2886         for ( i = 0; vp[i].bv_val != NULL; i++ ) {
2887                 if ( i == index ) {
2888                         *v = &vp[i];
2889                         return index + 1;
2890                 }
2891         }
2892 #endif
2893
2894         return -1;
2895 }
2896
2897 int slapi_valueset_count( const Slapi_ValueSet *vs )
2898 {
2899 #ifdef LDAP_SLAPI
2900         int i;
2901         BerVarray vp;
2902
2903         if ( vs == NULL )
2904                 return 0;
2905
2906         vp = *vs;
2907
2908         for ( i = 0; vp[i].bv_val != NULL; i++ )
2909                 ;
2910
2911         return i;
2912 #else
2913         return 0;
2914 #endif
2915
2916 }
2917
2918 void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
2919 {
2920 #ifdef LDAP_SLAPI
2921         BerVarray vp;
2922
2923         for ( vp = *vs2; vp->bv_val != NULL; vp++ ) {
2924                 slapi_valueset_add_value( vs1, vp );
2925         }
2926 #endif
2927 }
2928
2929 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
2930         struct berval *val, int access )
2931 {
2932 #ifdef LDAPI_SLAPI
2933         Backend *be;
2934         Connection *conn;
2935         Operation *op;
2936         int ret;
2937         slap_access_t slap_access;
2938         AttributeDescription *ad = NULL;
2939         char *text;
2940
2941         ret = slap_str2ad( attr, &ad, &text );
2942         if ( ret != LDAP_SUCCESS ) {
2943                 return ret;
2944         }
2945
2946         switch ( access & SLAPI_ACL_ALL ) {
2947         case SLAPI_ACL_COMPARE:
2948                 slap_access = ACL_COMPARE;
2949                 break;
2950         case SLAPI_ACL_SEARCH:
2951                 slap_access = ACL_SEARCH;
2952                 break;
2953         case SLAPI_ACL_READ:
2954                 slap_access = ACL_READ;
2955                 break;
2956         case SLAPI_ACL_WRITE:
2957         case SLAPI_ACL_DELETE:
2958         case SLAPI_ACL_ADD:
2959         case SLAPI_ACL_SELF:
2960                 slap_access = ACL_WRITE;
2961                 break;
2962         default:
2963                 return LDAP_INSUFFICIENT_ACCESS;
2964                 break;
2965         }
2966
2967         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2968                 return LDAP_PARAM_ERROR;
2969         }
2970
2971         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
2972                 return LDAP_PARAM_ERROR;
2973         }
2974
2975         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
2976                 return LDAP_PARAM_ERROR;
2977         }
2978
2979         ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL );
2980
2981         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2982 #else
2983         return LDAP_UNWILLING_TO_PERFORM;
2984 #endif
2985 }
2986
2987 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
2988 {
2989 #ifdef LDAP_SLAPI
2990         Backend *be;
2991         Connection *conn;
2992         Operation *op;
2993         int ret;
2994         Modifications *ml;
2995         Modifications *next;
2996
2997         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2998                 return LDAP_PARAM_ERROR;
2999         }
3000
3001         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
3002                 return LDAP_PARAM_ERROR;
3003         }
3004
3005         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
3006                 return LDAP_PARAM_ERROR;
3007         }
3008
3009         ml = slapi_x_ldapmods2modifications( mods );
3010         if ( ml == NULL ) {
3011                 return LDAP_OTHER;
3012         }
3013
3014         ret = acl_check_modlist( be, conn, op, e, ml );
3015
3016         /* Careful when freeing the modlist because it has pointers into the mods array. */
3017         for ( ; ml != NULL; ml = next ) {
3018                 next = ml->sml_next;
3019
3020                 /* just free the containing array */
3021                 slapi_ch_free( (void **)&ml->sml_bvalues );
3022                 slapi_ch_free( (void **)&ml );
3023         }
3024
3025         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
3026 #else
3027         return LDAP_UNWILLING_TO_PERFORM;
3028 #endif
3029 }
3030
3031 /*
3032  * Synthesise an LDAPMod array from a Modifications list to pass
3033  * to SLAPI. This synthesis is destructive and as such the 
3034  * Modifications list may not be used after calling this 
3035  * function.
3036  * 
3037  * This function must also be called before slap_mods_check().
3038  */
3039 LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
3040 {
3041 #ifdef LDAP_SLAPI
3042         Modifications *ml, *modlist;
3043         LDAPMod **mods, *modp;
3044         int i, j;
3045
3046         modlist = *pmodlist;
3047
3048         for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
3049                 ;
3050
3051         mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
3052
3053         for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
3054                 mods[i] = (LDAPMod *)ch_malloc( sizeof(LDAPMod) );
3055                 modp = mods[i];
3056                 modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
3057
3058                 /* Take ownership of original type. */
3059                 modp->mod_type = ml->sml_type.bv_val;
3060                 ml->sml_type.bv_val = NULL;
3061
3062                 if ( ml->sml_bvalues != NULL ) {
3063                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
3064                                 ;
3065                         modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
3066                                 sizeof(struct berval *) );
3067                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
3068                                 /* Take ownership of original values. */
3069                                 modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
3070                                 modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
3071                                 modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
3072                                 ml->sml_bvalues[j].bv_len = 0;
3073                                 ml->sml_bvalues[j].bv_val = NULL;
3074                         }
3075                         modp->mod_bvalues[j] = NULL;
3076                 } else {
3077                         modp->mod_bvalues = NULL;
3078                 }
3079                 i++;
3080         }
3081
3082         mods[i] = NULL;
3083
3084         slap_mods_free( modlist );
3085         *pmodlist = NULL;
3086
3087         return mods;
3088 #else
3089         return NULL;
3090 #endif
3091 }
3092
3093 /*
3094  * Convert a potentially modified array of LDAPMods back to a
3095  * Modification list. 
3096  * 
3097  * The returned Modification list contains pointers into the
3098  * LDAPMods array; the latter MUST be freed with
3099  * slapi_x_free_ldapmods() (see below).
3100  */
3101 Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
3102 {
3103 #ifdef LDAP_SLAPI
3104         Modifications *modlist, **modtail;
3105         LDAPMod **modp;
3106
3107         modtail = &modlist;
3108
3109         for( modp = mods; *modp != NULL; modp++ ) {
3110                 Modifications *mod;
3111                 int i;
3112                 char **p;
3113                 struct berval **bvp;
3114
3115                 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
3116                 mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
3117                 mod->sml_type.bv_val = (*modp)->mod_type;
3118                 mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
3119                 mod->sml_desc = NULL;
3120                 mod->sml_next = NULL;
3121
3122                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
3123                         for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ )
3124                                 ;
3125                 } else {
3126                         for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ )
3127                                 ;
3128                 }
3129
3130                 if ( i == 0 ) {
3131                          mod->sml_bvalues = NULL;
3132                 } else {
3133                         mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
3134
3135                         /* NB: This implicitly trusts a plugin to return valid modifications. */
3136                         if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
3137                                 for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ ) {
3138                                         mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
3139                                         mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
3140                                 }
3141                         } else {
3142                                 for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ ) {
3143                                         mod->sml_bvalues[i].bv_val = *p;
3144                                         mod->sml_bvalues[i].bv_len = strlen( *p );
3145                                 }
3146                         }
3147                         mod->sml_bvalues[i].bv_val = NULL;
3148                 }
3149
3150                 *modtail = mod;
3151                 modtail = &mod->sml_next;
3152         }
3153         
3154         return modlist;
3155 #else
3156         return NULL;
3157 #endif 
3158 }
3159
3160 /*
3161  * This function only frees the parts of the mods array that
3162  * are not shared with the Modification list that was created
3163  * by slapi_x_ldapmods2modifications(). 
3164  *
3165  */
3166 void slapi_x_free_ldapmods (LDAPMod **mods)
3167 {
3168 #ifdef LDAP_SLAPI
3169         int i, j;
3170
3171         if (mods == NULL)
3172                 return;
3173
3174         for ( i = 0; mods[i] != NULL; i++ ) {
3175                 /*
3176                  * Don't free values themselves; they're owned by the
3177                  * Modification list. Do free the containing array.
3178                  */
3179                 if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
3180                         for ( j = 0; mods[i]->mod_bvalues != NULL && mods[i]->mod_bvalues[j] != NULL; j++ ) {
3181                                 ch_free( mods[i]->mod_bvalues[j] );
3182                         }
3183                         ch_free( mods[i]->mod_bvalues );
3184                 } else {
3185                         ch_free( mods[i]->mod_values );
3186                 }
3187                 /* Don't free type, for same reasons. */
3188                 ch_free( mods[i] );
3189         }
3190         ch_free( mods );
3191 #endif /* LDAP_SLAPI */
3192 }
3193
3194 /*
3195  * Sun ONE DS 5.x computed attribute support. Computed attributes
3196  * allow for dynamically generated operational attributes, a very
3197  * useful thing indeed.
3198  */
3199
3200 /*
3201  * Write the computed attribute to a BerElement. Complementary 
3202  * functions need to be defined for anything that replaces 
3203  * op->o_callback->sc_sendentry, if you wish to make computed
3204  * attributes available to it.
3205  */
3206 int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e)
3207 {
3208 #ifdef LDAP_SLAPI
3209         Backend *be = NULL;
3210         Connection *conn = NULL;
3211         Operation *op = NULL;
3212         BerElement *ber;
3213         AttributeDescription *desc = NULL;
3214         int rc;
3215         int i;
3216
3217         if ( c == NULL ) {
3218                 return 1;
3219         }
3220
3221         if ( a == NULL ) {
3222                 return 1;
3223         }
3224
3225         if ( e == NULL ) {
3226                 return 1;
3227         }
3228
3229         rc = slapi_pblock_get( c->cac_pb, SLAPI_BACKEND, (void *)&be );
3230         if ( rc != 0 ) {
3231                 be = NULL; /* no backend for root DSE */
3232         }
3233
3234         rc = slapi_pblock_get( c->cac_pb, SLAPI_CONNECTION, (void *)&conn );
3235         if ( rc != 0 || conn == NULL ) {
3236                 return rc;
3237         }
3238
3239         rc = slapi_pblock_get( c->cac_pb, SLAPI_OPERATION, (void *)&op );
3240         if ( rc != 0 || op == NULL ) {
3241                 return rc;
3242         }
3243
3244         ber = (BerElement *)c->cac_private;
3245         desc = a->a_desc;
3246
3247         if ( c->cac_attrs == NULL ) {
3248                 /* All attrs request, skip operational attributes */
3249                 if ( is_at_operational( desc->ad_type ) ) {
3250                         return 0;
3251                 }
3252         } else {
3253                 /* Specific attrs requested */
3254                 if ( is_at_operational( desc->ad_type ) ) {
3255                         if ( !c->cac_opattrs && !ad_inlist( desc, c->cac_attrs ) ) {
3256                                 return 0;
3257                         }
3258                 } else {
3259                         if ( !c->cac_userattrs && !ad_inlist( desc, c->cac_attrs ) ) {
3260                                 return 0;
3261                         }
3262                 }
3263         }
3264
3265         if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_READ, &c->cac_acl_state) ) {
3266                 slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
3267                         "acl: access to attribute %s not allowed\n",
3268                         desc->ad_cname.bv_val );
3269                 return 0;
3270         }
3271
3272         rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
3273         if (rc == -1 ) {
3274                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
3275                         "ber_printf failed\n");
3276                 return 1;
3277         }
3278
3279         if ( !c->cac_attrsonly ) {
3280                 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
3281                         if ( !access_allowed( be, conn, op, e,
3282                                 desc, &a->a_vals[i], ACL_READ, &c->cac_acl_state)) {
3283                                 slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
3284                                         "slapi_x_compute_output_ber: conn %lu "
3285                                         "acl: access to %s, value %d not allowed\n",
3286                                         op->o_connid, desc->ad_cname.bv_val, i  );
3287                                 continue;
3288                         }
3289         
3290                         if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
3291                                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
3292                                         "ber_printf failed\n");
3293                                 return 1;
3294                         }
3295                 }
3296         }
3297
3298         if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
3299                 slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
3300                         "ber_printf failed\n" );
3301                 return 1;
3302         }
3303
3304         return 0;
3305 #else
3306         return 1;
3307 #endif
3308 }
3309
3310 /*
3311  * For some reason Sun don't use the normal plugin mechanism
3312  * registration path to register an "evaluator" function (an
3313  * "evaluator" is responsible for adding computed attributes;
3314  * the nomenclature is somewhat confusing).
3315  *
3316  * As such slapi_compute_add_evaluator() registers the 
3317  * function directly.
3318  */
3319 int slapi_compute_add_evaluator(slapi_compute_callback_t function)
3320 {
3321 #ifdef LDAP_SLAPI
3322         Slapi_PBlock *pPlugin = NULL;
3323         int rc;
3324
3325         pPlugin = slapi_pblock_new();
3326         if ( pPlugin == NULL ) {
3327                 rc = LDAP_NO_MEMORY;
3328                 goto done;
3329         }
3330
3331         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
3332         if ( rc != LDAP_SUCCESS ) {
3333                 goto done;
3334         }
3335
3336         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (void *)function );
3337         if ( rc != LDAP_SUCCESS ) {
3338                 goto done;
3339         }
3340
3341         rc = insertPlugin( NULL, pPlugin );
3342         if ( rc != 0 ) {
3343                 rc = LDAP_OTHER;
3344                 goto done;
3345         }
3346
3347 done:
3348         if ( rc != LDAP_SUCCESS ) {
3349                 if ( pPlugin != NULL ) {
3350                         slapi_pblock_destroy( pPlugin );
3351                 }
3352                 return -1;
3353         }
3354
3355         return 0;
3356 #else
3357         return -1;
3358 #endif /* LDAP_SLAPI */
3359 }
3360
3361 /*
3362  * See notes above regarding slapi_compute_add_evaluator().
3363  */
3364 int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
3365 {
3366 #ifdef LDAP_SLAPI
3367         Slapi_PBlock *pPlugin = NULL;
3368         int rc;
3369
3370         pPlugin = slapi_pblock_new();
3371         if ( pPlugin == NULL ) {
3372                 rc = LDAP_NO_MEMORY;
3373                 goto done;
3374         }
3375
3376         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
3377         if ( rc != LDAP_SUCCESS ) {
3378                 goto done;
3379         }
3380
3381         rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, (void *)function );
3382         if ( rc != LDAP_SUCCESS ) {
3383                 goto done;
3384         }
3385
3386         rc = insertPlugin( NULL, pPlugin );
3387         if ( rc != 0 ) {
3388                 rc = LDAP_OTHER;
3389                 goto done;
3390         }
3391
3392 done:
3393         if ( rc != LDAP_SUCCESS ) {
3394                 if ( pPlugin != NULL ) {
3395                         slapi_pblock_destroy( pPlugin );
3396                 }
3397                 return -1;
3398         }
3399
3400         return 0;
3401 #else
3402         return -1;
3403 #endif /* LDAP_SLAPI */
3404 }
3405
3406 /*
3407  * Call compute evaluators
3408  */
3409 int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn)
3410 {
3411 #ifdef LDAP_SLAPI
3412         int rc = 0;
3413         slapi_compute_callback_t *pGetPlugin, *tmpPlugin;
3414
3415         rc = getAllPluginFuncs( NULL, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (SLAPI_FUNC **)&tmpPlugin );
3416         if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
3417                 /* Nothing to do; front-end should ignore. */
3418                 return 0;
3419         }
3420
3421         for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
3422                 /*
3423                  * -1: no attribute matched requested type
3424                  *  0: one attribute matched
3425                  * >0: error happened
3426                  */
3427                 rc = (*pGetPlugin)( c, type, e, outputfn );
3428                 if ( rc > 0 ) {
3429                         break;
3430                 }
3431         }
3432
3433         slapi_ch_free( (void **)&tmpPlugin );
3434
3435         return rc;
3436 #else
3437         return 1;
3438 #endif /* LDAP_SLAPI */
3439 }
3440
3441 int compute_rewrite_search_filter(Slapi_PBlock *pb)
3442 {
3443 #ifdef LDAP_SLAPI
3444         Backend *be;
3445         int rc;
3446
3447         rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be );
3448         if ( rc != 0 ) {
3449                 return rc;
3450         }
3451
3452         return doPluginFNs( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
3453 #else
3454         return -1;
3455 #endif /* LDAP_SLAPI */
3456 }
3457
3458 /*
3459  * New API to provide the plugin with access to the search
3460  * pblock. Have informed Sun DS team.
3461  */
3462 int slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
3463 {
3464 #ifdef LDAP_SLAPI
3465         if ( c == NULL )
3466                 return -1;
3467
3468         if ( c->cac_pb == NULL )
3469                 return -1;
3470
3471         *pb = c->cac_pb;
3472
3473         return 0;
3474 #else
3475         return -1;
3476 #endif /* LDAP_SLAPI */
3477 }
3478
3479 Slapi_Mutex *slapi_new_mutex( void )
3480 {
3481 #ifdef LDAP_SLAPI
3482         Slapi_Mutex *m;
3483
3484         m = (Slapi_Mutex *)slapi_ch_malloc( sizeof(*m) );
3485         if ( ldap_pvt_thread_mutex_init( &m->mutex ) != 0 ) {
3486                 slapi_ch_free( (void **)&m );
3487                 return NULL;
3488         }
3489
3490         return m;
3491 #else
3492         return NULL;
3493 #endif
3494 }
3495
3496 void slapi_destroy_mutex( Slapi_Mutex *mutex )
3497 {
3498 #ifdef LDAP_SLAPI
3499         if ( mutex != NULL ) {
3500                 ldap_pvt_thread_mutex_destroy( &mutex->mutex );
3501                 slapi_ch_free( (void **)&mutex);
3502         }
3503 #endif
3504 }
3505
3506 void slapi_lock_mutex( Slapi_Mutex *mutex )
3507 {
3508 #ifdef LDAP_SLAPI
3509         ldap_pvt_thread_mutex_lock( &mutex->mutex );
3510 #endif
3511 }
3512
3513 int slapi_unlock_mutex( Slapi_Mutex *mutex )
3514 {
3515 #ifdef LDAP_SLAPI
3516         return ldap_pvt_thread_mutex_unlock( &mutex->mutex );
3517 #else
3518         return -1;
3519 #endif
3520 }
3521
3522 Slapi_CondVar *slapi_new_condvar( Slapi_Mutex *mutex )
3523 {
3524 #ifdef LDAP_SLAPI
3525         Slapi_CondVar *cv;
3526
3527         if ( mutex == NULL ) {
3528                 return NULL;
3529         }
3530
3531         cv = (Slapi_CondVar *)slapi_ch_malloc( sizeof(*cv) );
3532         if ( ldap_pvt_thread_cond_init( &cv->cond ) != 0 ) {
3533                 slapi_ch_free( (void **)&cv );
3534                 return NULL;
3535         }
3536
3537         /* XXX struct copy */
3538         cv->mutex = mutex->mutex;
3539
3540         return cv;
3541 #else   
3542         return NULL;
3543 #endif
3544 }
3545
3546 void slapi_destroy_condvar( Slapi_CondVar *cvar )
3547 {
3548 #ifdef LDAP_SLAPI
3549         if ( cvar != NULL ) {
3550                 ldap_pvt_thread_cond_destroy( &cvar->cond );
3551                 slapi_ch_free( (void **)&cvar );
3552         }
3553 #endif
3554 }
3555
3556 int slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout )
3557 {
3558 #ifdef LDAP_SLAPI
3559         if ( cvar == NULL ) {
3560                 return -1;
3561         }
3562
3563         return ldap_pvt_thread_cond_wait( &cvar->cond, &cvar->mutex );
3564 #else
3565         return -1;
3566 #endif
3567 }
3568
3569 int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
3570 {
3571 #ifdef LDAP_SLAPI
3572         if ( cvar == NULL ) {
3573                 return -1;
3574         }
3575
3576         if ( notify_all ) {
3577                 return ldap_pvt_thread_cond_broadcast( &cvar->cond );
3578         }
3579
3580         return ldap_pvt_thread_cond_signal( &cvar->cond );
3581 #else
3582         return -1;
3583 #endif
3584 }
3585