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