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 */ 46static struct timeval base_time; 47ldap_pvt_thread_mutex_t slapi_hn_mutex; 48ldap_pvt_thread_mutex_t slapi_time_mutex; 49 50struct slapi_mutex { 51 ldap_pvt_thread_mutex_t mutex; 52}; 53 54struct slapi_condvar { 55 ldap_pvt_thread_cond_t cond; 56 ldap_pvt_thread_mutex_t mutex; 57}; 58 59static 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 78int 79bvptr2obj( 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 117Slapi_Entry * 118slapi_str2entry( 119 char *s, 120 int flags ) 121{ 122 return str2entry( s ); 123} 124 125char * 126slapi_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 142char * 143slapi_entry_get_dn( Slapi_Entry *e ) 144{ 145 return e->e_name.bv_val; 146} 147 148int 149slapi_x_entry_get_id( Slapi_Entry *e ) 150{ 151 return e->e_id; 152} 153 154static int 155slapi_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 164static int 165slapi_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 175void 176slapi_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 189Slapi_Entry * 190slapi_entry_dup( Slapi_Entry *e ) 191{ 192 return entry_dup( e ); 193} 194 195int 196slapi_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 214Slapi_Entry * 215slapi_entry_alloc( void ) 216{ 217 return (Slapi_Entry *)entry_alloc(); 218} 219 220void 221slapi_entry_free( Slapi_Entry *e ) 222{ 223 if ( e != NULL ) 224 entry_free( e ); 225} 226 227int 228slapi_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 254int 255slapi_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 277char * 278slapi_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 307int 308slapi_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 328long 329slapi_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 349unsigned int 350slapi_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 370unsigned long 371slapi_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 391int 392slapi_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 416void 417slapi_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 437void 438slapi_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 446void 447slapi_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 455void 456slapi_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 464void 465slapi_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 473int 474slapi_is_rootdse( const char *dn ) 475{ 476 return ( dn == NULL || dn[0] == '\0' ); 477} 478 479int 480slapi_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 */ 516size_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 */ 542int 543slapi_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 583int 584slapi_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 589int 590slapi_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 604int 605slapi_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 646int 647slapi_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 652int 653slapi_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 658int 659slapi_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 678int 679slapi_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 689int 690slapi_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 703int 704slapi_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 709int 710slapi_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 721int 722slapi_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 737int 738slapi_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 */ 770int 771slapi_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 797char * 798slapi_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 815char * 816slapi_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 833int 834slapi_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 870int 871slapi_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 */ 920char * 921slapi_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 955int 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 */ 981char *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 1020char * 1021slapi_dn_ignore_case( char *dn ) 1022{ 1023 return slapi_dn_normalize_case( dn ); 1024} 1025 1026char * 1027slapi_ch_malloc( unsigned long size ) 1028{ 1029 return ch_malloc( size ); 1030} 1031 1032void 1033slapi_ch_free( void **ptr ) 1034{ 1035 if ( ptr == NULL || *ptr == NULL ) 1036 return; 1037 ch_free( *ptr ); 1038 *ptr = NULL; 1039} 1040 1041void 1042slapi_ch_free_string( char **ptr ) 1043{ 1044 slapi_ch_free( (void **)ptr ); 1045} 1046 1047void 1048slapi_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 1060struct berval * 1061slapi_ch_bvdup(const struct berval *v) 1062{ 1063 return ber_dupbv(NULL, (struct berval *)v); 1064} 1065 1066struct berval ** 1067slapi_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 1089char * 1090slapi_ch_calloc( 1091 unsigned long nelem, 1092 unsigned long size ) 1093{ 1094 return ch_calloc( nelem, size ); 1095} 1096 1097char * 1098slapi_ch_realloc( 1099 char *block, 1100 unsigned long size ) 1101{ 1102 return ch_realloc( block, size ); 1103} 1104 1105char * 1106slapi_ch_strdup( const char *s ) 1107{ 1108 return ch_strdup( s ); 1109} 1110 1111size_t 1112slapi_ch_stlen( const char *s ) 1113{ 1114 return strlen( s ); 1115} 1116 1117int 1118slapi_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 1157static void 1158slapControlMask2SlapiControlOp(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 1191static void 1192slapiControlOp2SlapControlMask(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 1227static int 1228slapi_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 1238void 1239slapi_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 1250int 1251slapi_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 1270LDAPControl * 1271slapi_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 1283void 1284slapi_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 1291char ** 1292slapi_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 1301char ** 1302slapi_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 1344void 1345slapi_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 1381int 1382slapi_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 1435int 1436slapi_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 1479Slapi_Filter * 1480slapi_str2filter( char *str ) 1481{ 1482 return str2filter( str ); 1483} 1484 1485void 1486slapi_filter_free( 1487 Slapi_Filter *f, 1488 int recurse ) 1489{ 1490 filter_free( f ); 1491} 1492 1493Slapi_Filter * 1494slapi_filter_dup( Slapi_Filter *filter ) 1495{ 1496 return filter_dup( filter, NULL ); 1497} 1498 1499int 1500slapi_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 1513int 1514slapi_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 1546Slapi_Filter * 1547slapi_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 1565Slapi_Filter * 1566slapi_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 1587int 1588slapi_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 1619int 1620slapi_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 1658int 1659slapi_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 1692Slapi_Filter * 1693slapi_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 1711int 1712slapi_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 1740int 1741slapi_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 1783int 1784slapi_filter_test_simple( Slapi_Entry *e, Slapi_Filter *f) 1785{ 1786 return slapi_filter_test( NULL, e, f, 0 ); 1787} 1788 1789int 1790slapi_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 1833int 1834slapi_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 */ 1861int 1862slapi_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. */ 1881void 1882slapi_free_client_ip(char **clientIP) 1883{ 1884 slapi_ch_free((void **) clientIP); 1885} 1886 1887#define MAX_HOSTNAME 512 1888 1889char * 1890slapi_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 */ 1933extern int slapi_int_log_error( int level, char *subsystem, char *fmt, va_list arglist ); 1934 1935int 1936slapi_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 1953unsigned long 1954slapi_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 */ 1997unsigned long 1998slapi_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 */ 2008void 2009slapi_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 2017void 2018slapi_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 2037int 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 2058int 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 2083int 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 2092Slapi_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 2101Slapi_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 2119void slapi_attr_free( Slapi_Attr **a ) 2120{ 2121 attr_free( *a ); 2122 *a = NULL; 2123} 2124 2125Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr ) 2126{ 2127 return attr_dup( (Slapi_Attr *)attr ); 2128} 2129 2130int 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 2161int slapi_attr_type2plugin( const char *type, void **pi ) 2162{ 2163 *pi = NULL; 2164 2165 return LDAP_OTHER; 2166} 2167 2168int 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 2179int 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 2189int 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 2206int 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 2218int 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 2255int 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 2260int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v ) 2261{ 2262 return slapi_valueset_first_value( &a->a_vals, v ); 2263} 2264 2265int 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 2270int 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 2277int 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 2284int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals ) 2285{ 2286 return slapi_attr_get_values( a, vals ); 2287} 2288 2289char *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 2301Slapi_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 2310Slapi_Value *slapi_value_new_berval(const struct berval *bval) 2311{ 2312 return ber_dupbv( NULL, (struct berval *)bval ); 2313} 2314 2315Slapi_Value *slapi_value_new_value(const Slapi_Value *v) 2316{ 2317 return slapi_value_new_berval( v ); 2318} 2319 2320Slapi_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 2330Slapi_Value *slapi_value_init(Slapi_Value *val) 2331{ 2332 val->bv_val = NULL; 2333 val->bv_len = 0; 2334 2335 return val; 2336} 2337 2338Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval) 2339{ 2340 return ber_dupbv( v, bval ); 2341} 2342 2343Slapi_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 2351Slapi_Value *slapi_value_dup(const Slapi_Value *v) 2352{ 2353 return slapi_value_new_value( v ); 2354} 2355 2356void 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 2368const struct berval *slapi_value_get_berval( const Slapi_Value *value ) 2369{ 2370 return value; 2371} 2372 2373Slapi_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 2386Slapi_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 2394Slapi_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 2409int 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 2418int 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 2427const 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 2436int 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 2445unsigned 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 2454long 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 2463unsigned 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 2472size_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 2480int 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. */ 2486Slapi_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 2496void 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 2508void 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 2517void 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 2531void 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 2539int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v ) 2540{ 2541 return slapi_valueset_next_value( vs, 0, v ); 2542} 2543 2544int 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 2564int 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 2584void 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 2593int 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 2645int 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 */ 2671LDAPMod **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 */ 2723Modifications *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 */ 2816int 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 2844done: 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 */ 2858int 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 2886done: 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 */ 2900int 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 2928int 2929compute_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 */ 2941int 2942slapi_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 2955Slapi_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 2968void 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 2976void slapi_lock_mutex( Slapi_Mutex *mutex ) 2977{ 2978 ldap_pvt_thread_mutex_lock( &mutex->mutex ); 2979} 2980 2981int slapi_unlock_mutex( Slapi_Mutex *mutex ) 2982{ 2983 return ldap_pvt_thread_mutex_unlock( &mutex->mutex ); 2984} 2985 2986Slapi_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 3005void 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 3013int 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 3022int 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 3035int 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 */ 3103int 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 3134char *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 3151int 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 3173int 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 3202int 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 3236const 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 3252void 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 3263LDAP *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 3298void slapi_ldap_unbind( LDAP *ld ) 3299{ 3300 ldap_unbind_ext_s( ld, NULL, NULL ); 3301} 3302 3303int 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 3313int 3314slapi_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 3327int 3328slapi_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 3336char * 3337slapi_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 3379unsigned long 3380slapi_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 3422void 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 3433int 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 3441const 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 3449Slapi_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 3461void 3462slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag) 3463{ 3464} 3465 3466void 3467slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag) 3468{ 3469} 3470 3471int 3472slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag) 3473{ 3474} 3475#endif 3476 3477#endif /* LDAP_SLAPI */ 3478 3479