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