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