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