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