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