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