]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
SLAPI - Netscape plugin API for slapd - based on patch contributed by Steve Omrani...
[openldap] / servers / slapd / slapi / slapi_utils.c
1 /*
2  * Copyright 1998-2002 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( 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( tmp );
158                 return (Slapi_Entry *)NULL;
159         }
160         
161         if (tmp != NULL) {
162                 slapi_ch_free( 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 #if 0
404         if ( ptr != NULL )      /* not required ... */
405 #endif /* 0 */
406                 ch_free( ptr );
407 #endif /* defined(LDAP_SLAPI) */
408 }
409
410 char *
411 slapi_ch_calloc(
412         unsigned long nelem, 
413         unsigned long size ) 
414 {
415 #if defined(LDAP_SLAPI)
416         return ch_calloc( nelem, size );
417 #else /* !defined(LDAP_SLAPI) */
418         return NULL;
419 #endif /* !defined(LDAP_SLAPI) */
420 }
421
422 char *
423 slapi_ch_realloc(
424         char *block, 
425         unsigned long size ) 
426 {
427 #if defined(LDAP_SLAPI)
428         return ch_realloc( block, size );
429 #else /* !defined(LDAP_SLAPI) */
430         return NULL;
431 #endif /* !defined(LDAP_SLAPI) */
432 }
433
434 char *
435 slapi_ch_strdup( char *s ) 
436 {
437 #if defined(LDAP_SLAPI)
438         return ch_strdup( (const char *)s );
439 #else /* !defined(LDAP_SLAPI) */
440         return NULL;
441 #endif /* !defined(LDAP_SLAPI) */
442 }
443
444 size_t
445 slapi_ch_stlen( char *s ) 
446 {
447 #if defined(LDAP_SLAPI)
448         return strlen( (const char *)s );
449 #else /* !defined(LDAP_SLAPI) */
450         return 0;
451 #endif /* !defined(LDAP_SLAPI) */
452 }
453
454 int 
455 slapi_control_present(
456         LDAPControl     **controls, 
457         char            *oid, 
458         struct berval   **val, 
459         int             *iscritical ) 
460 {
461 #if defined(LDAP_SLAPI)
462         int             i;
463         int             rc = 0;
464
465         if ( val ) {
466                 *val = NULL;
467         }
468         
469         if ( iscritical ) {
470                 *iscritical = 0;
471         }
472         
473         for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
474                 if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
475                         continue;
476                 }
477
478                 rc = 1;
479                 if ( controls[i]->ldctl_value.bv_len != 0 ) {
480                         /*
481                          * FIXME: according to 6.1 specification,
482                          *    "The val output parameter is set
483                          *    to point into the controls array.
484                          *    A copy of the control value is
485                          *    not made."
486                          */
487 #if 0
488                         struct berval   *pTmpBval;
489
490                         pTmpBval = (struct berval *)slapi_ch_malloc( sizeof(struct berval));
491                         if ( pTmpBval == NULL ) {
492                                 rc = 0;
493                         } else {
494                                 pTmpBval->bv_len = controls[i]->ldctl_value.bv_len;
495                                 pTmpBval->bv_val = controls[i]->ldctl_value.bv_val;
496                                 if ( val ) {
497                                         *val = pTmpBval;
498                                 } else {
499                                         slapi_ch_free( pTmpBval );
500                                         rc = 0;
501                                 }
502                         }
503 #endif /* 0 */
504                         if ( val ) {
505                                 *val = &controls[i]->ldctl_value;
506                         }
507                 }
508
509                 if ( iscritical ) {
510                         *iscritical = controls[i]->ldctl_iscritical;
511                 }
512
513                 break;
514         }
515
516         return rc;
517 #else /* !defined(LDAP_SLAPI) */
518         return 0;
519 #endif /* !defined(LDAP_SLAPI) */
520 }
521
522 void 
523 slapi_register_supported_control(
524         char            *controloid, 
525         unsigned long   controlops )
526 {
527 #if defined(LDAP_SLAPI)
528         /* FIXME -- can not add controls to openLDAP dynamically */
529         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_CONTROLS",
530                         "can not add controls to openLDAP dynamically\n" );
531 #endif /* defined(LDAP_SLAPI) */
532 }
533
534 int 
535 slapi_get_supported_controls(
536         char            ***ctrloidsp, 
537         unsigned long   **ctrlopsp ) 
538 {
539 #if defined(LDAP_SLAPI)
540         int             i, n;
541         int             rc = 1;
542         char            **oids = NULL;
543         unsigned long   *masks = NULL;
544
545         for (n = 0; get_supported_ctrl( n ) != NULL; n++) {
546                 ; /* count them */
547         }
548         
549         if ( n == 0 ) {
550                 /* no controls */
551                 *ctrloidsp = NULL;
552                 *ctrlopsp = NULL;
553                 return LDAP_SUCCESS;
554         }
555
556
557         oids = (char **)slapi_ch_malloc( (n + 1) * sizeof(char *) );
558         if ( oids == NULL ) {
559                 rc = LDAP_NO_MEMORY;
560                 goto error_return;
561         }
562
563         masks = (unsigned long *)slapi_ch_malloc( n * sizeof(int) );
564         if ( masks == NULL ) {
565                 rc = LDAP_NO_MEMORY;
566                 goto error_return;
567         }
568
569         for ( i = 0; i < n; i++ ) {
570                 /*
571                  * FIXME: Netscape's specification says nothing about
572                  * memory; should we copy the OIDs or return pointers
573                  * to internal values? In OpenLDAP the latter is safe
574                  * since we do not allow to register coltrols runtime
575                  */
576                 oids[ i ] = ch_strdup( get_supported_ctrl( i ) );
577                 if ( oids[ i ] == NULL ) {
578                         rc = LDAP_NO_MEMORY;
579                         goto error_return;
580                 }
581                 masks[ i ] = (unsigned long)get_supported_ctrl_mask( i );
582         }
583
584         *ctrloidsp = oids;
585         *ctrlopsp = masks;
586         return LDAP_SUCCESS;
587
588 error_return:
589         if ( rc != LDAP_SUCCESS ) {
590                 for ( i = 0; oids != NULL && oids[ i ] != NULL; i++ ) {
591                         ch_free( oids[ i ] );
592                 }
593                 ch_free( oids );
594                 ch_free( masks );
595         }
596
597         return rc;
598 #else /* !defined(LDAP_SLAPI) */
599         return 1;
600 #endif /* !defined(LDAP_SLAPI) */
601 }
602
603 void 
604 slapi_register_supported_saslmechanism( char *mechanism )
605 {
606 #if defined(LDAP_SLAPI)
607         /* FIXME -- can not add saslmechanism to openLDAP dynamically */
608         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
609                         "can not add saslmechanism to openLDAP dynamically\n" );
610 #endif /* defined(LDAP_SLAPI) */
611 }
612
613 char **
614 slapi_get_supported_saslmechanisms( void )
615 {
616 #if defined(LDAP_SLAPI)
617         /* FIXME -- can not get the saslmechanism wihtout a connection. */
618         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
619                         "can not get the saslmechanism "
620                         "wihtout a connection\n" );
621         return NULL;
622 #else /* defined(LDAP_SLAPI) */
623         return NULL;
624 #endif /* defined(LDAP_SLAPI) */
625 }
626
627 char **
628 slapi_get_supported_extended_ops( void )
629 {
630 #if defined(LDAP_SLAPI)
631         int             i, j, k;
632         char            **ppExtOpOID = NULL;
633         int             numExtOps = 0;
634
635         for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
636                 ;
637         }
638         
639         for ( j = 0; ns_get_supported_extop( j ) != NULL; j++ ) {
640                 ;
641         }
642
643         numExtOps = i + j;
644         if ( numExtOps == 0 ) {
645                 return NULL;
646         }
647
648         ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
649         for ( k = 0; k < i; k++ ) {
650                 struct berval   *bv;
651
652                 bv = get_supported_extop( k );
653                 assert( bv != NULL );
654
655                 ppExtOpOID[ k ] = bv->bv_val;
656         }
657         
658         for ( ; k < j; k++ ) {
659                 struct berval   *bv;
660
661                 bv = ns_get_supported_extop( k );
662                 assert( bv != NULL );
663
664                 ppExtOpOID[ i + k ] = bv->bv_val;
665         }
666         ppExtOpOID[ i + k ] = NULL;
667
668         return ppExtOpOID;
669 #else /* !defined(LDAP_SLAPI) */
670         return NULL;
671 #endif /* !defined(LDAP_SLAPI) */
672 }
673
674 void 
675 slapi_send_ldap_result(
676         Slapi_PBlock    *pb, 
677         int             err, 
678         char            *matched, 
679         char            *text, 
680         int             nentries, 
681         struct berval   **urls ) 
682 {
683 #if defined(LDAP_SLAPI)
684         Connection      *conn;
685         Operation       *op;
686         struct berval   *s;
687         char            *extOID = NULL;
688         struct berval   *extValue = NULL;
689         int             rc;
690
691         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
692         slapi_pblock_get( pb, SLAPI_OPERATION, &op );
693         if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
694                 slapi_pblock_get( pb, SLAPI_BIND_RET_SASLCREDS, &s );
695                 rc = LDAP_SASL_BIND_IN_PROGRESS;
696                 send_ldap_sasl( conn, op, rc, NULL, NULL, NULL, NULL, s );
697                 return;
698         }
699
700         slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID, &extOID );
701         if ( extOID != NULL ) {
702                 slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE, &extValue );
703                 slapi_send_ldap_extended_response( conn, op, err, extOID,
704                                 extValue );
705                 return;
706         }
707
708         send_ldap_result( conn, op, err, matched, text, NULL, NULL );
709 #endif /* defined(LDAP_SLAPI) */
710 }
711
712 int 
713 slapi_send_ldap_search_entry(
714         Slapi_PBlock    *pb, 
715         Slapi_Entry     *e, 
716         LDAPControl     **ectrls, 
717         char            **attrs, 
718         int             attrsonly )
719 {
720 #if defined(LDAP_SLAPI)
721         Backend         *be;
722         Connection      *pConn;
723         Operation       *pOp;
724         int             rc;
725
726         int             i;
727         AttributeName   *an = NULL;
728         const char      *text;
729
730         for ( i = 0; attrs[ i ] != NULL; i++ ) {
731                 ; /* empty */
732         }
733
734         if ( i > 0 ) {
735                 an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
736                 for ( i = 0; attrs[i] != NULL; i++ ) {
737                         an[i].an_name.bv_val = ch_strdup( attrs[i] );
738                         an[i].an_name.bv_len = strlen( attrs[i] );
739                         an[i].an_desc = NULL;
740                         if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
741                                 return -1;
742                 }
743         }
744
745         if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
746                         ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
747                         ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
748                 rc = LDAP_OTHER;
749         } else {
750                 rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
751         }
752
753         return rc;
754
755 #else /* !defined(LDAP_SLAPI) */
756         return -1;
757 #endif /* !defined(LDAP_SLAPI) */
758 }
759
760
761 Slapi_Filter *
762 slapi_str2filter( char *str ) 
763 {
764 #if defined(LDAP_SLAPI)
765         return str2filter( str );
766 #else /* !defined(LDAP_SLAPI) */
767         return NULL;
768 #endif /* !defined(LDAP_SLAPI) */
769 }
770
771 void 
772 slapi_filter_free(
773         Slapi_Filter    *f, 
774         int             recurse ) 
775 {
776 #if defined(LDAP_SLAPI)
777         filter_free( f );
778 #endif /* defined(LDAP_SLAPI) */
779 }
780
781 int 
782 slapi_filter_get_choice( Slapi_Filter *f )
783 {
784 #if defined(LDAP_SLAPI)
785         int             rc;
786
787         if ( f != NULL ) {
788                 rc = f->f_choice;
789         } else {
790                 rc = 0;
791         }
792
793         return rc;
794 #else /* !defined(LDAP_SLAPI) */
795         return -1;              /* invalid filter type */
796 #endif /* !defined(LDAP_SLAPI) */
797 }
798
799 int 
800 slapi_filter_get_ava(
801         Slapi_Filter    *f, 
802         char            **type, 
803         struct berval   **bval )
804 {
805 #if defined(LDAP_SLAPI)
806         int             ftype;
807         int             rc = LDAP_SUCCESS;
808
809         assert( type != NULL );
810         assert( bval != NULL );
811
812         *type = NULL;
813         *bval = NULL;
814
815         ftype = f->f_choice;
816         if ( ftype == LDAP_FILTER_EQUALITY 
817                         || ftype ==  LDAP_FILTER_GE 
818                         || ftype == LDAP_FILTER_LE 
819                         || ftype == LDAP_FILTER_APPROX ) {
820                 *type = slapi_ch_strdup( f->f_un.f_un_ava->aa_desc->ad_cname.bv_val );
821                 if ( *type == NULL ) {
822                         rc = LDAP_NO_MEMORY;
823                         goto done;
824                 }
825
826                 *bval = (struct berval *)slapi_ch_malloc( sizeof(struct berval) );
827                 if ( *bval == NULL ) {
828                         rc = LDAP_NO_MEMORY;
829                         goto done;
830                 }
831
832                 (*bval)->bv_len = f->f_un.f_un_ava->aa_value.bv_len;
833                 (*bval)->bv_val = slapi_ch_strdup( f->f_un.f_un_ava->aa_value.bv_val );
834                 if ( (*bval)->bv_val == NULL ) {
835                         rc = LDAP_NO_MEMORY;
836                         goto done;
837                 }
838         } else { /* filter type not supported */
839                 rc = -1;
840         }
841
842 done:
843         if ( rc != LDAP_SUCCESS ) {
844                 if ( *bval ) {
845                         ch_free( *bval );
846                         *bval = NULL;
847                 }
848
849                 if ( *type ) {
850                         ch_free( *type );
851                         *type = NULL;
852                 }
853         }
854
855         return rc;
856 #else /* !defined(LDAP_SLAPI) */
857         return -1;
858 #endif /* !defined(LDAP_SLAPI) */
859 }
860
861 Slapi_Filter *
862 slapi_filter_list_first( Slapi_Filter *f )
863 {
864 #if defined(LDAP_SLAPI)
865         int             ftype;
866
867         if ( f == NULL ) {
868                 return NULL;
869         }
870
871         ftype = f->f_choice;
872         if ( ftype == LDAP_FILTER_AND
873                         || ftype == LDAP_FILTER_OR
874                         || ftype == LDAP_FILTER_NOT ) {
875                 return (Slapi_Filter *)f->f_and;
876         } else {
877                 return NULL;
878         }
879 #else /* !defined(LDAP_SLAPI) */
880         return NULL;
881 #endif /* !defined(LDAP_SLAPI) */
882 }
883
884 Slapi_Filter *
885 slapi_filter_list_next(
886         Slapi_Filter    *f, 
887         Slapi_Filter    *fprev )
888 {
889 #if defined(LDAP_SLAPI)
890         int             ftype;
891
892         if ( f == NULL ) {
893                 return NULL;
894         }
895
896         ftype = f->f_choice;
897         if ( ftype == LDAP_FILTER_AND
898                         || ftype == LDAP_FILTER_OR
899                         || ftype == LDAP_FILTER_NOT ) {
900                 if ( f->f_and == fprev ) {
901                         return f->f_and->f_next;
902                 }
903         }
904
905         return NULL;
906 #else /* !defined(LDAP_SLAPI) */
907         return NULL;
908 #endif /* !defined(LDAP_SLAPI) */
909 }
910
911 int 
912 slapi_send_ldap_extended_response(
913         Connection      *conn, 
914         Operation       *op,
915         int             errornum, 
916         char            *respName,
917         struct berval   *response )
918 {
919 #if defined(LDAP_SLAPI)
920         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
921                         respName,response, NULL );
922         return LDAP_SUCCESS;
923 #else /* !defined(LDAP_SLAPI) */
924         return -1;
925 #endif /* !defined(LDAP_SLAPI) */
926 }
927
928 int 
929 slapi_pw_find(
930         struct berval   **vals, 
931         struct berval   *v ) 
932 {
933 #if defined(LDAP_SLAPI)
934         /*
935          * FIXME: what's the point?
936          */
937         return 1;
938 #else /* !defined(LDAP_SLAPI) */
939         return 1;
940 #endif /* !defined(LDAP_SLAPI) */
941 }
942              
943 char *
944 slapi_get_hostname( void ) 
945 {
946 #if defined(LDAP_SLAPI)
947         char            *hn = NULL;
948
949         /*
950          * FIXME: I'd prefer a different check ...
951          */
952 #if defined _SPARC 
953         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
954         if ( hn == NULL) {
955                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
956                                 "can't malloc memory for hostname\n" );
957                 hn = NULL;
958                 
959         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
960                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
961                                 "can't get hostname\n" );
962                 slapi_ch_free( hn );
963                 hn = NULL;
964         }
965 #else /* !_SPARC */
966         static int      been_here = 0;   
967         static char     *static_hn = NULL;
968
969         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
970         if ( !been_here ) {
971                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
972                 if ( static_hn == NULL) {
973                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
974                                         "can't malloc memory for hostname\n" );
975                         static_hn = NULL;
976                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
977
978                         return hn;
979                         
980                 } else { 
981                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
982                                 slapi_log_error( SLAPI_LOG_FATAL,
983                                                 "SLAPI_SYSINFO",
984                                                 "can't get hostname\n" );
985                                 slapi_ch_free( static_hn );
986                                 static_hn = NULL;
987                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
988
989                                 return hn;
990
991                         } else {
992                                 been_here = 1;
993                         }
994                 }
995         }
996         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
997         
998         hn = ch_strdup( static_hn );
999 #endif /* !_SPARC */
1000
1001         return hn;
1002 #else /* !defined(LDAP_SLAPI) */
1003         return NULL;
1004 #endif /* !defined(LDAP_SLAPI) */
1005 }
1006
1007 /*
1008  * FIXME: this should go in an appropriate header ...
1009  */
1010 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1011
1012 int 
1013 slapi_log_error(
1014         int             severity, 
1015         char            *subsystem, 
1016         char            *fmt, 
1017         ... ) 
1018 {
1019 #if defined(LDAP_SLAPI)
1020         int             rc = LDAP_SUCCESS;
1021         va_list         arglist;
1022
1023         va_start( arglist, fmt );
1024         rc = vLogError( severity, subsystem, fmt, arglist );
1025         va_end( arglist );
1026
1027         return rc;
1028 #else /* !defined(LDAP_SLAPI) */
1029         return -1;
1030 #endif /* !defined(LDAP_SLAPI) */
1031 }
1032
1033
1034 unsigned long
1035 slapi_timer_current_time( void ) 
1036 {
1037 #if defined(LDAP_SLAPI)
1038         static int      first_time = 1;
1039 #if !defined (_WIN32)
1040         struct timeval  now;
1041         unsigned long   ret;
1042
1043         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1044         if (first_time) {
1045                 first_time = 0;
1046                 gettimeofday( &base_time, NULL );
1047         }
1048         gettimeofday( &now, NULL );
1049         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1050                         (now.tv_usec - base_time.tv_usec);
1051         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1052
1053         return ret;
1054
1055         /*
1056          * Ain't it better?
1057         return (slap_get_time() - starttime) * 1000000;
1058          */
1059 #else /* _WIN32 */
1060         LARGE_INTEGER now;
1061
1062         if ( first_time ) {
1063                 first_time = 0;
1064                 performance_counter_present = QueryPerformanceCounter( &base_time );
1065                 QueryPerformanceFrequency( &performance_freq );
1066         }
1067
1068         if ( !performance_counter_present )
1069              return 0;
1070
1071         QueryPerformanceCounter( &now );
1072         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1073 #endif /* _WIN32 */
1074 #else /* !defined(LDAP_SLAPI) */
1075         return 0;
1076 #endif /* !defined(LDAP_SLAPI) */
1077 }
1078
1079 /*
1080  * FIXME ?
1081  */
1082 unsigned long
1083 slapi_timer_get_time( char *label ) 
1084 {
1085 #if defined(LDAP_SLAPI)
1086         unsigned long start = slapi_timer_current_time();
1087         printf("%10ld %10ld usec %s\n", start, 0, label);
1088         return start;
1089 #else /* !defined(LDAP_SLAPI) */
1090         return 0;
1091 #endif /* !defined(LDAP_SLAPI) */
1092 }
1093
1094 /*
1095  * FIXME ?
1096  */
1097 void
1098 slapi_timer_elapsed_time(
1099         char *label,
1100         unsigned long start ) 
1101 {
1102 #if defined(LDAP_SLAPI)
1103         unsigned long stop = slapi_timer_current_time();
1104         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1105 #endif /* defined(LDAP_SLAPI) */
1106 }
1107
1108 void
1109 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1110 {
1111 #if defined(LDAP_SLAPI)
1112         Slapi_Entry     **entries;
1113         int             k = 0, nEnt = 0;
1114
1115         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1116         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1117         if ( nEnt == 0 ) {
1118                 return;
1119         }
1120         
1121         if ( entries == NULL ) {
1122                 return;
1123         }
1124         
1125         for ( k = 0; k < nEnt; k++ ) {
1126                 slapi_entry_free( entries[k] );
1127         }
1128         
1129         slapi_ch_free( entries );
1130 #endif /* defined(LDAP_SLAPI) */
1131 }
1132