]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
Harmonise slapi_ch_free() with Sun ONE API
[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 #include "portable.h"
14 #include "slapi_common.h"
15
16 #include <slap.h>
17 #include <slapi.h>
18 #include <stdarg.h>
19 #include <ctype.h>
20 #include <slap.h>
21 #include <unistd.h>
22 #include <ldap_pvt.h>
23
24 struct berval *ns_get_supported_extop( int );
25
26 #ifdef _SPARC  
27 #include <sys/systeminfo.h>
28 #endif
29
30 #include <netdb.h>
31
32 /*
33  * server start time (should we use a struct timeval also in slapd?
34  */
35 static struct                   timeval base_time;
36 ldap_pvt_thread_mutex_t         slapi_hn_mutex;
37 ldap_pvt_thread_mutex_t         slapi_time_mutex;
38
39 /*
40  * This function converts an array of pointers to berval objects to
41  * an array of berval objects.
42  */
43
44 int
45 bvptr2obj(
46         struct berval   **bvptr, 
47         BerVarray       *bvobj )
48 {
49         int             rc = LDAP_SUCCESS;
50         int             i;
51         BerVarray       tmpberval;
52
53         if ( bvptr == NULL || *bvptr == NULL ) {
54                 return LDAP_OTHER;
55         }
56
57         for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
58                 ; /* EMPTY */
59         }
60
61         tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
62         if ( tmpberval == NULL ) {
63                 return LDAP_NO_MEMORY;
64         } 
65
66         for ( i = 0; bvptr[i] != NULL; i++ ) {
67                 tmpberval[i].bv_val = bvptr[i]->bv_val;
68                 tmpberval[i].bv_len = bvptr[i]->bv_len;
69         }
70
71         if ( rc == LDAP_SUCCESS ) {
72                 *bvobj = tmpberval;
73         }
74
75         return rc;
76 }
77
78 Slapi_Entry *
79 slapi_str2entry(
80         char            *s, 
81         int             check_dup )
82 {
83 #if defined(LDAP_SLAPI)
84         Slapi_Entry     *e = NULL;
85         char            *pTmpS;
86
87         pTmpS = slapi_ch_strdup( s );
88         if ( pTmpS != NULL ) {
89                 e = str2entry( pTmpS ); 
90                 slapi_ch_free( (void **)&pTmpS );
91         }
92
93         return e;
94 #else /* !defined(LDAP_SLAPI) */
95         return NULL;
96 #endif /* !defined(LDAP_SLAPI) */
97 }
98
99 char *
100 slapi_entry2str(
101         Slapi_Entry     *e, 
102         int             *len ) 
103 {
104 #if defined(LDAP_SLAPI)
105         char            *ret;
106
107         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
108         ret = entry2str( e, len );
109         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
110
111         return ret;
112 #else /* !defined(LDAP_SLAPI) */
113         return NULL;
114 #endif /* !defined(LDAP_SLAPI) */
115 }
116
117 char *
118 slapi_entry_get_dn( Slapi_Entry *e ) 
119 {
120 #if defined(LDAP_SLAPI)
121         return e->e_name.bv_val;
122 #else /* !defined(LDAP_SLAPI) */
123         return NULL;
124 #endif /* !defined(LDAP_SLAPI) */
125 }
126
127 void 
128 slapi_entry_set_dn(
129         Slapi_Entry     *e, 
130         char            *ldn )
131 {
132 #if defined(LDAP_SLAPI)
133         struct berval   dn = { 0, NULL };
134
135         dn.bv_val = ldn;
136         dn.bv_len = strlen( ldn );
137
138         dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
139 #endif /* defined(LDAP_SLAPI) */
140 }
141
142 Slapi_Entry *
143 slapi_entry_dup( Slapi_Entry *e ) 
144 {
145 #if defined(LDAP_SLAPI)
146         char            *tmp = NULL;
147         Slapi_Entry     *tmpEnt;
148         int             len = 0;
149         
150         tmp = slapi_entry2str( e, &len );
151         if ( tmp == NULL ) {
152                 return (Slapi_Entry *)NULL;
153         }
154
155         tmpEnt = (Slapi_Entry *)str2entry( tmp );
156         if ( tmpEnt == NULL ) { 
157                 slapi_ch_free( (void **)&tmp );
158                 return (Slapi_Entry *)NULL;
159         }
160         
161         if (tmp != NULL) {
162                 slapi_ch_free( (void **)&tmp );
163         }
164
165         return tmpEnt;
166 #else /* !defined(LDAP_SLAPI) */
167         return NULL;
168 #endif /* !defined(LDAP_SLAPI) */
169 }
170
171 int 
172 slapi_entry_attr_delete(
173         Slapi_Entry     *e,             
174         char            *type ) 
175 {
176 #if defined(LDAP_SLAPI)
177         AttributeDescription    *ad;
178         const char              *text;
179
180         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
181                 return 1;       /* LDAP_NO_SUCH_ATTRIBUTE */
182         }
183
184         if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
185                 return 0;       /* attribute is deleted */
186         } else {
187                 return -1;      /* something went wrong */
188         }
189 #else /* !defined(LDAP_SLAPI) */
190         return -1;
191 #endif /* !defined(LDAP_SLAPI) */
192 }
193
194 Slapi_Entry *
195 slapi_entry_alloc( void ) 
196 {
197 #if defined(LDAP_SLAPI)
198         return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
199 #else /* !defined(LDAP_SLAPI) */
200         return NULL;
201 #endif /* !defined(LDAP_SLAPI) */
202 }
203
204 void 
205 slapi_entry_free( Slapi_Entry *e ) 
206 {
207 #if defined(LDAP_SLAPI)
208         entry_free( e );
209 #endif /* defined(LDAP_SLAPI) */
210 }
211
212 int 
213 slapi_entry_attr_merge(
214         Slapi_Entry     *e, 
215         char            *type, 
216         struct berval   **vals ) 
217 {
218 #if defined(LDAP_SLAPI)
219         AttributeDescription    *ad;
220         const char              *text;
221         BerVarray               bv;
222         int                     rc;
223
224         rc = bvptr2obj( vals, &bv );
225         if ( rc != LDAP_SUCCESS ) {
226                 return -1;
227         }
228         
229         rc = slap_str2ad( type, &ad, &text );
230         if ( rc != LDAP_SUCCESS ) {
231                 return -1;
232         }
233         
234         rc = attr_merge( e, ad, bv );
235         ch_free( bv );
236
237         return rc;
238 #else /* !defined(LDAP_SLAPI) */
239         return -1;
240 #endif /* !defined(LDAP_SLAPI) */
241 }
242
243 int
244 slapi_entry_attr_find(
245         Slapi_Entry     *e, 
246         char            *type, 
247         Slapi_Attr      **attr ) 
248 {
249 #if defined(LDAP_SLAPI)
250         AttributeDescription    *ad;
251         const char              *text;
252         int                     rc;
253
254         rc = slap_str2ad( type, &ad, &text );
255         if ( rc != LDAP_SUCCESS ) {
256                 return -1;
257         }
258
259         *attr = attr_find( e->e_attrs, ad );
260         if ( *attr == NULL ) {
261                 return -1;
262         }
263
264         return 0;
265 #else /* !defined(LDAP_SLAPI) */
266         return -1;
267 #endif /* !defined(LDAP_SLAPI) */
268 }
269
270 /* 
271  * FIXME -- The caller must free the allocated memory. 
272  * In Netscape they do not have to.
273  */
274 int 
275 slapi_attr_get_values(
276         Slapi_Attr      *attr, 
277         struct berval   ***vals ) 
278 {
279 #if defined(LDAP_SLAPI)
280         int             i, j;
281         struct berval   **bv;
282
283         if ( attr == NULL ) {
284                 return 1;
285         }
286
287         for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
288                 ; /* EMPTY */
289         }
290
291         bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
292         for ( j = 0; j < i; j++ ) {
293                 bv[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
294                 bv[j]->bv_val = ch_strdup( attr->a_vals[j].bv_val );
295                 bv[j]->bv_len = attr->a_vals[j].bv_len;
296         }
297         bv[j] = NULL;
298         
299         *vals = (struct berval **)bv;
300
301         return 0;
302 #else /* !defined(LDAP_SLAPI) */
303         return -1;
304 #endif /* !defined(LDAP_SLAPI) */
305 }
306
307 char *
308 slapi_dn_normalize( char *dn ) 
309 {
310 #if defined(LDAP_SLAPI)
311         struct berval   bdn;
312         struct berval   ndn;
313
314         assert( dn != NULL );
315         
316         bdn.bv_val = dn;
317         bdn.bv_len = strlen( dn );
318
319         dnNormalize2( NULL, &bdn, &ndn );
320
321         /*
322          * FIXME: ain't it safe to set dn = ndn.bv_val ?
323          */
324         dn = ch_strdup( ndn.bv_val );
325         ch_free( ndn.bv_val );
326         
327         return dn;
328 #else /* !defined(LDAP_SLAPI) */
329         return NULL;
330 #endif /* !defined(LDAP_SLAPI) */
331 }
332
333 /*
334  * FIXME: this function is dangerous and should be deprecated;
335  * DN normalization is a lot more than lower-casing, and BTW
336  * OpenLDAP's DN normalization for case insensitive attributes
337  * is already lower case
338  */
339 char *
340 slapi_dn_normalize_case( char *dn ) 
341 {
342 #if defined(LDAP_SLAPI)
343         slapi_dn_normalize( dn );
344         ldap_pvt_str2lower( dn );
345
346         return dn;
347 #else /* defined(LDAP_SLAPI) */
348         return NULL;
349 #endif /* defined(LDAP_SLAPI) */
350 }
351
352 int 
353 slapi_dn_issuffix(
354         char            *dn, 
355         char            *suffix )
356 {
357 #if defined(LDAP_SLAPI)
358         struct berval   bdn, ndn;
359         struct berval   bsuffix, nsuffix;
360
361         assert( dn != NULL );
362         assert( suffix != NULL );
363
364         bdn.bv_val = dn;
365         bdn.bv_len = strlen( dn );
366
367         bsuffix.bv_val = suffix;
368         bsuffix.bv_len = strlen( suffix );
369
370         dnNormalize2( NULL, &bdn, &ndn );
371         dnNormalize2( NULL, &bsuffix, &nsuffix );
372
373         return dnIsSuffix( &ndn, &nsuffix );
374 #else /* !defined(LDAP_SLAPI) */
375         return 0;
376 #endif /* !defined(LDAP_SLAPI) */
377 }
378
379 char *
380 slapi_dn_ignore_case( char *dn )
381 {       
382 #if defined(LDAP_SLAPI)
383         return slapi_dn_normalize_case( dn );
384 #else /* !defined(LDAP_SLAPI) */
385         return NULL;
386 #endif /* !defined(LDAP_SLAPI) */
387 }
388
389 char *
390 slapi_ch_malloc( unsigned long size ) 
391 {
392 #if defined(LDAP_SLAPI)
393         return ch_malloc( size );       
394 #else /* !defined(LDAP_SLAPI) */
395         return NULL;
396 #endif /* !defined(LDAP_SLAPI) */
397 }
398
399 void 
400 slapi_ch_free( void **ptr ) 
401 {
402 #if defined(LDAP_SLAPI)
403         ch_free( *ptr );
404         *ptr = NULL;
405 #endif /* defined(LDAP_SLAPI) */
406 }
407
408 char *
409 slapi_ch_calloc(
410         unsigned long nelem, 
411         unsigned long size ) 
412 {
413 #if defined(LDAP_SLAPI)
414         return ch_calloc( nelem, size );
415 #else /* !defined(LDAP_SLAPI) */
416         return NULL;
417 #endif /* !defined(LDAP_SLAPI) */
418 }
419
420 char *
421 slapi_ch_realloc(
422         char *block, 
423         unsigned long size ) 
424 {
425 #if defined(LDAP_SLAPI)
426         return ch_realloc( block, size );
427 #else /* !defined(LDAP_SLAPI) */
428         return NULL;
429 #endif /* !defined(LDAP_SLAPI) */
430 }
431
432 char *
433 slapi_ch_strdup( char *s ) 
434 {
435 #if defined(LDAP_SLAPI)
436         return ch_strdup( (const char *)s );
437 #else /* !defined(LDAP_SLAPI) */
438         return NULL;
439 #endif /* !defined(LDAP_SLAPI) */
440 }
441
442 size_t
443 slapi_ch_stlen( char *s ) 
444 {
445 #if defined(LDAP_SLAPI)
446         return strlen( (const char *)s );
447 #else /* !defined(LDAP_SLAPI) */
448         return 0;
449 #endif /* !defined(LDAP_SLAPI) */
450 }
451
452 int 
453 slapi_control_present(
454         LDAPControl     **controls, 
455         char            *oid, 
456         struct berval   **val, 
457         int             *iscritical ) 
458 {
459 #if defined(LDAP_SLAPI)
460         int             i;
461         int             rc = 0;
462
463         if ( val ) {
464                 *val = NULL;
465         }
466         
467         if ( iscritical ) {
468                 *iscritical = 0;
469         }
470         
471         for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
472                 if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
473                         continue;
474                 }
475
476                 rc = 1;
477                 if ( controls[i]->ldctl_value.bv_len != 0 ) {
478                         /*
479                          * FIXME: according to 6.1 specification,
480                          *    "The val output parameter is set
481                          *    to point into the controls array.
482                          *    A copy of the control value is
483                          *    not made."
484                          */
485 #if 0
486                         struct berval   *pTmpBval;
487
488                         pTmpBval = (struct berval *)slapi_ch_malloc( sizeof(struct berval));
489                         if ( pTmpBval == NULL ) {
490                                 rc = 0;
491                         } else {
492                                 pTmpBval->bv_len = controls[i]->ldctl_value.bv_len;
493                                 pTmpBval->bv_val = controls[i]->ldctl_value.bv_val;
494                                 if ( val ) {
495                                         *val = pTmpBval;
496                                 } else {
497                                         slapi_ch_free( (void **)&pTmpBval );
498                                         rc = 0;
499                                 }
500                         }
501 #endif /* 0 */
502                         if ( val ) {
503                                 *val = &controls[i]->ldctl_value;
504                         }
505                 }
506
507                 if ( iscritical ) {
508                         *iscritical = controls[i]->ldctl_iscritical;
509                 }
510
511                 break;
512         }
513
514         return rc;
515 #else /* !defined(LDAP_SLAPI) */
516         return 0;
517 #endif /* !defined(LDAP_SLAPI) */
518 }
519
520 void 
521 slapi_register_supported_control(
522         char            *controloid, 
523         unsigned long   controlops )
524 {
525 #if defined(LDAP_SLAPI)
526         /* FIXME -- can not add controls to openLDAP dynamically */
527         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_CONTROLS",
528                         "can not add controls to openLDAP dynamically\n" );
529 #endif /* defined(LDAP_SLAPI) */
530 }
531
532 int 
533 slapi_get_supported_controls(
534         char            ***ctrloidsp, 
535         unsigned long   **ctrlopsp ) 
536 {
537 #if defined(LDAP_SLAPI)
538         int             i, n;
539         int             rc = 1;
540         char            **oids = NULL;
541         unsigned long   *masks = NULL;
542
543         for (n = 0; get_supported_ctrl( n ) != NULL; n++) {
544                 ; /* count them */
545         }
546         
547         if ( n == 0 ) {
548                 /* no controls */
549                 *ctrloidsp = NULL;
550                 *ctrlopsp = NULL;
551                 return LDAP_SUCCESS;
552         }
553
554
555         oids = (char **)slapi_ch_malloc( (n + 1) * sizeof(char *) );
556         if ( oids == NULL ) {
557                 rc = LDAP_NO_MEMORY;
558                 goto error_return;
559         }
560
561         masks = (unsigned long *)slapi_ch_malloc( n * sizeof(int) );
562         if ( masks == NULL ) {
563                 rc = LDAP_NO_MEMORY;
564                 goto error_return;
565         }
566
567         for ( i = 0; i < n; i++ ) {
568                 /*
569                  * FIXME: Netscape's specification says nothing about
570                  * memory; should we copy the OIDs or return pointers
571                  * to internal values? In OpenLDAP the latter is safe
572                  * since we do not allow to register coltrols runtime
573                  */
574                 oids[ i ] = ch_strdup( get_supported_ctrl( i ) );
575                 if ( oids[ i ] == NULL ) {
576                         rc = LDAP_NO_MEMORY;
577                         goto error_return;
578                 }
579                 masks[ i ] = (unsigned long)get_supported_ctrl_mask( i );
580         }
581
582         *ctrloidsp = oids;
583         *ctrlopsp = masks;
584         return LDAP_SUCCESS;
585
586 error_return:
587         if ( rc != LDAP_SUCCESS ) {
588                 for ( i = 0; oids != NULL && oids[ i ] != NULL; i++ ) {
589                         ch_free( oids[ i ] );
590                 }
591                 ch_free( oids );
592                 ch_free( masks );
593         }
594
595         return rc;
596 #else /* !defined(LDAP_SLAPI) */
597         return 1;
598 #endif /* !defined(LDAP_SLAPI) */
599 }
600
601 void 
602 slapi_register_supported_saslmechanism( char *mechanism )
603 {
604 #if defined(LDAP_SLAPI)
605         /* FIXME -- can not add saslmechanism to openLDAP dynamically */
606         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
607                         "can not add saslmechanism to openLDAP dynamically\n" );
608 #endif /* defined(LDAP_SLAPI) */
609 }
610
611 char **
612 slapi_get_supported_saslmechanisms( void )
613 {
614 #if defined(LDAP_SLAPI)
615         /* FIXME -- can not get the saslmechanism wihtout a connection. */
616         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
617                         "can not get the saslmechanism "
618                         "wihtout a connection\n" );
619         return NULL;
620 #else /* defined(LDAP_SLAPI) */
621         return NULL;
622 #endif /* defined(LDAP_SLAPI) */
623 }
624
625 char **
626 slapi_get_supported_extended_ops( void )
627 {
628 #if defined(LDAP_SLAPI)
629         int             i, j, k;
630         char            **ppExtOpOID = NULL;
631         int             numExtOps = 0;
632
633         for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
634                 ;
635         }
636         
637         for ( j = 0; ns_get_supported_extop( j ) != NULL; j++ ) {
638                 ;
639         }
640
641         numExtOps = i + j;
642         if ( numExtOps == 0 ) {
643                 return NULL;
644         }
645
646         ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
647         for ( k = 0; k < i; k++ ) {
648                 struct berval   *bv;
649
650                 bv = get_supported_extop( k );
651                 assert( bv != NULL );
652
653                 ppExtOpOID[ k ] = bv->bv_val;
654         }
655         
656         for ( ; k < j; k++ ) {
657                 struct berval   *bv;
658
659                 bv = ns_get_supported_extop( k );
660                 assert( bv != NULL );
661
662                 ppExtOpOID[ i + k ] = bv->bv_val;
663         }
664         ppExtOpOID[ i + k ] = NULL;
665
666         return ppExtOpOID;
667 #else /* !defined(LDAP_SLAPI) */
668         return NULL;
669 #endif /* !defined(LDAP_SLAPI) */
670 }
671
672 void 
673 slapi_send_ldap_result(
674         Slapi_PBlock    *pb, 
675         int             err, 
676         char            *matched, 
677         char            *text, 
678         int             nentries, 
679         struct berval   **urls ) 
680 {
681 #if defined(LDAP_SLAPI)
682         Connection      *conn;
683         Operation       *op;
684         struct berval   *s;
685         char            *extOID = NULL;
686         struct berval   *extValue = NULL;
687         int             rc;
688
689         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
690         slapi_pblock_get( pb, SLAPI_OPERATION, &op );
691         if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
692                 slapi_pblock_get( pb, SLAPI_BIND_RET_SASLCREDS, &s );
693                 rc = LDAP_SASL_BIND_IN_PROGRESS;
694                 send_ldap_sasl( conn, op, rc, NULL, NULL, NULL, NULL, s );
695                 return;
696         }
697
698         slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID, &extOID );
699         if ( extOID != NULL ) {
700                 slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE, &extValue );
701                 slapi_send_ldap_extended_response( conn, op, err, extOID,
702                                 extValue );
703                 return;
704         }
705
706         slapi_pblock_set( pb, SLAPI_RESULT_CODE, (void *)err);
707         slapi_pblock_set( pb, SLAPI_RESULT_MATCHED, ( matched != NULL ) ? (void *)ch_strdup( matched ) : NULL );
708         slapi_pblock_set( pb, SLAPI_RESULT_TEXT, ( text != NULL ) ? (void *)ch_strdup( text ) : NULL );
709
710         send_ldap_result( conn, op, err, matched, text, NULL, NULL );
711 #endif /* defined(LDAP_SLAPI) */
712 }
713
714 int 
715 slapi_send_ldap_search_entry(
716         Slapi_PBlock    *pb, 
717         Slapi_Entry     *e, 
718         LDAPControl     **ectrls, 
719         char            **attrs, 
720         int             attrsonly )
721 {
722 #if defined(LDAP_SLAPI)
723         Backend         *be;
724         Connection      *pConn;
725         Operation       *pOp;
726         int             rc;
727
728         int             i;
729         AttributeName   *an = NULL;
730         const char      *text;
731
732         for ( i = 0; attrs[ i ] != NULL; i++ ) {
733                 ; /* empty */
734         }
735
736         if ( i > 0 ) {
737                 an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
738                 for ( i = 0; attrs[i] != NULL; i++ ) {
739                         an[i].an_name.bv_val = ch_strdup( attrs[i] );
740                         an[i].an_name.bv_len = strlen( attrs[i] );
741                         an[i].an_desc = NULL;
742                         if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
743                                 return -1;
744                 }
745         }
746
747         if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
748                         ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
749                         ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
750                 rc = LDAP_OTHER;
751         } else {
752                 rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
753         }
754
755         return rc;
756
757 #else /* !defined(LDAP_SLAPI) */
758         return -1;
759 #endif /* !defined(LDAP_SLAPI) */
760 }
761
762
763 Slapi_Filter *
764 slapi_str2filter( char *str ) 
765 {
766 #if defined(LDAP_SLAPI)
767         return str2filter( str );
768 #else /* !defined(LDAP_SLAPI) */
769         return NULL;
770 #endif /* !defined(LDAP_SLAPI) */
771 }
772
773 void 
774 slapi_filter_free(
775         Slapi_Filter    *f, 
776         int             recurse ) 
777 {
778 #if defined(LDAP_SLAPI)
779         filter_free( f );
780 #endif /* defined(LDAP_SLAPI) */
781 }
782
783 int 
784 slapi_filter_get_choice( Slapi_Filter *f )
785 {
786 #if defined(LDAP_SLAPI)
787         int             rc;
788
789         if ( f != NULL ) {
790                 rc = f->f_choice;
791         } else {
792                 rc = 0;
793         }
794
795         return rc;
796 #else /* !defined(LDAP_SLAPI) */
797         return -1;              /* invalid filter type */
798 #endif /* !defined(LDAP_SLAPI) */
799 }
800
801 int 
802 slapi_filter_get_ava(
803         Slapi_Filter    *f, 
804         char            **type, 
805         struct berval   **bval )
806 {
807 #if defined(LDAP_SLAPI)
808         int             ftype;
809         int             rc = LDAP_SUCCESS;
810
811         assert( type != NULL );
812         assert( bval != NULL );
813
814         *type = NULL;
815         *bval = NULL;
816
817         ftype = f->f_choice;
818         if ( ftype == LDAP_FILTER_EQUALITY 
819                         || ftype ==  LDAP_FILTER_GE 
820                         || ftype == LDAP_FILTER_LE 
821                         || ftype == LDAP_FILTER_APPROX ) {
822                 *type = slapi_ch_strdup( f->f_un.f_un_ava->aa_desc->ad_cname.bv_val );
823                 if ( *type == NULL ) {
824                         rc = LDAP_NO_MEMORY;
825                         goto done;
826                 }
827
828                 *bval = (struct berval *)slapi_ch_malloc( sizeof(struct berval) );
829                 if ( *bval == NULL ) {
830                         rc = LDAP_NO_MEMORY;
831                         goto done;
832                 }
833
834                 (*bval)->bv_len = f->f_un.f_un_ava->aa_value.bv_len;
835                 (*bval)->bv_val = slapi_ch_strdup( f->f_un.f_un_ava->aa_value.bv_val );
836                 if ( (*bval)->bv_val == NULL ) {
837                         rc = LDAP_NO_MEMORY;
838                         goto done;
839                 }
840         } else { /* filter type not supported */
841                 rc = -1;
842         }
843
844 done:
845         if ( rc != LDAP_SUCCESS ) {
846                 if ( *bval ) {
847                         ch_free( *bval );
848                         *bval = NULL;
849                 }
850
851                 if ( *type ) {
852                         ch_free( *type );
853                         *type = NULL;
854                 }
855         }
856
857         return rc;
858 #else /* !defined(LDAP_SLAPI) */
859         return -1;
860 #endif /* !defined(LDAP_SLAPI) */
861 }
862
863 Slapi_Filter *
864 slapi_filter_list_first( Slapi_Filter *f )
865 {
866 #if defined(LDAP_SLAPI)
867         int             ftype;
868
869         if ( f == NULL ) {
870                 return NULL;
871         }
872
873         ftype = f->f_choice;
874         if ( ftype == LDAP_FILTER_AND
875                         || ftype == LDAP_FILTER_OR
876                         || ftype == LDAP_FILTER_NOT ) {
877                 return (Slapi_Filter *)f->f_and;
878         } else {
879                 return NULL;
880         }
881 #else /* !defined(LDAP_SLAPI) */
882         return NULL;
883 #endif /* !defined(LDAP_SLAPI) */
884 }
885
886 Slapi_Filter *
887 slapi_filter_list_next(
888         Slapi_Filter    *f, 
889         Slapi_Filter    *fprev )
890 {
891 #if defined(LDAP_SLAPI)
892         int             ftype;
893
894         if ( f == NULL ) {
895                 return NULL;
896         }
897
898         ftype = f->f_choice;
899         if ( ftype == LDAP_FILTER_AND
900                         || ftype == LDAP_FILTER_OR
901                         || ftype == LDAP_FILTER_NOT ) {
902                 if ( f->f_and == fprev ) {
903                         return f->f_and->f_next;
904                 }
905         }
906
907         return NULL;
908 #else /* !defined(LDAP_SLAPI) */
909         return NULL;
910 #endif /* !defined(LDAP_SLAPI) */
911 }
912
913 int 
914 slapi_send_ldap_extended_response(
915         Connection      *conn, 
916         Operation       *op,
917         int             errornum, 
918         char            *respName,
919         struct berval   *response )
920 {
921 #if defined(LDAP_SLAPI)
922         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
923                         respName,response, NULL );
924         return LDAP_SUCCESS;
925 #else /* !defined(LDAP_SLAPI) */
926         return -1;
927 #endif /* !defined(LDAP_SLAPI) */
928 }
929
930 int 
931 slapi_pw_find(
932         struct berval   **vals, 
933         struct berval   *v ) 
934 {
935 #if defined(LDAP_SLAPI)
936         /*
937          * FIXME: what's the point?
938          */
939         return 1;
940 #else /* !defined(LDAP_SLAPI) */
941         return 1;
942 #endif /* !defined(LDAP_SLAPI) */
943 }
944              
945 char *
946 slapi_get_hostname( void ) 
947 {
948 #if defined(LDAP_SLAPI)
949         char            *hn = NULL;
950
951         /*
952          * FIXME: I'd prefer a different check ...
953          */
954 #if defined _SPARC 
955         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
956         if ( hn == NULL) {
957                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
958                                 "can't malloc memory for hostname\n" );
959                 hn = NULL;
960                 
961         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
962                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
963                                 "can't get hostname\n" );
964                 slapi_ch_free( (void **)&hn );
965                 hn = NULL;
966         }
967 #else /* !_SPARC */
968         static int      been_here = 0;   
969         static char     *static_hn = NULL;
970
971         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
972         if ( !been_here ) {
973                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
974                 if ( static_hn == NULL) {
975                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
976                                         "can't malloc memory for hostname\n" );
977                         static_hn = NULL;
978                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
979
980                         return hn;
981                         
982                 } else { 
983                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
984                                 slapi_log_error( SLAPI_LOG_FATAL,
985                                                 "SLAPI_SYSINFO",
986                                                 "can't get hostname\n" );
987                                 slapi_ch_free( (void **)&static_hn );
988                                 static_hn = NULL;
989                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
990
991                                 return hn;
992
993                         } else {
994                                 been_here = 1;
995                         }
996                 }
997         }
998         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
999         
1000         hn = ch_strdup( static_hn );
1001 #endif /* !_SPARC */
1002
1003         return hn;
1004 #else /* !defined(LDAP_SLAPI) */
1005         return NULL;
1006 #endif /* !defined(LDAP_SLAPI) */
1007 }
1008
1009 /*
1010  * FIXME: this should go in an appropriate header ...
1011  */
1012 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1013
1014 int 
1015 slapi_log_error(
1016         int             severity, 
1017         char            *subsystem, 
1018         char            *fmt, 
1019         ... ) 
1020 {
1021 #if defined(LDAP_SLAPI)
1022         int             rc = LDAP_SUCCESS;
1023         va_list         arglist;
1024
1025         va_start( arglist, fmt );
1026         rc = vLogError( severity, subsystem, fmt, arglist );
1027         va_end( arglist );
1028
1029         return rc;
1030 #else /* !defined(LDAP_SLAPI) */
1031         return -1;
1032 #endif /* !defined(LDAP_SLAPI) */
1033 }
1034
1035
1036 unsigned long
1037 slapi_timer_current_time( void ) 
1038 {
1039 #if defined(LDAP_SLAPI)
1040         static int      first_time = 1;
1041 #if !defined (_WIN32)
1042         struct timeval  now;
1043         unsigned long   ret;
1044
1045         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1046         if (first_time) {
1047                 first_time = 0;
1048                 gettimeofday( &base_time, NULL );
1049         }
1050         gettimeofday( &now, NULL );
1051         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1052                         (now.tv_usec - base_time.tv_usec);
1053         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1054
1055         return ret;
1056
1057         /*
1058          * Ain't it better?
1059         return (slap_get_time() - starttime) * 1000000;
1060          */
1061 #else /* _WIN32 */
1062         LARGE_INTEGER now;
1063
1064         if ( first_time ) {
1065                 first_time = 0;
1066                 performance_counter_present = QueryPerformanceCounter( &base_time );
1067                 QueryPerformanceFrequency( &performance_freq );
1068         }
1069
1070         if ( !performance_counter_present )
1071              return 0;
1072
1073         QueryPerformanceCounter( &now );
1074         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1075 #endif /* _WIN32 */
1076 #else /* !defined(LDAP_SLAPI) */
1077         return 0;
1078 #endif /* !defined(LDAP_SLAPI) */
1079 }
1080
1081 /*
1082  * FIXME ?
1083  */
1084 unsigned long
1085 slapi_timer_get_time( char *label ) 
1086 {
1087 #if defined(LDAP_SLAPI)
1088         unsigned long start = slapi_timer_current_time();
1089         printf("%10ld %10ld usec %s\n", start, 0, label);
1090         return start;
1091 #else /* !defined(LDAP_SLAPI) */
1092         return 0;
1093 #endif /* !defined(LDAP_SLAPI) */
1094 }
1095
1096 /*
1097  * FIXME ?
1098  */
1099 void
1100 slapi_timer_elapsed_time(
1101         char *label,
1102         unsigned long start ) 
1103 {
1104 #if defined(LDAP_SLAPI)
1105         unsigned long stop = slapi_timer_current_time();
1106         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1107 #endif /* defined(LDAP_SLAPI) */
1108 }
1109
1110 void
1111 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1112 {
1113 #if defined(LDAP_SLAPI)
1114         Slapi_Entry     **entries;
1115         int             k = 0, nEnt = 0;
1116
1117         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1118         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1119         if ( nEnt == 0 ) {
1120                 return;
1121         }
1122         
1123         if ( entries == NULL ) {
1124                 return;
1125         }
1126         
1127         for ( k = 0; k < nEnt; k++ ) {
1128                 slapi_entry_free( entries[k] );
1129         }
1130         
1131         slapi_ch_free( (void **)&entries );
1132 #endif /* defined(LDAP_SLAPI) */
1133 }
1134
1135 /*
1136  * Internal API to prime a Slapi_PBlock with a Backend.
1137  */
1138 int slapi_backend_set_pb( Slapi_PBlock *pb, Backend *be )
1139 {
1140 #if defined(LDAP_SLAPI)
1141         int rc;
1142
1143         rc = slapi_pblock_set(pb, SLAPI_BACKEND, (void *)be);
1144         if (rc != LDAP_SUCCESS)
1145                 return rc;
1146
1147         rc = slapi_pblock_set(pb, SLAPI_BE_TYPE, (void *)be->bd_info->bi_type);
1148         if (rc != LDAP_SUCCESS)
1149                 return rc;
1150
1151         return LDAP_SUCCESS;
1152 #else
1153         return -1;
1154 #endif /* defined(LDAP_SLAPI) */
1155 }
1156
1157 /*
1158  * Internal API to prime a Slapi_PBlock with a Connection.
1159  */
1160 int slapi_connection_set_pb( Slapi_PBlock *pb, Connection *conn )
1161 {
1162 #if defined(LDAP_SLAPI)
1163         char *connAuthType;
1164         size_t len;
1165         int rc;
1166
1167         rc = slapi_pblock_set(pb, SLAPI_CONNECTION, (void *)conn);
1168         if (rc != LDAP_SUCCESS)
1169                 return rc;
1170
1171         rc = slapi_pblock_set(pb, SLAPI_CONN_ID, (void *)conn->c_connid);
1172         if (rc != LDAP_SUCCESS)
1173                 return rc;
1174
1175         switch (conn->c_authz.sai_method) {
1176         case LDAP_AUTH_SASL: 
1177                 len = sizeof(SLAPD_AUTH_SASL) + conn->c_authz.sai_mech.bv_len;
1178                 connAuthType = slapi_ch_malloc(len);
1179                 snprintf(connAuthType, len, "%s%s", SLAPD_AUTH_SASL, conn->c_authz.sai_mech.bv_val);
1180                 break;
1181         case LDAP_AUTH_SIMPLE:
1182                 connAuthType = slapi_ch_strdup(SLAPD_AUTH_SIMPLE);
1183                 break;
1184         case LDAP_AUTH_NONE:
1185                 connAuthType = slapi_ch_strdup(SLAPD_AUTH_NONE);
1186                 break;
1187         default:
1188                 connAuthType = NULL;
1189                 break;
1190         }
1191         if (conn->c_is_tls && connAuthType == NULL) {
1192                 connAuthType = slapi_ch_strdup(SLAPD_AUTH_SSL);
1193         }
1194         if (connAuthType != NULL) {
1195                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
1196                 if (rc != LDAP_SUCCESS)
1197                         return rc;
1198         }
1199         if (conn->c_authz.sai_dn.bv_val != NULL) {
1200                 char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
1201                 rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
1202                 if (rc != LDAP_SUCCESS)
1203                         return rc;
1204         }
1205         return LDAP_SUCCESS;
1206 #else
1207         return -1;
1208 #endif /* defined(LDAP_SLAPI) */
1209 }
1210
1211 /*
1212  * Internal API to prime a Slapi_PBlock with an Operation.
1213  */
1214 int slapi_operation_set_pb( Slapi_PBlock *pb, Operation *op )
1215 {
1216 #if defined(LDAP_SLAPI)
1217         int isRoot = 0;
1218         int isUpdateDn = 0;
1219         int rc;
1220         Backend *be;
1221
1222         if (slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be) != 0) {
1223                 be = NULL;
1224         }
1225         if (be != NULL) {
1226                 isRoot = be_isroot(be, &op->o_ndn);
1227                 isUpdateDn = be_isupdate(be, &op->o_ndn);
1228         }
1229                 
1230         rc = slapi_pblock_set(pb, SLAPI_OPERATION, (void *)op);
1231         if (rc != LDAP_SUCCESS)
1232                 return rc;
1233
1234         rc = slapi_pblock_set(pb, SLAPI_OPINITIATED_TIME, (void *)op->o_time);
1235         if (rc != LDAP_SUCCESS)
1236                 return rc;
1237
1238         rc = slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, (void *)isRoot);
1239         if (rc != LDAP_SUCCESS)
1240                 return rc;
1241
1242         rc = slapi_pblock_set(pb, SLAPI_REQUESTOR_ISUPDATEDN, (void *)isUpdateDn);
1243         if (rc != LDAP_SUCCESS)
1244                 return rc;
1245
1246         rc = slapi_pblock_set(pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls);
1247         if (rc != LDAP_SUCCESS)
1248                 return rc;
1249
1250         rc = slapi_pblock_set(pb, SLAPI_REQUESTOR_DN, (void *)op->o_ndn.bv_val);
1251         if (rc != LDAP_SUCCESS)
1252                 return rc;
1253
1254         return LDAP_SUCCESS;
1255 #else
1256         return -1;
1257 #endif
1258 }
1259
1260 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
1261 {
1262 #if defined( LDAP_SLAPI )
1263         Connection *conn;
1264
1265         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
1266         *isSSL = conn->c_is_tls;
1267
1268         return LDAP_SUCCESS;
1269 #else
1270         return -1;
1271 #endif /* defined(LDAP_SLAPI) */
1272 }