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