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