]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_utils.c
Confusingly, make SLAPI_OPERATION_AUTHTYPE return a pointer to
[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         send_ldap_result( conn, op, err, matched, text, NULL, NULL );
707 #endif /* defined(LDAP_SLAPI) */
708 }
709
710 int 
711 slapi_send_ldap_search_entry(
712         Slapi_PBlock    *pb, 
713         Slapi_Entry     *e, 
714         LDAPControl     **ectrls, 
715         char            **attrs, 
716         int             attrsonly )
717 {
718 #if defined(LDAP_SLAPI)
719         Backend         *be;
720         Connection      *pConn;
721         Operation       *pOp;
722         int             rc;
723
724         int             i;
725         AttributeName   *an = NULL;
726         const char      *text;
727
728         for ( i = 0; attrs[ i ] != NULL; i++ ) {
729                 ; /* empty */
730         }
731
732         if ( i > 0 ) {
733                 an = (AttributeName *) ch_malloc( i * sizeof(AttributeName) );
734                 for ( i = 0; attrs[i] != NULL; i++ ) {
735                         an[i].an_name.bv_val = ch_strdup( attrs[i] );
736                         an[i].an_name.bv_len = strlen( attrs[i] );
737                         an[i].an_desc = NULL;
738                         if( slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text ) != LDAP_SUCCESS)
739                                 return -1;
740                 }
741         }
742
743         if ( ( rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) ||
744                         ( rc = slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&pConn) != 0 ) ||
745                         ( rc = slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp) != 0 ) ) {
746                 rc = LDAP_OTHER;
747         } else {
748                 rc = send_search_entry( be, pConn, pOp, e, an, attrsonly, NULL );
749         }
750
751         return rc;
752
753 #else /* !defined(LDAP_SLAPI) */
754         return -1;
755 #endif /* !defined(LDAP_SLAPI) */
756 }
757
758
759 Slapi_Filter *
760 slapi_str2filter( char *str ) 
761 {
762 #if defined(LDAP_SLAPI)
763         return str2filter( str );
764 #else /* !defined(LDAP_SLAPI) */
765         return NULL;
766 #endif /* !defined(LDAP_SLAPI) */
767 }
768
769 void 
770 slapi_filter_free(
771         Slapi_Filter    *f, 
772         int             recurse ) 
773 {
774 #if defined(LDAP_SLAPI)
775         filter_free( f );
776 #endif /* defined(LDAP_SLAPI) */
777 }
778
779 int 
780 slapi_filter_get_choice( Slapi_Filter *f )
781 {
782 #if defined(LDAP_SLAPI)
783         int             rc;
784
785         if ( f != NULL ) {
786                 rc = f->f_choice;
787         } else {
788                 rc = 0;
789         }
790
791         return rc;
792 #else /* !defined(LDAP_SLAPI) */
793         return -1;              /* invalid filter type */
794 #endif /* !defined(LDAP_SLAPI) */
795 }
796
797 int 
798 slapi_filter_get_ava(
799         Slapi_Filter    *f, 
800         char            **type, 
801         struct berval   **bval )
802 {
803 #if defined(LDAP_SLAPI)
804         int             ftype;
805         int             rc = LDAP_SUCCESS;
806
807         assert( type != NULL );
808         assert( bval != NULL );
809
810         *type = NULL;
811         *bval = NULL;
812
813         ftype = f->f_choice;
814         if ( ftype == LDAP_FILTER_EQUALITY 
815                         || ftype ==  LDAP_FILTER_GE 
816                         || ftype == LDAP_FILTER_LE 
817                         || ftype == LDAP_FILTER_APPROX ) {
818                 *type = slapi_ch_strdup( f->f_un.f_un_ava->aa_desc->ad_cname.bv_val );
819                 if ( *type == NULL ) {
820                         rc = LDAP_NO_MEMORY;
821                         goto done;
822                 }
823
824                 *bval = (struct berval *)slapi_ch_malloc( sizeof(struct berval) );
825                 if ( *bval == NULL ) {
826                         rc = LDAP_NO_MEMORY;
827                         goto done;
828                 }
829
830                 (*bval)->bv_len = f->f_un.f_un_ava->aa_value.bv_len;
831                 (*bval)->bv_val = slapi_ch_strdup( f->f_un.f_un_ava->aa_value.bv_val );
832                 if ( (*bval)->bv_val == NULL ) {
833                         rc = LDAP_NO_MEMORY;
834                         goto done;
835                 }
836         } else { /* filter type not supported */
837                 rc = -1;
838         }
839
840 done:
841         if ( rc != LDAP_SUCCESS ) {
842                 if ( *bval ) {
843                         ch_free( *bval );
844                         *bval = NULL;
845                 }
846
847                 if ( *type ) {
848                         ch_free( *type );
849                         *type = NULL;
850                 }
851         }
852
853         return rc;
854 #else /* !defined(LDAP_SLAPI) */
855         return -1;
856 #endif /* !defined(LDAP_SLAPI) */
857 }
858
859 Slapi_Filter *
860 slapi_filter_list_first( Slapi_Filter *f )
861 {
862 #if defined(LDAP_SLAPI)
863         int             ftype;
864
865         if ( f == NULL ) {
866                 return NULL;
867         }
868
869         ftype = f->f_choice;
870         if ( ftype == LDAP_FILTER_AND
871                         || ftype == LDAP_FILTER_OR
872                         || ftype == LDAP_FILTER_NOT ) {
873                 return (Slapi_Filter *)f->f_and;
874         } else {
875                 return NULL;
876         }
877 #else /* !defined(LDAP_SLAPI) */
878         return NULL;
879 #endif /* !defined(LDAP_SLAPI) */
880 }
881
882 Slapi_Filter *
883 slapi_filter_list_next(
884         Slapi_Filter    *f, 
885         Slapi_Filter    *fprev )
886 {
887 #if defined(LDAP_SLAPI)
888         int             ftype;
889
890         if ( f == NULL ) {
891                 return NULL;
892         }
893
894         ftype = f->f_choice;
895         if ( ftype == LDAP_FILTER_AND
896                         || ftype == LDAP_FILTER_OR
897                         || ftype == LDAP_FILTER_NOT ) {
898                 if ( f->f_and == fprev ) {
899                         return f->f_and->f_next;
900                 }
901         }
902
903         return NULL;
904 #else /* !defined(LDAP_SLAPI) */
905         return NULL;
906 #endif /* !defined(LDAP_SLAPI) */
907 }
908
909 int 
910 slapi_send_ldap_extended_response(
911         Connection      *conn, 
912         Operation       *op,
913         int             errornum, 
914         char            *respName,
915         struct berval   *response )
916 {
917 #if defined(LDAP_SLAPI)
918         send_ldap_extended( conn,op, errornum, NULL, NULL, NULL,
919                         respName,response, NULL );
920         return LDAP_SUCCESS;
921 #else /* !defined(LDAP_SLAPI) */
922         return -1;
923 #endif /* !defined(LDAP_SLAPI) */
924 }
925
926 int 
927 slapi_pw_find(
928         struct berval   **vals, 
929         struct berval   *v ) 
930 {
931 #if defined(LDAP_SLAPI)
932         /*
933          * FIXME: what's the point?
934          */
935         return 1;
936 #else /* !defined(LDAP_SLAPI) */
937         return 1;
938 #endif /* !defined(LDAP_SLAPI) */
939 }
940              
941 char *
942 slapi_get_hostname( void ) 
943 {
944 #if defined(LDAP_SLAPI)
945         char            *hn = NULL;
946
947         /*
948          * FIXME: I'd prefer a different check ...
949          */
950 #if defined _SPARC 
951         hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
952         if ( hn == NULL) {
953                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
954                                 "can't malloc memory for hostname\n" );
955                 hn = NULL;
956                 
957         } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
958                 slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
959                                 "can't get hostname\n" );
960                 slapi_ch_free( (void **)&hn );
961                 hn = NULL;
962         }
963 #else /* !_SPARC */
964         static int      been_here = 0;   
965         static char     *static_hn = NULL;
966
967         ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
968         if ( !been_here ) {
969                 static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
970                 if ( static_hn == NULL) {
971                         slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
972                                         "can't malloc memory for hostname\n" );
973                         static_hn = NULL;
974                         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
975
976                         return hn;
977                         
978                 } else { 
979                         if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
980                                 slapi_log_error( SLAPI_LOG_FATAL,
981                                                 "SLAPI_SYSINFO",
982                                                 "can't get hostname\n" );
983                                 slapi_ch_free( (void **)&static_hn );
984                                 static_hn = NULL;
985                                 ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
986
987                                 return hn;
988
989                         } else {
990                                 been_here = 1;
991                         }
992                 }
993         }
994         ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
995         
996         hn = ch_strdup( static_hn );
997 #endif /* !_SPARC */
998
999         return hn;
1000 #else /* !defined(LDAP_SLAPI) */
1001         return NULL;
1002 #endif /* !defined(LDAP_SLAPI) */
1003 }
1004
1005 /*
1006  * FIXME: this should go in an appropriate header ...
1007  */
1008 extern int vLogError( int level, char *subsystem, char *fmt, va_list arglist );
1009
1010 int 
1011 slapi_log_error(
1012         int             severity, 
1013         char            *subsystem, 
1014         char            *fmt, 
1015         ... ) 
1016 {
1017 #if defined(LDAP_SLAPI)
1018         int             rc = LDAP_SUCCESS;
1019         va_list         arglist;
1020
1021         va_start( arglist, fmt );
1022         rc = vLogError( severity, subsystem, fmt, arglist );
1023         va_end( arglist );
1024
1025         return rc;
1026 #else /* !defined(LDAP_SLAPI) */
1027         return -1;
1028 #endif /* !defined(LDAP_SLAPI) */
1029 }
1030
1031
1032 unsigned long
1033 slapi_timer_current_time( void ) 
1034 {
1035 #if defined(LDAP_SLAPI)
1036         static int      first_time = 1;
1037 #if !defined (_WIN32)
1038         struct timeval  now;
1039         unsigned long   ret;
1040
1041         ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
1042         if (first_time) {
1043                 first_time = 0;
1044                 gettimeofday( &base_time, NULL );
1045         }
1046         gettimeofday( &now, NULL );
1047         ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
1048                         (now.tv_usec - base_time.tv_usec);
1049         ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
1050
1051         return ret;
1052
1053         /*
1054          * Ain't it better?
1055         return (slap_get_time() - starttime) * 1000000;
1056          */
1057 #else /* _WIN32 */
1058         LARGE_INTEGER now;
1059
1060         if ( first_time ) {
1061                 first_time = 0;
1062                 performance_counter_present = QueryPerformanceCounter( &base_time );
1063                 QueryPerformanceFrequency( &performance_freq );
1064         }
1065
1066         if ( !performance_counter_present )
1067              return 0;
1068
1069         QueryPerformanceCounter( &now );
1070         return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
1071 #endif /* _WIN32 */
1072 #else /* !defined(LDAP_SLAPI) */
1073         return 0;
1074 #endif /* !defined(LDAP_SLAPI) */
1075 }
1076
1077 /*
1078  * FIXME ?
1079  */
1080 unsigned long
1081 slapi_timer_get_time( char *label ) 
1082 {
1083 #if defined(LDAP_SLAPI)
1084         unsigned long start = slapi_timer_current_time();
1085         printf("%10ld %10ld usec %s\n", start, 0, label);
1086         return start;
1087 #else /* !defined(LDAP_SLAPI) */
1088         return 0;
1089 #endif /* !defined(LDAP_SLAPI) */
1090 }
1091
1092 /*
1093  * FIXME ?
1094  */
1095 void
1096 slapi_timer_elapsed_time(
1097         char *label,
1098         unsigned long start ) 
1099 {
1100 #if defined(LDAP_SLAPI)
1101         unsigned long stop = slapi_timer_current_time();
1102         printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
1103 #endif /* defined(LDAP_SLAPI) */
1104 }
1105
1106 void
1107 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
1108 {
1109 #if defined(LDAP_SLAPI)
1110         Slapi_Entry     **entries;
1111         int             k = 0, nEnt = 0;
1112
1113         slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
1114         slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
1115         if ( nEnt == 0 ) {
1116                 return;
1117         }
1118         
1119         if ( entries == NULL ) {
1120                 return;
1121         }
1122         
1123         for ( k = 0; k < nEnt; k++ ) {
1124                 slapi_entry_free( entries[k] );
1125         }
1126         
1127         slapi_ch_free( (void **)&entries );
1128 #endif /* defined(LDAP_SLAPI) */
1129 }
1130
1131 /*
1132  * Internal API to prime a Slapi_PBlock with a Backend.
1133  */
1134 int slapi_x_backend_set_pb( Slapi_PBlock *pb, Backend *be )
1135 {
1136 #if defined(LDAP_SLAPI)
1137         int rc;
1138
1139         rc = slapi_pblock_set( pb, SLAPI_BACKEND, (void *)be );
1140         if ( rc != LDAP_SUCCESS )
1141                 return rc;
1142
1143         rc = slapi_pblock_set( pb, SLAPI_BE_TYPE, (void *)be->bd_info->bi_type );
1144         if ( rc != LDAP_SUCCESS )
1145                 return rc;
1146
1147         return LDAP_SUCCESS;
1148 #else
1149         return -1;
1150 #endif /* defined(LDAP_SLAPI) */
1151 }
1152
1153 #if defined(LDAP_SLAPI)
1154 /*
1155  * If oldStyle is TRUE, then a value suitable for setting to
1156  * the deprecated SLAPI_CONN_AUTHTYPE value is returned 
1157  * (pointer to static storage).
1158  *
1159  * If oldStyle is FALSE, then a value suitable for setting to
1160  * the new SLAPI_CONN_AUTHMETHOD will be returned, which is
1161  * a pointer to allocated memory and will include the SASL
1162  * mechanism (if any).
1163  */
1164 static char *Authorization2AuthType( AuthorizationInformation *authz, int is_tls, int oldStyle )
1165 {
1166         size_t len;
1167         char *authType;
1168
1169         switch ( authz->sai_method ) {
1170         case LDAP_AUTH_SASL:
1171                 if ( oldStyle ) {
1172                         authType = SLAPD_AUTH_SASL;
1173                 } else {
1174                         len = sizeof(SLAPD_AUTH_SASL) + authz->sai_mech.bv_len;
1175                         authType = slapi_ch_malloc( len );
1176                         snprintf( authType, len, "%s%s", SLAPD_AUTH_SASL, authz->sai_mech.bv_val );
1177                 }
1178                 break;
1179         case LDAP_AUTH_SIMPLE:
1180                 authType = oldStyle ? SLAPD_AUTH_SIMPLE : slapi_ch_strdup( SLAPD_AUTH_SIMPLE );
1181                 break;
1182         case LDAP_AUTH_NONE:
1183                 authType = oldStyle ? SLAPD_AUTH_NONE : slapi_ch_strdup( SLAPD_AUTH_NONE );
1184                 break;
1185         default:
1186                 authType = NULL;
1187                 break;
1188         }
1189         if ( is_tls && authType == NULL ) {
1190                 authType = oldStyle ? SLAPD_AUTH_SSL : slapi_ch_strdup( SLAPD_AUTH_SSL );
1191         }
1192
1193         return authType;
1194 }
1195 #endif
1196
1197 /*
1198  * Internal API to prime a Slapi_PBlock with a Connection.
1199  */
1200 int slapi_x_connection_set_pb( Slapi_PBlock *pb, Connection *conn )
1201 {
1202 #if defined(LDAP_SLAPI)
1203         char *connAuthType;
1204         int rc;
1205
1206         rc = slapi_pblock_set( pb, SLAPI_CONNECTION, (void *)conn );
1207         if ( rc != LDAP_SUCCESS )
1208                 return rc;
1209
1210         if ( strncmp( conn->c_peer_name.bv_val, "IP=", 3 ) == 0 ) {
1211                 rc = slapi_pblock_set( pb, SLAPI_CONN_CLIENTIP, (void *)&conn->c_peer_name.bv_val[3] );
1212                 if ( rc != LDAP_SUCCESS )
1213                         return rc;
1214         }
1215
1216         if ( strncmp( conn->c_sock_name.bv_val, "IP=", 3 ) == 0 ) {
1217                 rc = slapi_pblock_set( pb, SLAPI_CONN_SERVERIP, (void *)&conn->c_sock_name.bv_val[3] );
1218                 if ( rc != LDAP_SUCCESS )
1219                         return rc;
1220         }
1221
1222         rc = slapi_pblock_set( pb, SLAPI_CONN_ID, (void *)conn->c_connid );
1223         if ( rc != LDAP_SUCCESS )
1224                 return rc;
1225
1226         /* Returns pointer to static string */
1227         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 1 );
1228         if ( connAuthType != NULL ) {
1229                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
1230                 if ( rc != LDAP_SUCCESS )
1231                         return rc;
1232         }
1233
1234         /* Returns pointer to allocated string */
1235         connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 0 );
1236         if ( connAuthType != NULL ) {
1237                 rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType);
1238                 if ( rc != LDAP_SUCCESS )
1239                         return rc;
1240         }
1241
1242         if ( conn->c_authz.sai_dn.bv_val != NULL ) {
1243                 char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
1244                 rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
1245                 if ( rc != LDAP_SUCCESS )
1246                         return rc;
1247         }
1248 #else
1249         return -1;
1250 #endif /* defined(LDAP_SLAPI) */
1251 }
1252
1253 /*
1254  * Internal API to prime a Slapi_PBlock with an Operation.
1255  */
1256 int slapi_x_operation_set_pb( Slapi_PBlock *pb, Operation *op )
1257 {
1258 #if defined(LDAP_SLAPI)
1259         int isRoot = 0;
1260         int isUpdateDn = 0;
1261         int rc;
1262         Backend *be;
1263         char *opAuthType;
1264
1265         if ( slapi_pblock_get(pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
1266                 be = NULL;
1267         }
1268         if (be != NULL) {
1269                 isRoot = be_isroot( be, &op->o_ndn );
1270                 isUpdateDn = be_isupdate( be, &op->o_ndn );
1271         }
1272                 
1273         rc = slapi_pblock_set( pb, SLAPI_OPERATION, (void *)op );
1274         if ( rc != LDAP_SUCCESS )
1275                 return rc;
1276
1277         rc = slapi_pblock_set( pb, SLAPI_OPINITIATED_TIME, (void *)op->o_time );
1278         if ( rc != LDAP_SUCCESS )
1279                 return rc;
1280
1281         rc = slapi_pblock_set( pb, SLAPI_OPERATION_ID, (void *)op->o_opid );
1282         if ( rc != LDAP_SUCCESS )
1283                 return rc;
1284
1285         rc = slapi_pblock_set( pb, SLAPI_OPERATION_TYPE, (void *)op->o_tag );
1286         if ( rc != LDAP_SUCCESS )
1287                 return rc;
1288
1289         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, (void *)isRoot );
1290         if ( rc != LDAP_SUCCESS )
1291                 return rc;
1292
1293         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_ISUPDATEDN, (void *)isUpdateDn );
1294         if ( rc != LDAP_SUCCESS )
1295                 return rc;
1296
1297         rc = slapi_pblock_set( pb, SLAPI_REQCONTROLS, (void *)op->o_ctrls );
1298         if ( rc != LDAP_SUCCESS)
1299                 return rc;
1300
1301         rc = slapi_pblock_set( pb, SLAPI_REQUESTOR_DN, (void *)op->o_ndn.bv_val );
1302         if ( rc != LDAP_SUCCESS )
1303                 return rc;
1304
1305         rc = slapi_pblock_get( pb, SLAPI_CONN_AUTHMETHOD, (void *)&opAuthType );
1306         if ( rc == LDAP_SUCCESS && opAuthType != NULL ) {
1307                 /* Not quite sure what the point of this is. */
1308                 rc = slapi_pblock_set( pb, SLAPI_OPERATION_AUTHTYPE, (void *)opAuthType );
1309                 if ( rc != LDAP_SUCCESS )
1310                         return rc;
1311         }
1312
1313         return LDAP_SUCCESS;
1314 #else
1315         return -1;
1316 #endif
1317 }
1318
1319 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
1320 {
1321 #if defined( LDAP_SLAPI )
1322         Connection *conn;
1323
1324         slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
1325         *isSSL = conn->c_is_tls;
1326
1327         return LDAP_SUCCESS;
1328 #else
1329         return -1;
1330 #endif /* defined(LDAP_SLAPI) */
1331 }