]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
fe15ffd277886848858c3e4b0cdee6e12e49be42
[openldap] / servers / slapd / slapi / slapi_utils.c
1 /*
2  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*
6  * (C) Copyright IBM Corp. 1997,2002
7  * Redistribution and use in source and binary forms are permitted
8  * provided that this notice is preserved and that due credit is 
9  * given to IBM Corporation. This software is provided ``as is'' 
10  * without express or implied warranty.
11  */
12 /*
13  * Portions (C) Copyright PADL Software Pty Ltd.
14  * Redistribution and use in source and binary forms are permitted
15  * provided that this notice is preserved and that due credit is 
16  * given to PADL Software Pty Ltd. This software is provided ``as is'' 
17  * without express or implied warranty.
18  */
19
20 #include "portable.h"
21 #include "slapi_common.h"
22
23 #include <ac/string.h>
24
25 #include <slap.h>
26 #include <slapi.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <unistd.h>
30 #include <ldap_pvt.h>
31
32 struct berval *ns_get_supported_extop( int );
33
34 #ifdef _SPARC  
35 #include <sys/systeminfo.h>
36 #endif
37
38 #include <netdb.h>
39
40 /*
41  * server start time (should we use a struct timeval also in slapd?
42  */
43 static struct                   timeval base_time;
44 ldap_pvt_thread_mutex_t         slapi_hn_mutex;
45 ldap_pvt_thread_mutex_t         slapi_time_mutex;
46
47 /*
48  * This function converts an array of pointers to berval objects to
49  * an array of berval objects.
50  */
51
52 int
53 bvptr2obj(
54         struct berval   **bvptr, 
55         BerVarray       *bvobj )
56 {
57         int             rc = LDAP_SUCCESS;
58         int             i;
59         BerVarray       tmpberval;
60
61         if ( bvptr == NULL || *bvptr == NULL ) {
62                 return LDAP_OTHER;
63         }
64
65         for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
66                 ; /* EMPTY */
67         }
68
69         tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
70         if ( tmpberval == NULL ) {
71                 return LDAP_NO_MEMORY;
72         } 
73
74         for ( i = 0; bvptr[i] != NULL; i++ ) {
75                 tmpberval[i].bv_val = bvptr[i]->bv_val;
76                 tmpberval[i].bv_len = bvptr[i]->bv_len;
77         }
78
79         if ( rc == LDAP_SUCCESS ) {
80                 *bvobj = tmpberval;
81         }
82
83         return rc;
84 }
85
86 Slapi_Entry *
87 slapi_str2entry(
88         char            *s, 
89         int             check_dup )
90 {
91 #if defined(LDAP_SLAPI)
92         Slapi_Entry     *e = NULL;
93         char            *pTmpS;
94
95         pTmpS = slapi_ch_strdup( s );
96         if ( pTmpS != NULL ) {
97                 e = str2entry( pTmpS ); 
98                 slapi_ch_free( (void **)&pTmpS );
99         }
100
101         return e;
102 #else /* !defined(LDAP_SLAPI) */
103         return NULL;
104 #endif /* !defined(LDAP_SLAPI) */
105 }
106
107 char *
108 slapi_entry2str(
109         Slapi_Entry     *e, 
110         int             *len ) 
111 {
112 #if defined(LDAP_SLAPI)
113         char            *ret;
114
115         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
116         ret = entry2str( e, len );
117         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
118
119         return ret;
120 #else /* !defined(LDAP_SLAPI) */
121         return NULL;
122 #endif /* !defined(LDAP_SLAPI) */
123 }
124
125 char *
126 slapi_entry_get_dn( Slapi_Entry *e ) 
127 {
128 #if defined(LDAP_SLAPI)
129         return e->e_name.bv_val;
130 #else /* !defined(LDAP_SLAPI) */
131         return NULL;
132 #endif /* !defined(LDAP_SLAPI) */
133 }
134
135 int
136 slapi_x_entry_get_id( Slapi_Entry *e )
137 {
138 #if defined(LDAP_SLAPI)
139         return e->e_id;
140 #else
141         return NOID;
142 #endif /* !defined(LDAP_SLAPI) */
143 }
144
145 void 
146 slapi_entry_set_dn(
147         Slapi_Entry     *e, 
148         char            *ldn )
149 {
150 #if defined(LDAP_SLAPI)
151         struct berval   dn = { 0, NULL };
152
153         dn.bv_val = ldn;
154         dn.bv_len = strlen( ldn );
155
156         dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
157 #endif /* defined(LDAP_SLAPI) */
158 }
159
160 Slapi_Entry *
161 slapi_entry_dup( Slapi_Entry *e ) 
162 {
163 #if defined(LDAP_SLAPI)
164         char            *tmp = NULL;
165         Slapi_Entry     *tmpEnt;
166         int             len = 0;
167         
168         tmp = slapi_entry2str( e, &len );
169         if ( tmp == NULL ) {
170                 return (Slapi_Entry *)NULL;
171         }
172
173         tmpEnt = (Slapi_Entry *)str2entry( tmp );
174         if ( tmpEnt == NULL ) { 
175                 slapi_ch_free( (void **)&tmp );
176                 return (Slapi_Entry *)NULL;
177         }
178         
179         if (tmp != NULL) {
180                 slapi_ch_free( (void **)&tmp );
181         }
182
183         return tmpEnt;
184 #else /* !defined(LDAP_SLAPI) */
185         return NULL;
186 #endif /* !defined(LDAP_SLAPI) */
187 }
188
189 int 
190 slapi_entry_attr_delete(
191         Slapi_Entry     *e,             
192         char            *type ) 
193 {
194 #if defined(LDAP_SLAPI)
195         AttributeDescription    *ad = NULL;
196         const char              *text;
197
198         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
199                 return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
200         }
201
202         if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
203                 return 0;       /* attribute is deleted */
204         } else {
205                 return -1;      /* something went wrong */
206         }
207 #else /* !defined(LDAP_SLAPI) */
208         return -1;
209 #endif /* !defined(LDAP_SLAPI) */
210 }
211
212 Slapi_Entry *
213 slapi_entry_alloc( void ) 
214 {
215 #if defined(LDAP_SLAPI)
216         return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
217 #else /* !defined(LDAP_SLAPI) */
218         return NULL;
219 #endif /* !defined(LDAP_SLAPI) */
220 }
221
222 void 
223 slapi_entry_free( Slapi_Entry *e ) 
224 {
225 #if defined(LDAP_SLAPI)
226         entry_free( e );
227 #endif /* defined(LDAP_SLAPI) */
228 }
229
230 int 
231 slapi_entry_attr_merge(
232         Slapi_Entry     *e, 
233         char            *type, 
234         struct berval   **vals ) 
235 {
236 #if defined(LDAP_SLAPI)
237         AttributeDescription    *ad = NULL;
238         const char              *text;
239         BerVarray               bv;
240         int                     rc;
241
242         rc = bvptr2obj( vals, &bv );
243         if ( rc != LDAP_SUCCESS ) {
244                 return -1;
245         }
246         
247         rc = slap_str2ad( type, &ad, &text );
248         if ( rc != LDAP_SUCCESS ) {
249                 return -1;
250         }
251         
252         rc = attr_merge( e, ad, bv );
253         ch_free( bv );
254
255         return rc;
256 #else /* !defined(LDAP_SLAPI) */
257         return -1;
258 #endif /* !defined(LDAP_SLAPI) */
259 }
260
261 int
262 slapi_entry_attr_find(
263         Slapi_Entry     *e, 
264         char            *type, 
265         Slapi_Attr      **attr ) 
266 {
267 #if defined(LDAP_SLAPI)
268         AttributeDescription    *ad = NULL;
269         const char              *text;
270         int                     rc;
271
272         rc = slap_str2ad( type, &ad, &text );
273         if ( rc != LDAP_SUCCESS ) {
274                 return -1;
275         }
276
277         *attr = attr_find( e->e_attrs, ad );
278         if ( *attr == NULL ) {
279                 return -1;
280         }
281
282         return 0;
283 #else /* !defined(LDAP_SLAPI) */
284         return -1;
285 #endif /* !defined(LDAP_SLAPI) */
286 }
287
288 /* 
289  * FIXME -- The caller must free the allocated memory. 
290  * In Netscape they do not have to.
291  */
292 int 
293 slapi_attr_get_values(
294         Slapi_Attr      *attr, 
295         struct berval   ***vals ) 
296 {
297 #if defined(LDAP_SLAPI)
298         int             i, j;
299         struct berval   **bv;
300
301         if ( attr == NULL ) {
302                 return 1;
303         }
304
305         for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
306                 ; /* EMPTY */
307         }
308
309         bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
310         for ( j = 0; j < i; j++ ) {
311                 bv[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
312                 bv[j]->bv_val = ch_strdup( attr->a_vals[j].bv_val );
313                 bv[j]->bv_len = attr->a_vals[j].bv_len;
314         }
315         bv[j] = NULL;
316         
317         *vals = (struct berval **)bv;
318
319         return 0;
320 #else /* !defined(LDAP_SLAPI) */
321         return -1;
322 #endif /* !defined(LDAP_SLAPI) */
323 }
324
325 char *
326 slapi_dn_normalize( char *dn ) 
327 {
328 #if defined(LDAP_SLAPI)
329         struct berval   bdn;
330         struct berval   ndn;
331
332         assert( dn != NULL );
333         
334         bdn.bv_val = dn;
335         bdn.bv_len = strlen( dn );
336
337         dnNormalize2( NULL, &bdn, &ndn );
338
339         /*
340          * FIXME: ain't it safe to set dn = ndn.bv_val ?
341          */
342         dn = ch_strdup( ndn.bv_val );
343         ch_free( ndn.bv_val );
344         
345         return dn;
346 #else /* !defined(LDAP_SLAPI) */
347         return NULL;
348 #endif /* !defined(LDAP_SLAPI) */
349 }
350
351 /*
352  * FIXME: this function is dangerous and should be deprecated;
353  * DN normalization is a lot more than lower-casing, and BTW
354  * OpenLDAP's DN normalization for case insensitive attributes
355  * is already lower case
356  */
357 char *
358 slapi_dn_normalize_case( char *dn ) 
359 {
360 #if defined(LDAP_SLAPI)
361         slapi_dn_normalize( dn );
362         ldap_pvt_str2lower( dn );
363
364         return dn;
365 #else /* defined(LDAP_SLAPI) */
366         return NULL;
367 #endif /* defined(LDAP_SLAPI) */
368 }
369
370 int 
371 slapi_dn_issuffix(
372         char            *dn, 
373         char            *suffix )
374 {
375 #if defined(LDAP_SLAPI)
376         struct berval   bdn, ndn;
377         struct berval   bsuffix, nsuffix;
378
379         assert( dn != NULL );
380         assert( suffix != NULL );
381
382         bdn.bv_val = dn;
383         bdn.bv_len = strlen( dn );
384
385         bsuffix.bv_val = suffix;
386         bsuffix.bv_len = strlen( suffix );
387
388         dnNormalize2( NULL, &bdn, &ndn );
389         dnNormalize2( NULL, &bsuffix, &nsuffix );
390
391         return dnIsSuffix( &ndn, &nsuffix );
392 #else /* !defined(LDAP_SLAPI) */
393         return 0;
394 #endif /* !defined(LDAP_SLAPI) */
395 }
396
397 char *
398 slapi_dn_ignore_case( char *dn )
399 {       
400 #if defined(LDAP_SLAPI)
401         return slapi_dn_normalize_case( dn );
402 #else /* !defined(LDAP_SLAPI) */
403         return NULL;
404 #endif /* !defined(LDAP_SLAPI) */
405 }
406
407 char *
408 slapi_ch_malloc( unsigned long size ) 
409 {
410 #if defined(LDAP_SLAPI)
411         return ch_malloc( size );       
412 #else /* !defined(LDAP_SLAPI) */
413         return NULL;
414 #endif /* !defined(LDAP_SLAPI) */
415 }
416
417 void 
418 slapi_ch_free( void **ptr ) 
419 {
420 #if defined(LDAP_SLAPI)
421         ch_free( *ptr );
422         *ptr = NULL;
423 #endif /* defined(LDAP_SLAPI) */
424 }
425
426 void 
427 slapi_ch_free_string( char **ptr ) 
428 {
429 #if defined(LDAP_SLAPI)
430         slapi_ch_free( (void **)ptr );
431 #endif /* defined(LDAP_SLAPI) */
432 }
433
434 char *
435 slapi_ch_calloc(
436         unsigned long nelem, 
437         unsigned long size ) 
438 {
439 #if defined(LDAP_SLAPI)
440         return ch_calloc( nelem, size );
441 #else /* !defined(LDAP_SLAPI) */
442         return NULL;
443 #endif /* !defined(LDAP_SLAPI) */
444 }
445
446 char *
447 slapi_ch_realloc(
448         char *block, 
449         unsigned long size ) 
450 {
451 #if defined(LDAP_SLAPI)
452         return ch_realloc( block, size );
453 #else /* !defined(LDAP_SLAPI) */
454         return NULL;
455 #endif /* !defined(LDAP_SLAPI) */
456 }
457
458 char *
459 slapi_ch_strdup( char *s ) 
460 {
461 #if defined(LDAP_SLAPI)
462         return ch_strdup( (const char *)s );
463 #else /* !defined(LDAP_SLAPI) */
464         return NULL;
465 #endif /* !defined(LDAP_SLAPI) */
466 }
467
468 size_t
469 slapi_ch_stlen( char *s ) 
470 {
471 #if defined(LDAP_SLAPI)
472         return strlen( (const char *)s );
473 #else /* !defined(LDAP_SLAPI) */
474         return 0;
475 #endif /* !defined(LDAP_SLAPI) */
476 }
477
478 int 
479 slapi_control_present(
480         LDAPControl     **controls, 
481         char            *oid, 
482         struct berval   **val, 
483         int             *iscritical ) 
484 {
485 #if defined(LDAP_SLAPI)
486         int             i;
487         int             rc = 0;
488
489         if ( val ) {
490                 *val = NULL;
491         }
492         
493         if ( iscritical ) {
494                 *iscritical = 0;
495         }
496         
497         for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
498                 if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
499                         continue;
500                 }
501
502                 rc = 1;
503                 if ( controls[i]->ldctl_value.bv_len != 0 ) {
504                         /*
505                          * FIXME: according to 6.1 specification,
506                          *    "The val output parameter is set
507                          *    to point into the controls array.
508                          *    A copy of the control value is
509                          *    not made."
510                          */
511 #if 0
512                         struct berval   *pTmpBval;
513
514                         pTmpBval = (struct berval *)slapi_ch_malloc( sizeof(struct berval));
515                         if ( pTmpBval == NULL ) {
516                                 rc = 0;
517                         } else {
518                                 pTmpBval->bv_len = controls[i]->ldctl_value.bv_len;
519                                 pTmpBval->bv_val = controls[i]->ldctl_value.bv_val;
520                                 if ( val ) {
521                                         *val = pTmpBval;
522                                 } else {
523                                         slapi_ch_free( (void **)&pTmpBval );
524                                         rc = 0;
525                                 }
526                         }
527 #endif /* 0 */
528                         if ( val ) {
529                                 *val = &controls[i]->ldctl_value;
530                         }
531                 }
532
533                 if ( iscritical ) {
534                         *iscritical = controls[i]->ldctl_iscritical;
535                 }
536
537                 break;
538         }
539
540         return rc;
541 #else /* !defined(LDAP_SLAPI) */
542         return 0;
543 #endif /* !defined(LDAP_SLAPI) */
544 }
545
546 void 
547 slapi_register_supported_control(
548         char            *controloid, 
549         unsigned long   controlops )
550 {
551 #if defined(LDAP_SLAPI)
552         /* FIXME -- can not add controls to openLDAP dynamically */
553         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_CONTROLS",
554                         "can not add controls to openLDAP dynamically\n" );
555 #endif /* defined(LDAP_SLAPI) */
556 }
557
558 int 
559 slapi_get_supported_controls(
560         char            ***ctrloidsp, 
561         unsigned long   **ctrlopsp ) 
562 {
563 #if defined(LDAP_SLAPI)
564         int             i, n;
565         int             rc = 1;
566         char            **oids = NULL;
567         unsigned long   *masks = NULL;
568
569         for (n = 0; get_supported_ctrl( n ) != NULL; n++) {
570                 ; /* count them */
571         }
572         
573         if ( n == 0 ) {
574                 /* no controls */
575                 *ctrloidsp = NULL;
576                 *ctrlopsp = NULL;
577                 return LDAP_SUCCESS;
578         }
579
580
581         oids = (char **)slapi_ch_malloc( (n + 1) * sizeof(char *) );
582         if ( oids == NULL ) {
583                 rc = LDAP_NO_MEMORY;
584                 goto error_return;
585         }
586
587         masks = (unsigned long *)slapi_ch_malloc( n * sizeof(int) );
588         if ( masks == NULL ) {
589                 rc = LDAP_NO_MEMORY;
590                 goto error_return;
591         }
592
593         for ( i = 0; i < n; i++ ) {
594                 /*
595                  * FIXME: Netscape's specification says nothing about
596                  * memory; should we copy the OIDs or return pointers
597                  * to internal values? In OpenLDAP the latter is safe
598                  * since we do not allow to register coltrols runtime
599                  */
600                 oids[ i ] = ch_strdup( get_supported_ctrl( i ) );
601                 if ( oids[ i ] == NULL ) {
602                         rc = LDAP_NO_MEMORY;
603                         goto error_return;
604                 }
605                 masks[ i ] = (unsigned long)get_supported_ctrl_mask( i );
606         }
607
608         *ctrloidsp = oids;
609         *ctrlopsp = masks;
610         return LDAP_SUCCESS;
611
612 error_return:
613         if ( rc != LDAP_SUCCESS ) {
614                 for ( i = 0; oids != NULL && oids[ i ] != NULL; i++ ) {
615                         ch_free( oids[ i ] );
616                 }
617                 ch_free( oids );
618                 ch_free( masks );
619         }
620
621         return rc;
622 #else /* !defined(LDAP_SLAPI) */
623         return 1;
624 #endif /* !defined(LDAP_SLAPI) */
625 }
626
627 void 
628 slapi_register_supported_saslmechanism( char *mechanism )
629 {
630 #if defined(LDAP_SLAPI)
631         /* FIXME -- can not add saslmechanism to openLDAP dynamically */
632         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
633                         "can not add saslmechanism to openLDAP dynamically\n" );
634 #endif /* defined(LDAP_SLAPI) */
635 }
636
637 char **
638 slapi_get_supported_saslmechanisms( void )
639 {
640 #if defined(LDAP_SLAPI)
641         /* FIXME -- can not get the saslmechanism wihtout a connection. */
642         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
643                         "can not get the saslmechanism "
644                         "wihtout a connection\n" );
645         return NULL;
646 #else /* defined(LDAP_SLAPI) */
647         return NULL;
648 #endif /* defined(LDAP_SLAPI) */
649 }
650
651 char **
652 slapi_get_supported_extended_ops( void )
653 {
654 #if defined(LDAP_SLAPI)
655         int             i, j, k;
656         char            **ppExtOpOID = NULL;
657         int             numExtOps = 0;
658
659         for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
660                 ;
661         }
662         
663         for ( j = 0; ns_get_supported_extop( j ) != NULL; j++ ) {
664                 ;
665         }
666
667         numExtOps = i + j;
668         if ( numExtOps == 0 ) {
669                 return NULL;
670         }
671
672         ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
673         for ( k = 0; k < i; k++ ) {
674                 struct berval   *bv;
675
676                 bv = get_supported_extop( k );
677                 assert( bv != NULL );
678
679                 ppExtOpOID[ k ] = bv->bv_val;
680         }
681         
682         for ( ; k < j; k++ ) {
683                 struct berval   *bv;
684
685                 bv = ns_get_supported_extop( k );
686                 assert( bv != NULL );
687
688                 ppExtOpOID[ i + k ] = bv->bv_val;
689         }
690         ppExtOpOID[ i + k ] = NULL;
691
692         return ppExtOpOID;
693 #else /* !defined(LDAP_SLAPI) */
694         return NULL;
695 #endif /* !defined(LDAP_SLAPI) */
696 }
697
698 void 
699 slapi_send_ldap_result(
700         Slapi_PBlock    *pb, 
701         int             err, 
702         char            *matched, 
703         char            *text, 
704         int             nentries, 
705         struct berval   **urls ) 
706 {
707 #if defined(LDAP_SLAPI)
708         Connection      *conn;
709         Operation       *op;
710         struct berval   *s;
711         char            *extOID = NULL;
712         struct berval   *extValue = NULL;
713         int             rc;
714
715         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
716         slapi_pblock_get( pb, SLAPI_OPERATION, &op );
717         if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
718                 slapi_pblock_get( pb, SLAPI_BIND_RET_SASLCREDS, &s );
719                 rc = LDAP_SASL_BIND_IN_PROGRESS;
720                 send_ldap_sasl( conn, op, rc, NULL, NULL, NULL, NULL, s );
721                 return;
722         }
723
724         slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID, &extOID );
725         if ( extOID != NULL ) {
726                 slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE, &extValue );
727                 slapi_send_ldap_extended_response( conn, op, err, extOID,
728                                 extValue );
729                 return;
730         }
731
732         send_ldap_result( conn, op, err, matched, text, NULL, NULL );
733 #endif /* defined(LDAP_SLAPI) */
734 }
735
736 int 
737 slapi_send_ldap_search_entry(
738         Slapi_PBlock    *pb, 
739         Slapi_Entry     *e, 
740         LDAPControl     **ectrls, 
741         char            **attrs, 
742         int             attrsonly )
743 {
744 #if defined(LDAP_SLAPI)
745         Backend         *be;
746         Connection      *pConn;
747         Operation       *pOp;
748         int             rc;
749
750         int             i;
751         AttributeName   *an = NULL;
752         const char      *text;
753
754         for ( i = 0; attrs[ i ] != NULL; i++ ) {
755                 ; /* empty */
756         }
757
758         if ( i > 0 ) {
759                 an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
760                 for ( i = 0; attrs[i] != NULL; i++ ) {
761                         an[i].an_name.bv_val = ch_strdup( attrs[i] );
762                         an[i].an_name.bv_len = strlen( attrs[i] );
763                         an[i].an_desc = NULL;
764                         if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
765                                 return -1;
766                 }
767         }
768
769         if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
770                         ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
771                         ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
772                 rc = LDAP_OTHER;
773         } else {
774                 rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
775         }
776
777         return rc;
778
779 #else /* !defined(LDAP_SLAPI) */
780         return -1;
781 #endif /* !defined(LDAP_SLAPI) */
782 }
783
784
785 Slapi_Filter *
786 slapi_str2filter( char *str ) 
787 {
788 #if defined(LDAP_SLAPI)
789         return str2filter( str );
790 #else /* !defined(LDAP_SLAPI) */
791         return NULL;
792 #endif /* !defined(LDAP_SLAPI) */
793 }
794
795 void 
796 slapi_filter_free(
797         Slapi_Filter    *f, 
798         int             recurse ) 
799 {
800 #if defined(LDAP_SLAPI)
801         filter_free( f );
802 #endif /* defined(LDAP_SLAPI) */
803 }
804
805 int 
806 slapi_filter_get_choice( Slapi_Filter *f )
807 {
808 #if defined(LDAP_SLAPI)
809         int             rc;
810
811         if ( f != NULL ) {
812                 rc = f->f_choice;
813         } else {
814                 rc = 0;
815         }
816
817         return rc;
818 #else /* !defined(LDAP_SLAPI) */
819         return -1;              /* invalid filter type */
820 #endif /* !defined(LDAP_SLAPI) */
821 }
822
823 int 
824 slapi_filter_get_ava(
825         Slapi_Filter    *f, 
826         char            **type, 
827         struct berval   **bval )
828 {
829 #if defined(LDAP_SLAPI)
830         int             ftype;
831         int             rc = LDAP_SUCCESS;
832
833         assert( type != NULL );
834         assert( bval != NULL );
835
836         *type = NULL;
837         *bval = NULL;
838
839         ftype = f->f_choice;
840         if ( ftype == LDAP_FILTER_EQUALITY 
841                         || ftype ==  LDAP_FILTER_GE 
842                         || ftype == LDAP_FILTER_LE 
843                         || ftype == LDAP_FILTER_APPROX ) {
844                 *type = slapi_ch_strdup( f->f_un.f_un_ava->aa_desc->ad_cname.bv_val );
845                 if ( *type == NULL ) {
846                         rc = LDAP_NO_MEMORY;
847                         goto done;
848                 }
849
850                 *bval = (struct berval *)slapi_ch_malloc( sizeof(struct berval) );
851                 if ( *bval == NULL ) {
852                         rc = LDAP_NO_MEMORY;
853                         goto done;
854                 }
855
856                 (*bval)->bv_len = f->f_un.f_un_ava->aa_value.bv_len;
857                 (*bval)->bv_val = slapi_ch_strdup( f->f_un.f_un_ava->aa_value.bv_val );
858                 if ( (*bval)->bv_val == NULL ) {
859                         rc = LDAP_NO_MEMORY;
860                         goto done;
861                 }
862         } else { /* filter type not supported */
863                 rc = -1;
864         }
865
866 done:
867         if ( rc != LDAP_SUCCESS ) {
868                 if ( *bval ) {
869                         ch_free( *bval );
870                         *bval = NULL;
871                 }
872
873                 if ( *type ) {
874                         ch_free( *type );
875                         *type = NULL;
876                 }
877         }
878
879         return rc;
880 #else /* !defined(LDAP_SLAPI) */
881         return -1;
882 #endif /* !defined(LDAP_SLAPI) */
883 }
884
885 Slapi_Filter *
886 slapi_filter_list_first( Slapi_Filter *f )
887 {
888 #if defined(LDAP_SLAPI)
889         int             ftype;
890
891         if ( f == NULL ) {
892                 return NULL;
893         }
894
895         ftype = f->f_choice;
896         if ( ftype == LDAP_FILTER_AND
897                         || ftype == LDAP_FILTER_OR
898                         || ftype == LDAP_FILTER_NOT ) {
899                 return (Slapi_Filter *)f->f_and;
900         } else {
901                 return NULL;
902         }
903 #else /* !defined(LDAP_SLAPI) */
904         return NULL;
905 #endif /* !defined(LDAP_SLAPI) */
906 }
907
908 Slapi_Filter *
909 slapi_filter_list_next(
910         Slapi_Filter    *f, 
911         Slapi_Filter    *fprev )
912 {
913 #if defined(LDAP_SLAPI)
914         int             ftype;
915
916         if ( f == NULL ) {
917                 return NULL;
918         }
919
920         ftype = f->f_choice;
921         if ( ftype == LDAP_FILTER_AND
922                         || ftype == LDAP_FILTER_OR
923                         || ftype == LDAP_FILTER_NOT ) {
924                 if ( f->f_and == fprev ) {
925                         return f->f_and->f_next;
926                 }
927         }
928
929         return NULL;
930 #else /* !defined(LDAP_SLAPI) */
931         return NULL;
932 #endif /* !defined(LDAP_SLAPI) */
933 }
934
935 int 
936 slapi_send_ldap_extended_response(
937         Connection      *conn, 
938         Operation       *op,
939         int             errornum, 
940         char            *respName,
941         struct berval   *response )
942 {
943 #if defined(LDAP_SLAPI)
944         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
945                         respName,response, NULL );
946         return LDAP_SUCCESS;
947 #else /* !defined(LDAP_SLAPI) */
948         return -1;
949 #endif /* !defined(LDAP_SLAPI) */
950 }
951
952 int 
953 slapi_pw_find(
954         struct berval   **vals, 
955         struct berval   *v ) 
956 {
957 #if defined(LDAP_SLAPI)
958         /*
959          * FIXME: what's the point?
960          */
961         return 1;
962 #else /* !defined(LDAP_SLAPI) */
963         return 1;
964 #endif /* !defined(LDAP_SLAPI) */
965 }
966              
967 char *
968 slapi_get_hostname( void ) 
969 {
970 #if defined(LDAP_SLAPI)
971         char            *hn = NULL;
972
973         /*
974          * FIXME: I'd prefer a different check ...
975          */
976 #if defined _SPARC 
977         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
978         if ( hn == NULL) {
979                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
980                                 "can't malloc memory for hostname\n" );
981                 hn = NULL;
982                 
983         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
984                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
985                                 "can't get hostname\n" );
986                 slapi_ch_free( (void **)&hn );
987                 hn = NULL;
988         }
989 #else /* !_SPARC */
990         static int      been_here = 0;   
991         static char     *static_hn = NULL;
992
993         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
994         if ( !been_here ) {
995                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
996                 if ( static_hn == NULL) {
997                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
998                                         "can't malloc memory for hostname\n" );
999                         static_hn = NULL;
1000                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1001
1002                         return hn;
1003                         
1004                 } else { 
1005                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
1006                                 slapi_log_error( SLAPI_LOG_FATAL,
1007                                                 "SLAPI_SYSINFO",
1008                                                 "can't get hostname\n" );
1009                                 slapi_ch_free( (void **)&static_hn );
1010                                 static_hn = NULL;
1011                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1012
1013                                 return hn;
1014
1015                         } else {
1016                                 been_here = 1;
1017                         }
1018                 }
1019         }
1020         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
1021         
1022         hn = ch_strdup( static_hn );
1023 #endif /* !_SPARC */
1024
1025         return hn;
1026 #else /* !defined(LDAP_SLAPI) */
1027         return NULL;
1028 #endif /* !defined(LDAP_SLAPI) */
1029 }
1030
1031 /*
1032  * FIXME: this should go in an appropriate header ...
1033  */
1034 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1035
1036 int 
1037 slapi_log_error(
1038         int             severity, 
1039         char            *subsystem, 
1040         char            *fmt, 
1041         ... ) 
1042 {
1043 #if defined(LDAP_SLAPI)
1044         int             rc = LDAP_SUCCESS;
1045         va_list         arglist;
1046
1047         va_start( arglist, fmt );
1048         rc = vLogError( severity, subsystem, fmt, arglist );
1049         va_end( arglist );
1050
1051         return rc;
1052 #else /* !defined(LDAP_SLAPI) */
1053         return -1;
1054 #endif /* !defined(LDAP_SLAPI) */
1055 }
1056
1057
1058 unsigned long
1059 slapi_timer_current_time( void ) 
1060 {
1061 #if defined(LDAP_SLAPI)
1062         static int      first_time = 1;
1063 #if !defined (_WIN32)
1064         struct timeval  now;
1065         unsigned long   ret;
1066
1067         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1068         if (first_time) {
1069                 first_time = 0;
1070                 gettimeofday( &base_time, NULL );
1071         }
1072         gettimeofday( &now, NULL );
1073         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1074                         (now.tv_usec - base_time.tv_usec);
1075         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1076
1077         return ret;
1078
1079         /*
1080          * Ain't it better?
1081         return (slap_get_time() - starttime) * 1000000;
1082          */
1083 #else /* _WIN32 */
1084         LARGE_INTEGER now;
1085
1086         if ( first_time ) {
1087                 first_time = 0;
1088                 performance_counter_present = QueryPerformanceCounter( &base_time );
1089                 QueryPerformanceFrequency( &performance_freq );
1090         }
1091
1092         if ( !performance_counter_present )
1093              return 0;
1094
1095         QueryPerformanceCounter( &now );
1096         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1097 #endif /* _WIN32 */
1098 #else /* !defined(LDAP_SLAPI) */
1099         return 0;
1100 #endif /* !defined(LDAP_SLAPI) */
1101 }
1102
1103 /*
1104  * FIXME ?
1105  */
1106 unsigned long
1107 slapi_timer_get_time( char *label ) 
1108 {
1109 #if defined(LDAP_SLAPI)
1110         unsigned long start = slapi_timer_current_time();
1111         printf("%10ld %10ld usec %s\n", start, 0, label);
1112         return start;
1113 #else /* !defined(LDAP_SLAPI) */
1114         return 0;
1115 #endif /* !defined(LDAP_SLAPI) */
1116 }
1117
1118 /*
1119  * FIXME ?
1120  */
1121 void
1122 slapi_timer_elapsed_time(
1123         char *label,
1124         unsigned long start ) 
1125 {
1126 #if defined(LDAP_SLAPI)
1127         unsigned long stop = slapi_timer_current_time();
1128         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1129 #endif /* defined(LDAP_SLAPI) */
1130 }
1131
1132 void
1133 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1134 {
1135 #if defined(LDAP_SLAPI)
1136         Slapi_Entry     **entries;
1137         int             k = 0, nEnt = 0;
1138
1139         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1140         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1141         if ( nEnt == 0 ) {
1142                 return;
1143         }
1144         
1145         if ( entries == NULL ) {
1146                 return;
1147         }
1148         
1149         for ( k = 0; k < nEnt; k++ ) {
1150                 slapi_entry_free( entries[k] );
1151         }
1152         
1153         slapi_ch_free( (void **)&entries );
1154 #endif /* defined(LDAP_SLAPI) */
1155 }
1156
1157 /*
1158  * Internal API to prime a Slapi_PBlock with a Backend.
1159  */
1160 int slapi_x_backend_set_pb( Slapi_PBlock *pb, Backend *be )
1161 {
1162 #if defined(LDAP_SLAPI)
1163         int rc;
1164         
1165         rc = slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
1166         if ( rc != LDAP_SUCCESS )
1167                 return rc;
1168         
1169         if ( be != NULL ) {
1170                 rc = slapi_pblock_set( pb, SLAPI_BE_TYPE, (void *)be->bd_info->bi_type );
1171                 if ( rc != LDAP_SUCCESS )
1172                         return rc;
1173         }
1174
1175         return LDAP_SUCCESS;
1176 #else
1177         return -1;
1178 #endif /* defined(LDAP_SLAPI) */
1179 }
1180
1181 #if defined(LDAP_SLAPI)
1182 /*
1183  * If oldStyle is TRUE, then a value suitable for setting to
1184  * the deprecated SLAPI_CONN_AUTHTYPE value is returned 
1185  * (pointer to static storage).
1186  *
1187  * If oldStyle is FALSE, then a value suitable for setting to
1188  * the new SLAPI_CONN_AUTHMETHOD will be returned, which is
1189  * a pointer to allocated memory and will include the SASL
1190  * mechanism (if any).
1191  */
1192 static char *Authorization2AuthType( AuthorizationInformation *authz, int is_tls, int oldStyle )
1193 {
1194         size_t len;
1195         char *authType;
1196
1197         switch ( authz->sai_method ) {
1198         case LDAP_AUTH_SASL:
1199                 if ( oldStyle ) {
1200                         authType = SLAPD_AUTH_SASL;
1201                 } else {
1202                         len = sizeof(SLAPD_AUTH_SASL) + authz->sai_mech.bv_len;
1203                         authType = slapi_ch_malloc( len );
1204                         snprintf( authType, len, "%s%s", SLAPD_AUTH_SASL, authz->sai_mech.bv_val );
1205                 }
1206                 break;
1207         case LDAP_AUTH_SIMPLE:
1208                 authType = oldStyle ? SLAPD_AUTH_SIMPLE : slapi_ch_strdup( SLAPD_AUTH_SIMPLE );
1209                 break;
1210         case LDAP_AUTH_NONE:
1211                 authType = oldStyle ? SLAPD_AUTH_NONE : slapi_ch_strdup( SLAPD_AUTH_NONE );
1212                 break;
1213         default:
1214                 authType = NULL;
1215                 break;
1216         }
1217         if ( is_tls && authType == NULL ) {
1218                 authType = oldStyle ? SLAPD_AUTH_SSL : slapi_ch_strdup( SLAPD_AUTH_SSL );
1219         }
1220
1221         return authType;
1222 }
1223 #endif
1224
1225 /*
1226  * Internal API to prime a Slapi_PBlock with a Connection.
1227  */
1228 int slapi_x_connection_set_pb( Slapi_PBlock *pb, Connection *conn )
1229 {
1230 #if defined(LDAP_SLAPI)
1231         char *connAuthType;
1232         int rc;
1233
1234         rc = slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
1235         if ( rc != LDAP_SUCCESS )
1236                 return rc;
1237
1238         if ( strncmp( conn->c_peer_name.bv_val, "IP=", 3 ) == 0 ) {
1239                 rc = slapi_pblock_set( pb, SLAPI_CONN_CLIENTIP, (void *)&conn->c_peer_name.bv_val[3] );
1240                 if ( rc != LDAP_SUCCESS )
1241                         return rc;
1242         }
1243
1244         if ( strncmp( conn->c_sock_name.bv_val, "IP=", 3 ) == 0 ) {
1245                 rc = slapi_pblock_set( pb, SLAPI_CONN_SERVERIP, (void *)&conn->c_sock_name.bv_val[3] );
1246                 if ( rc != LDAP_SUCCESS )
1247                         return rc;
1248         }
1249
1250         rc = slapi_pblock_set( pb, SLAPI_CONN_ID, (void *)conn->c_connid );
1251         if ( rc != LDAP_SUCCESS )
1252                 return rc;
1253
1254         /* Returns pointer to static string */
1255         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 1 );
1256         if ( connAuthType != NULL ) {
1257                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
1258                 if ( rc != LDAP_SUCCESS )
1259                         return rc;
1260         }
1261
1262         /* Returns pointer to allocated string */
1263         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 0 );
1264         if ( connAuthType != NULL ) {
1265                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType);
1266                 if ( rc != LDAP_SUCCESS )
1267                         return rc;
1268         }
1269
1270         if ( conn->c_authz.sai_dn.bv_val != NULL ) {
1271                 char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
1272                 rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
1273                 if ( rc != LDAP_SUCCESS )
1274                         return rc;
1275         }
1276
1277         return rc;
1278 #else
1279         return -1;
1280 #endif /* defined(LDAP_SLAPI) */
1281 }
1282
1283 /*
1284  * Internal API to prime a Slapi_PBlock with an Operation.
1285  */
1286 int slapi_x_operation_set_pb( Slapi_PBlock *pb, Operation *op )
1287 {
1288 #if defined(LDAP_SLAPI)
1289         int isRoot = 0;
1290         int isUpdateDn = 0;
1291         int rc;
1292         Backend *be;
1293         char *opAuthType;
1294
1295         if ( slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
1296                 be = NULL;
1297         }
1298         if (be != NULL) {
1299                 isRoot = be_isroot( be, &op->o_ndn );
1300                 isUpdateDn = be_isupdate( be, &op->o_ndn );
1301         }
1302                 
1303         rc = slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
1304         if ( rc != LDAP_SUCCESS )
1305                 return rc;
1306
1307         rc = slapi_pblock_set( pb, SLAPI_OPINITIATED_TIME, (void *)op->o_time );
1308         if ( rc != LDAP_SUCCESS )
1309                 return rc;
1310
1311         rc = slapi_pblock_set( pb, SLAPI_OPERATION_ID, (void *)op->o_opid );
1312         if ( rc != LDAP_SUCCESS )
1313                 return rc;
1314
1315         rc = slapi_pblock_set( pb, SLAPI_OPERATION_TYPE, (void *)op->o_tag );
1316         if ( rc != LDAP_SUCCESS )
1317                 return rc;
1318
1319         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, (void *)isRoot );
1320         if ( rc != LDAP_SUCCESS )
1321                 return rc;
1322
1323         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISUPDATEDN, (void *)isUpdateDn );
1324         if ( rc != LDAP_SUCCESS )
1325                 return rc;
1326
1327         rc = slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
1328         if ( rc != LDAP_SUCCESS)
1329                 return rc;
1330
1331         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_DN, (void *)op->o_ndn.bv_val );
1332         if ( rc != LDAP_SUCCESS )
1333                 return rc;
1334
1335         rc = slapi_pblock_get( pb, SLAPI_CONN_AUTHMETHOD, (void *)&opAuthType );
1336         if ( rc == LDAP_SUCCESS && opAuthType != NULL ) {
1337                 /* Not quite sure what the point of this is. */
1338                 rc = slapi_pblock_set( pb, SLAPI_OPERATION_AUTHTYPE, (void *)opAuthType );
1339                 if ( rc != LDAP_SUCCESS )
1340                         return rc;
1341         }
1342
1343         return LDAP_SUCCESS;
1344 #else
1345         return -1;
1346 #endif
1347 }
1348
1349 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
1350 {
1351 #if defined( LDAP_SLAPI )
1352         Connection *conn;
1353
1354         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
1355         *isSSL = conn->c_is_tls;
1356
1357         return LDAP_SUCCESS;
1358 #else
1359         return -1;
1360 #endif /* defined(LDAP_SLAPI) */
1361 }
1362
1363 /*
1364  * DS 5.x compatability API follow
1365  */
1366
1367 int slapi_attr_get_flags( const Slapi_Attr *attr, unsigned long *flags )
1368 {
1369 #if defined( LDAP_SLAPI )
1370         AttributeType *at;
1371
1372         if ( attr == NULL )
1373                 return LDAP_PARAM_ERROR;
1374
1375         at = attr->a_desc->ad_type;
1376
1377         *flags = SLAPI_ATTR_FLAG_STD_ATTR;
1378
1379         if ( is_at_single_value( at ) )
1380                 *flags |= SLAPI_ATTR_FLAG_SINGLE;
1381         if ( is_at_operational( at ) )
1382                 *flags |= SLAPI_ATTR_FLAG_OPATTR;
1383         if ( is_at_obsolete( at ) )
1384                 *flags |= SLAPI_ATTR_FLAG_OBSOLETE;
1385         if ( is_at_collective( at ) )
1386                 *flags |= SLAPI_ATTR_FLAG_COLLECTIVE;
1387         if ( is_at_no_user_mod( at ) )
1388                 *flags |= SLAPI_ATTR_FLAG_NOUSERMOD;
1389
1390         return LDAP_SUCCESS;
1391 #else
1392         return -1;
1393 #endif /* defined(LDAP_SLAPI) */
1394 }
1395
1396 int slapi_attr_flag_is_set( const Slapi_Attr *attr, unsigned long flag )
1397 {
1398 #if defined( LDAP_SLAPI )
1399         unsigned long flags;
1400
1401         if ( slapi_attr_get_flags( attr, &flags ) != 0 )
1402                 return 0;
1403         return (flags & flag) ? 1 : 0;
1404 #else
1405         return 0;
1406 #endif /* defined(LDAP_SLAPI) */
1407 }
1408
1409 Slapi_Attr *slapi_attr_new( void )
1410 {
1411 #ifdef LDAP_SLAPI
1412         Attribute *ad;
1413
1414         ad = (Attribute  *)slapi_ch_calloc( 1, sizeof(*ad) );
1415
1416         return ad;
1417 #else
1418         return NULL;
1419 #endif
1420 }
1421
1422 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type )
1423 {
1424 #ifdef LDAP_SLAPI
1425         const char *text;
1426         AttributeDescription *ad = NULL;
1427
1428         if( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
1429                 return NULL;
1430         }
1431
1432         a->a_desc = ad;
1433         a->a_vals = NULL;
1434         a->a_next = NULL;
1435         a->a_flags = 0;
1436
1437         return a;
1438 #else
1439         return NULL;
1440 #endif
1441 }
1442
1443 void slapi_attr_free( Slapi_Attr **a )
1444 {
1445 #ifdef LDAP_SLAPI
1446         attr_free( *a );
1447         *a = NULL;
1448 #endif
1449 }
1450
1451 Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr )
1452 {
1453 #ifdef LDAP_SLAPI
1454         return attr_dup( (Slapi_Attr *)attr );
1455 #else
1456         return NULL;
1457 #endif
1458 }
1459
1460 int slapi_attr_add_value( Slapi_Attr *a, const Slapi_Value *v )
1461 {
1462 #ifdef LDAP_SLAPI
1463         return value_add_one( &a->a_vals, (Slapi_Value *)v );
1464 #else
1465         return -1;
1466 #endif
1467 }
1468
1469 int slapi_attr_type2plugin( const char *type, void **pi )
1470 {
1471         *pi = NULL;
1472
1473         return LDAP_OTHER;
1474 }
1475
1476 int slapi_attr_get_type( const Slapi_Attr *attr, char **type )
1477 {
1478 #ifdef LDAP_SLAPI
1479         if ( attr == NULL ) {
1480                 return LDAP_PARAM_ERROR;
1481         }
1482
1483         *type = attr->a_desc->ad_cname.bv_val;
1484
1485         return LDAP_SUCCESS;
1486 #else
1487         return -1;
1488 #endif
1489 }
1490
1491 int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp )
1492 {
1493 #ifdef LDAP_SLAPI
1494         if ( attr == NULL ) {
1495                 return LDAP_PARAM_ERROR;
1496         }
1497         *oidp = attr->a_desc->ad_type->sat_oid;
1498
1499         return LDAP_SUCCESS;
1500 #else
1501         return -1;
1502 #endif
1503 }
1504
1505 int slapi_attr_value_cmp( const Slapi_Attr *a, const struct berval *v1, const struct berval *v2 )
1506 {
1507 #ifdef LDAP_SLAPI
1508         MatchingRule *mr;
1509         int ret;
1510         int rc;
1511         const char *text;
1512
1513         mr = a->a_desc->ad_type->sat_equality;
1514         rc = value_match( &ret, a->a_desc, mr, SLAP_MR_ASSERTION_SYNTAX_MATCH,
1515                 (struct berval *)v1, (void *)v2, &text );
1516         if ( rc != LDAP_SUCCESS ) 
1517                 return -1;
1518
1519         return ( ret == 0 ) ? 0 : -1;
1520 #else
1521         return -1;
1522 #endif
1523 }
1524
1525 int slapi_attr_value_find( const Slapi_Attr *a, struct berval *v )
1526 {
1527 #ifdef LDAP_SLAPI
1528         MatchingRule *mr;
1529         struct berval *bv;
1530         int j;
1531         const char *text;
1532         int rc;
1533         int ret;
1534
1535         mr = a->a_desc->ad_type->sat_equality;
1536         for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
1537                 rc = value_match( &ret, a->a_desc, mr,
1538                         SLAP_MR_ASSERTION_SYNTAX_MATCH, bv, v, &text );
1539                 if ( rc != LDAP_SUCCESS ) {
1540                         return -1;
1541                 }
1542                 if ( ret == 0 ) {
1543                         return 0;
1544                 }
1545         }
1546 #endif
1547         return -1;
1548 }
1549
1550 int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
1551 {
1552 #ifdef LDAP_SLAPI
1553         AttributeDescription *a1 = NULL;
1554         AttributeDescription *a2 = NULL;
1555         const char *text;
1556         int ret;
1557
1558         if ( slap_str2ad( t1, &a1, &text ) != LDAP_SUCCESS ) {
1559                 return -1;
1560         }
1561
1562         if ( slap_str2ad( t2, &a2, &text ) != LDAP_SUCCESS ) {
1563                 return 1;
1564         }
1565
1566 #define ad_base_cmp(l,r) (((l)->ad_type->sat_cname.bv_len < (r)->ad_type->sat_cname.bv_len) \
1567         ? -1 : (((l)->ad_type->sat_cname.bv_len > (r)->ad_type->sat_cname.bv_len) \
1568                 ? 1 : strcasecmp((l)->ad_type->sat_cname.bv_val, (r)->ad_type->sat_cname.bv_val )))
1569
1570         switch ( opt ) {
1571         case SLAPI_TYPE_CMP_EXACT:
1572                 ret = ad_cmp( a1, a2 );
1573                 break;
1574         case SLAPI_TYPE_CMP_BASE:
1575                 ret = ad_base_cmp( a1, a2 );
1576                 break;
1577         case SLAPI_TYPE_CMP_SUBTYPE:
1578                 ret = is_ad_subtype( a2, a2 );
1579                 break;
1580         default:
1581                 ret = -1;
1582                 break;
1583         }
1584
1585         return ret;
1586 #else
1587         return -1;
1588 #endif
1589 }
1590
1591 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
1592 {
1593 #ifdef LDAP_SLAPI
1594         return slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT );
1595 #else
1596         return -1;
1597 #endif
1598 }
1599
1600 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
1601 {
1602 #ifdef LDAP_SLAPI
1603         return slapi_valueset_first_value( &a->a_vals, v );
1604 #else
1605         return -1;
1606 #endif
1607 }
1608
1609 int slapi_attr_next_value( Slapi_Attr *a, int hint, Slapi_Value **v )
1610 {
1611 #ifdef LDAP_SLAPI
1612         return slapi_valueset_next_value( &a->a_vals, hint, v );
1613 #else
1614         return -1;
1615 #endif
1616 }
1617
1618 int slapi_attr_get_numvalues( const Slapi_Attr *a, int *numValues )
1619 {
1620 #ifdef LDAP_SLAPI
1621         *numValues = slapi_valueset_count( &a->a_vals );
1622
1623         return 0;
1624 #else
1625         return -1;
1626 #endif
1627 }
1628
1629 int slapi_attr_get_valueset( const Slapi_Attr *a, Slapi_ValueSet **vs )
1630 {
1631 #ifdef LDAP_SLAPI
1632         *vs = &((Slapi_Attr *)a)->a_vals;
1633
1634         return 0;
1635 #else
1636         return -1;
1637 #endif
1638 }
1639
1640 int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals )
1641 {
1642 #ifdef LDAP_SLAPI
1643         return slapi_attr_get_values( a, vals );
1644 #else
1645         return -1;
1646 #endif
1647 }
1648
1649 char *slapi_attr_syntax_normalize( const char *s )
1650 {
1651 #ifdef LDAP_SLAPI
1652         AttributeDescription *ad = NULL;
1653         const char *text;
1654
1655         if ( slap_str2ad( s, &ad, &text ) != LDAP_SUCCESS ) {
1656                 return NULL;
1657         }
1658
1659         return ad->ad_cname.bv_val;
1660 #else
1661         return -1;
1662 #endif
1663 }
1664
1665 Slapi_Value *slapi_value_new( void )
1666 {
1667 #ifdef LDAP_SLAPI
1668         struct berval *bv;
1669
1670         bv = (struct berval *)slapi_ch_malloc( sizeof(*bv) );
1671
1672         return bv;
1673 #else
1674         return NULL;
1675 #endif
1676 }
1677
1678 Slapi_Value *slapi_value_new_berval(const struct berval *bval)
1679 {
1680 #ifdef LDAP_SLAPI
1681         return ber_dupbv( NULL, (struct berval *)bval );
1682 #else
1683         return NULL;
1684 #endif
1685 }
1686
1687 Slapi_Value *slapi_value_new_value(const Slapi_Value *v)
1688 {
1689 #ifdef LDAP_SLAPI
1690         return slapi_value_new_berval( v );
1691 #else
1692         return NULL;
1693 #endif
1694 }
1695
1696 Slapi_Value *slapi_value_new_string(const char *s)
1697 {
1698 #ifdef LDAP_SLAPI
1699         struct berval bv;
1700
1701         bv.bv_val = (char *)s;
1702         bv.bv_len = strlen( s );
1703
1704         return slapi_value_new_berval( &bv );
1705 #else
1706         return NULL;
1707 #endif
1708 }
1709
1710 Slapi_Value *slapi_value_init(Slapi_Value *val)
1711 {
1712 #ifdef LDAP_SLAPI
1713         val->bv_val = NULL;
1714         val->bv_len = 0;
1715
1716         return val;
1717 #else
1718         return NULL;
1719 #endif
1720 }
1721
1722 Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
1723 {
1724 #ifdef LDAP_SLAPI
1725         return ber_dupbv( v, bval );
1726 #else
1727         return NULL;
1728 #endif
1729 }
1730
1731 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
1732 {
1733 #ifdef LDAP_SLAPI
1734         v->bv_val = slapi_ch_strdup( (char *)s );
1735         v->bv_len = strlen( s );
1736
1737         return v;
1738 #else
1739         return NULL;
1740 #endif
1741 }
1742
1743 Slapi_Value *slapi_value_dup(const Slapi_Value *v)
1744 {
1745 #ifdef LDAP_SLAPI
1746         return slapi_value_new_value( v );
1747 #else
1748         return NULL;
1749 #endif
1750 }
1751
1752 void slapi_value_free(Slapi_Value **value)
1753 {
1754 #ifdef LDAP_SLAPI       
1755         if ( value == NULL ) {
1756                 return;
1757         }
1758
1759         if ( (*value) != NULL ) {
1760                 slapi_ch_free( (void **)&(*value)->bv_val );
1761                 slapi_ch_free( (void **)value );
1762         }
1763 #endif
1764 }
1765
1766 const struct berval *slapi_value_get_berval( const Slapi_Value *value )
1767 {
1768 #ifdef LDAP_SLAPI
1769         return value;
1770 #else
1771         return NULL;
1772 #endif
1773 }
1774
1775 Slapi_Value *slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
1776 {
1777 #ifdef LDAP_SLAPI
1778         if ( value == NULL ) {
1779                 return NULL;
1780         }
1781         if ( value->bv_val != NULL ) {
1782                 slapi_ch_free( (void **)&value->bv_val );
1783         }
1784         slapi_value_init_berval( value, (struct berval *)bval );
1785
1786         return value;
1787 #else
1788         return NULL;
1789 #endif
1790 }
1791
1792 Slapi_Value *slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
1793 {
1794 #ifdef LDAP_SLAPI
1795         if ( value == NULL ) {
1796                 return NULL;
1797         }
1798         return slapi_value_set_berval( value, vfrom );
1799 #else
1800         return NULL;
1801 #endif
1802 }
1803
1804 Slapi_Value *slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
1805 {
1806 #ifdef LDAP_SLAPI
1807         if ( value == NULL ) {
1808                 return NULL;
1809         }
1810         if ( value->bv_val != NULL ) {
1811                 slapi_ch_free( (void **)&value->bv_val );
1812         }
1813         value->bv_val = slapi_ch_malloc( len );
1814         value->bv_len = len;
1815         AC_MEMCPY( value->bv_val, val, len );
1816
1817         return value;
1818 #else
1819         return NULL;
1820 #endif
1821 }
1822
1823 int slapi_value_set_string(Slapi_Value *value, const char *strVal)
1824 {
1825 #ifdef LDAP_SLAPI
1826         if ( value == NULL ) {
1827                 return -1;
1828         }
1829         slapi_value_set( value, (void *)strVal, strlen( strVal ) );
1830         return 0;
1831 #else
1832         return NULL;
1833 #endif
1834 }
1835
1836 int slapi_value_set_int(Slapi_Value *value, int intVal)
1837 {
1838 #ifdef LDAP_SLAPI
1839         char buf[64];
1840
1841         snprintf( buf, sizeof( buf ), "%d", intVal );
1842
1843         return slapi_value_set_string( value, buf );
1844 #else
1845         return -1;
1846 #endif
1847 }
1848
1849 const char *slapi_value_get_string(const Slapi_Value *value)
1850 {
1851 #ifdef LDAP_SLAPI
1852         if ( value == NULL ) {
1853                 return NULL;
1854         }
1855         return value->bv_val;
1856 #else
1857         return NULL;
1858 #endif
1859 }
1860
1861 #ifdef LDAP_SLAPI
1862 static int checkBVString(const struct berval *bv)
1863 {
1864         int i;
1865
1866         for ( i = 0; i < bv->bv_len; i++ ) {
1867                 if ( bv->bv_val[i] == '\0' )
1868                         return 0;
1869         }
1870         if ( bv->bv_val[i] != '\0' )
1871                 return 0;
1872
1873         return 1;
1874 }
1875 #endif
1876
1877 int slapi_value_get_int(const Slapi_Value *value)
1878 {
1879 #ifdef LDAP_SLAPI
1880         if ( value == NULL ) return 0;
1881         if ( !checkBVString( value ) ) return 0;
1882
1883         return (int)strtol( value->bv_val, NULL, 10 );
1884 #else
1885         return NULL;
1886 #endif
1887 }
1888
1889 unsigned int slapi_value_get_uint(const Slapi_Value *value)
1890 {
1891 #ifdef LDAP_SLAPI
1892         if ( value == NULL ) return 0;
1893         if ( !checkBVString( value ) ) return 0;
1894
1895         return (unsigned int)strtoul( value->bv_val, NULL, 10 );
1896 #else
1897         return NULL;
1898 #endif
1899 }
1900
1901 long slapi_value_get_long(const Slapi_Value *value)
1902 {
1903 #ifdef LDAP_SLAPI
1904         if ( value == NULL ) return 0;
1905         if ( !checkBVString( value ) ) return 0;
1906
1907         return strtol( value->bv_val, NULL, 10 );
1908 #else
1909         return NULL;
1910 #endif
1911 }
1912
1913 unsigned long slapi_value_get_ulong(const Slapi_Value *value)
1914 {
1915 #ifdef LDAP_SLAPI
1916         if ( value == NULL ) return 0;
1917         if ( !checkBVString( value ) ) return 0;
1918
1919         return strtoul( value->bv_val, NULL, 10 );
1920 #else
1921         return NULL;
1922 #endif
1923 }
1924
1925 size_t slapi_value_get_length(const Slapi_Value *value)
1926 {
1927 #ifdef LDAP_SLAPI
1928         if ( value == NULL )
1929                 return 0;
1930
1931         return (size_t) value->bv_len;
1932 #else
1933         return 0;
1934 #endif
1935 }
1936
1937 int slapi_value_compare(const Slapi_Attr *a, const Slapi_Value *v1, const Slapi_Value *v2)
1938 {
1939 #ifdef LDAP_SLAPI
1940         return slapi_attr_value_cmp( a, v1, v2 );
1941 #else
1942         return -1;
1943 #endif
1944 }
1945
1946 /* A ValueSet is a container for a BerVarray. */
1947 Slapi_ValueSet *slapi_valueset_new( void )
1948 {
1949 #ifdef LDAP_SLAPI
1950         Slapi_ValueSet *vs;
1951
1952         vs = (Slapi_ValueSet *)slapi_ch_malloc( sizeof( *vs ) );
1953         *vs = NULL;
1954
1955         return vs;
1956 #else
1957         return NULL;
1958 #endif
1959 }
1960
1961 void slapi_valueset_free(Slapi_ValueSet *vs)
1962 {
1963 #ifdef LDAP_SLAPI
1964         if ( vs != NULL ) {
1965                 BerVarray vp = *vs;
1966
1967                 ber_bvarray_free( vp );
1968                 slapi_ch_free( (void **)&vp );
1969
1970                 *vs = NULL;
1971         }
1972 #endif
1973 }
1974
1975 void slapi_valueset_init(Slapi_ValueSet *vs)
1976 {
1977 #ifdef LDAP_SLAPI
1978         if ( vs != NULL && *vs == NULL ) {
1979                 *vs = (Slapi_ValueSet)slapi_ch_calloc( 1, sizeof(struct berval) );
1980                 (*vs)->bv_val = NULL;
1981                 (*vs)->bv_len = 0;
1982         }
1983 #endif
1984 }
1985
1986 void slapi_valueset_done(Slapi_ValueSet *vs)
1987 {
1988 #ifdef LDAP_SLAPI
1989         BerVarray vp;
1990
1991         if ( vs == NULL )
1992                 return;
1993
1994         for ( vp = *vs; vp->bv_val != NULL; vp++ ) {
1995                 vp->bv_len = 0;
1996                 slapi_ch_free( (void **)&vp->bv_val );
1997         }
1998         /* but don't free *vs or vs */
1999 #endif
2000 }
2001
2002 void slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
2003 {
2004 #ifdef LDAP_SLAPI
2005         struct berval bv;
2006
2007         ber_dupbv( &bv, (Slapi_Value *)addval );
2008         ber_bvarray_add( vs, &bv );
2009 #endif
2010 }
2011
2012 int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
2013 {
2014 #ifdef LDAP_SLAPI
2015         return slapi_valueset_next_value( vs, 0, v );
2016 #else
2017         return -1;
2018 #endif
2019 }
2020
2021 int slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
2022 {
2023 #ifdef LDAP_SLAPI
2024         int i;
2025         BerVarray vp;
2026
2027         if ( vs == NULL )
2028                 return -1;
2029
2030         vp = *vs;
2031
2032         for ( i = 0; vp[i].bv_val != NULL; i++ ) {
2033                 if ( i == index ) {
2034                         *v = &vp[i];
2035                         return index + 1;
2036                 }
2037         }
2038 #endif
2039
2040         return -1;
2041 }
2042
2043 int slapi_valueset_count( const Slapi_ValueSet *vs )
2044 {
2045 #ifdef LDAP_SLAPI
2046         int i;
2047         BerVarray vp;
2048
2049         if ( vs == NULL )
2050                 return 0;
2051
2052         vp = *vs;
2053
2054         for ( i = 0; vp[i].bv_val != NULL; i++ )
2055                 ;
2056
2057         return i;
2058 #else
2059         return 0;
2060 #endif
2061
2062 }
2063
2064 void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
2065 {
2066 #ifdef LDAP_SLAPI
2067         BerVarray vp;
2068
2069         for ( vp = *vs2; vp->bv_val != NULL; vp++ ) {
2070                 slapi_valueset_add_value( vs1, vp );
2071         }
2072 #endif
2073 }
2074
2075 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
2076         struct berval *val, int access )
2077 {
2078 #ifdef LDAPI_SLAPI
2079         Backend *be;
2080         Connection *conn;
2081         Operation *op;
2082         int ret;
2083         slap_access_t slap_access;
2084         AttributeDescription *ad = NULL;
2085         char *text;
2086
2087         ret = slap_str2ad( attr, &ad, &text );
2088         if ( ret != LDAP_SUCCESS ) {
2089                 return ret;
2090         }
2091
2092         switch ( access & SLAPI_ACL_ALL ) {
2093         case SLAPI_ACL_COMPARE:
2094                 slap_access = ACL_COMPARE;
2095                 break;
2096         case SLAPI_ACL_SEARCH:
2097                 slap_access = ACL_SEARCH;
2098                 break;
2099         case SLAPI_ACL_READ:
2100                 slap_access = ACL_READ;
2101                 break;
2102         case SLAPI_ACL_WRITE:
2103         case SLAPI_ACL_DELETE:
2104         case SLAPI_ACL_ADD:
2105         case SLAPI_ACL_SELF:
2106                 slap_access = ACL_WRITE;
2107                 break;
2108         default:
2109                 return LDAP_INSUFFICIENT_ACCESS;
2110                 break;
2111         }
2112
2113         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2114                 return LDAP_PARAM_ERROR;
2115         }
2116
2117         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
2118                 return LDAP_PARAM_ERROR;
2119         }
2120
2121         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
2122                 return LDAP_PARAM_ERROR;
2123         }
2124
2125         ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL );
2126
2127         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2128 #else
2129         return LDAP_UNWILLING_TO_PERFORM;
2130 #endif
2131 }
2132
2133 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
2134 {
2135 #ifdef LDAP_SLAPI
2136         Backend *be;
2137         Connection *conn;
2138         Operation *op;
2139         int ret;
2140         Modifications *ml;
2141         Modifications *next;
2142
2143         if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
2144                 return LDAP_PARAM_ERROR;
2145         }
2146
2147         if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
2148                 return LDAP_PARAM_ERROR;
2149         }
2150
2151         if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
2152                 return LDAP_PARAM_ERROR;
2153         }
2154
2155         ml = slapi_x_ldapmods2modifications( mods );
2156         if ( ml == NULL ) {
2157                 return LDAP_OTHER;
2158         }
2159
2160         ret = acl_check_modlist( be, conn, op, e, ml );
2161
2162         /* Careful when freeing the modlist because it has pointers into the mods array. */
2163         for ( ; ml != NULL; ml = next ) {
2164                 next = ml->sml_next;
2165
2166                 /* just free the containing array */
2167                 slapi_ch_free( (void **)&ml->sml_bvalues );
2168                 slapi_ch_free( (void **)&ml );
2169         }
2170
2171         return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
2172 #else
2173         return LDAP_UNWILLING_TO_PERFORM;
2174 #endif
2175 }
2176
2177 /*
2178  * Attribute sets are an OpenLDAP extension for the 
2179  * virtual operational attribute coalescing plugin  
2180  *
2181  * Subject to going away very soon; do not use
2182  */
2183 Slapi_AttrSet *slapi_x_attrset_new( void )
2184 {
2185 #ifdef LDAP_SLAPI
2186         Slapi_AttrSet *a;
2187
2188         /*
2189          * Like a Slapi_ValueSet, a Slapi_AttrSet is a container
2190          * for objects: we need this because it may be initially
2191          * empty.
2192          */
2193         a = (Slapi_AttrSet *)slapi_ch_malloc( sizeof( *a ) );
2194         *a = NULL;
2195
2196         return a;
2197 #else
2198         return NULL;
2199 #endif
2200 }
2201
2202 Slapi_AttrSet *slapi_x_attrset_init( Slapi_AttrSet *as, Slapi_Attr *a )
2203 {
2204 #ifdef LDAP_SLAPI
2205         *as = a;
2206         a->a_next = NULL;
2207
2208         return as;
2209 #else
2210         return NULL;
2211 #endif
2212 }
2213
2214 void slapi_x_attrset_free( Slapi_AttrSet **pAs )
2215 {
2216 #ifdef LDAP_SLAPI
2217         Slapi_AttrSet *as = *pAs;
2218
2219         if ( as != NULL ) {
2220                 attrs_free( *as );
2221                 slapi_ch_free( (void **)pAs );
2222         }
2223 #endif
2224 }
2225
2226 Slapi_AttrSet *slapi_x_attrset_dup( Slapi_AttrSet *as )
2227 {
2228 #ifdef LDAP_SLAPI
2229         Slapi_AttrSet *newAs = slapi_x_attrset_new();
2230         
2231         if ( *as != NULL )
2232                 *newAs = attrs_dup( *as );
2233
2234         return newAs;
2235 #else
2236         return NULL;
2237 #endif
2238 }
2239
2240 int slapi_x_attrset_add_attr( Slapi_AttrSet *as, Slapi_Attr *a )
2241 {
2242 #ifdef LDAP_SLAPI
2243         Slapi_Attr *nextAttr;
2244
2245         if ( as == NULL || a == NULL )
2246                 return -1;
2247
2248         if ( *as == NULL ) {
2249                 /* First attribute */
2250                 nextAttr = NULL;
2251                 (*as) = a;
2252         } else {
2253                 /* Non-first attribute */
2254                 nextAttr = (*as)->a_next;
2255                 (*as)->a_next = a;
2256         }
2257
2258         a->a_next = nextAttr;
2259
2260         return 0;
2261 #else
2262         return -1;
2263 #endif
2264 }
2265
2266 int slapi_x_attrset_add_attr_copy( Slapi_AttrSet *as, Slapi_Attr *a )
2267 {
2268 #ifdef LDAP_SLAPI
2269         Slapi_Attr *adup;
2270
2271         adup = slapi_attr_dup( a );
2272         return slapi_x_attrset_add_attr( as, adup );
2273 #else
2274         return -1;
2275 #endif
2276 }
2277
2278 int slapi_x_attrset_find( Slapi_AttrSet *as, const char *type, Slapi_Attr **attr )
2279 {
2280 #ifdef LDAP_SLAPI
2281         AttributeDescription *ad = NULL;
2282         const char *text;
2283
2284         if ( as == NULL || *as == NULL ) {
2285                 return -1;
2286         }
2287
2288         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
2289                 return -1;
2290         }
2291         *attr = attrs_find( *as, ad );
2292         return ( *attr == NULL ) ? -1 : 0;
2293 #else
2294         return -1;
2295 #endif
2296 }
2297
2298 int slapi_x_attrset_merge( Slapi_AttrSet *as, const char *type, Slapi_ValueSet *vals )
2299 {
2300 #ifdef LDAP_SLAPI
2301         AttributeDescription *ad = NULL;
2302         Slapi_AttrSet *a;
2303         const char *text;
2304
2305         if ( vals == NULL || *vals == NULL ) {
2306                 /* Must have something to add. */
2307                 return -1;
2308         }
2309
2310         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
2311                 return -1;
2312         }
2313
2314         for ( a = as; *a != NULL; a = &(*a)->a_next ) {
2315                 if ( ad_cmp( (*a)->a_desc, ad ) == 0 ) {
2316                         break;
2317                 }
2318         }
2319
2320         if ( *a == NULL ) {
2321                 *a = (Slapi_Attr *) slapi_ch_malloc( sizeof(Attribute) );
2322                 (*a)->a_desc = ad;
2323                 (*a)->a_vals = NULL;
2324                 (*a)->a_next = NULL;
2325                 (*a)->a_flags = 0;
2326         }
2327
2328         return value_add ( &(*a)->a_vals, *vals );
2329 #else
2330         return -1;
2331 #endif
2332 }
2333
2334 int slapi_x_attrset_merge_bervals( Slapi_AttrSet *as, const char *type, struct berval **vals )
2335 {
2336 #ifdef LDAP_SLAPI
2337         BerVarray vp;
2338         int rc;
2339
2340         if ( bvptr2obj( vals, &vp ) != LDAP_SUCCESS ) {
2341                 return -1;
2342         }
2343         rc = slapi_x_attrset_merge( as, type, &vp );
2344         slapi_ch_free( (void **)&vp );
2345
2346         return rc;
2347 #else
2348         return -1;
2349 #endif
2350 }
2351
2352 int slapi_x_attrset_delete( Slapi_AttrSet *as, const char *type )
2353 {
2354 #ifdef LDAP_SLAPI
2355         AttributeDescription *ad = NULL;
2356         const char *text;
2357
2358         if ( as == NULL ) {
2359                 return -1;
2360         }
2361
2362         if ( *as == NULL ) {
2363                 return -1;
2364         }
2365
2366         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
2367                 return -1;
2368         }
2369
2370         if ( attr_delete( as, ad ) != LDAP_SUCCESS ) {
2371                 return -1;
2372         }
2373
2374         return 0;
2375 #else
2376         return -1;
2377 #endif
2378 }
2379
2380 /*
2381  * Synthesise an LDAPMod array from a Modifications list to pass
2382  * to SLAPI. This synthesis is destructive and as such the 
2383  * Modifications list may not be used after calling this 
2384  * function.
2385  * 
2386  * This function must also be called before slap_mods_check().
2387  */
2388 LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
2389 {
2390 #ifdef LDAP_SLAPI
2391         Modifications *ml, *modlist;
2392         LDAPMod **mods, *modp;
2393         int i, j;
2394
2395         modlist = *pmodlist;
2396
2397         for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
2398                 ;
2399
2400         mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
2401
2402         for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
2403                 modp = mods[i];
2404                 modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
2405
2406                 /* Take ownership of original type. */
2407                 modp->mod_type = ml->sml_type.bv_val;
2408                 ml->sml_type.bv_val = NULL;
2409
2410                 if ( ml->sml_bvalues != NULL ) {
2411                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
2412                                 ;
2413                         modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
2414                                 sizeof(struct berval *) );
2415                         for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
2416                                 /* Take ownership of original values. */
2417                                 modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
2418                                 modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
2419                                 modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
2420                                 ml->sml_bvalues[j].bv_len = 0;
2421                                 ml->sml_bvalues[j].bv_val = NULL;
2422                         }
2423                         modp->mod_bvalues[j] = NULL;
2424                 } else {
2425                         modp->mod_bvalues = NULL;
2426                 }
2427                 i++;
2428         }
2429
2430         mods[i] = NULL;
2431
2432         slap_mods_free( modlist );
2433         *pmodlist = NULL;
2434
2435         return mods;
2436 #else
2437         return NULL;
2438 #endif
2439 }
2440
2441 /*
2442  * Convert a potentially modified array of LDAPMods back to a
2443  * Modification list. 
2444  * 
2445  * The returned Modification list contains pointers into the
2446  * LDAPMods array; the latter MUST be freed with
2447  * slapi_x_free_ldapmods() (see below).
2448  */
2449 Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
2450 {
2451 #ifdef LDAP_SLAPI
2452         Modifications *modlist, **modtail;
2453         LDAPMod **modp;
2454
2455         modtail = &modlist;
2456
2457         for( modp = mods; *modp != NULL; modp++ ) {
2458                 Modifications *mod;
2459                 int i;
2460                 char **p;
2461                 struct berval **bvp;
2462
2463                 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
2464                 mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
2465                 mod->sml_type.bv_val = (*modp)->mod_type;
2466                 mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
2467                 mod->sml_desc = NULL;
2468                 mod->sml_next = NULL;
2469
2470                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2471                         for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ )
2472                                 ;
2473                 } else {
2474                         for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ )
2475                                 ;
2476                 }
2477
2478                 mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
2479
2480                 /* NB: This implicitly trusts a plugin to return valid modifications. */
2481                 if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
2482                         for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ ) {
2483                                 mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
2484                                 mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
2485                         }
2486                 } else {
2487                         for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ ) {
2488                                 mod->sml_bvalues[i].bv_val = *p;
2489                                 mod->sml_bvalues[i].bv_len = strlen( *p );
2490                         }
2491                 }
2492                 mod->sml_bvalues[i].bv_val = NULL;
2493
2494                 *modtail = mod;
2495                 modtail = &mod->sml_next;
2496         }
2497         
2498         return modlist;
2499 #else
2500         return NULL;
2501 #endif 
2502 }
2503
2504 /*
2505  * This function only frees the parts of the mods array that
2506  * are not shared with the Modification list that was created
2507  * by slapi_x_ldapmods2modifications(). 
2508  *
2509  */
2510 void slapi_x_free_ldapmods (LDAPMod **mods)
2511 {
2512 #ifdef LDAP_SLAPI
2513         int i, j;
2514
2515         if (mods == NULL)
2516                 return;
2517
2518         for ( i = 0; mods[i] != NULL; i++ ) {
2519                 /*
2520                  * Don't free values themselves; they're owned by the
2521                  * Modification list. Do free the containing array.
2522                  */
2523                 if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
2524                         for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ ) {
2525                                 ch_free( mods[i]->mod_bvalues[j] );
2526                         }
2527                         ch_free( mods[i]->mod_bvalues );
2528                 } else {
2529                         ch_free( mods[i]->mod_values );
2530                 }
2531                 /* Don't free type, for same reasons. */
2532                 ch_free( mods[i] );
2533         }
2534         ch_free( mods );
2535 #endif /* LDAP_SLAPI */
2536 }
2537