1 /* $NetBSD: at.c,v 1.1.1.5 2014/05/28 09:58:45 tron Exp $ */ 2 3 /* at.c - routines for dealing with attribute types */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2014 The OpenLDAP Foundation. 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 19 #include "portable.h" 20 21 #include <stdio.h> 22 23 #include <ac/ctype.h> 24 #include <ac/errno.h> 25 #include <ac/socket.h> 26 #include <ac/string.h> 27 #include <ac/time.h> 28 29 #include "slap.h" 30 31 32 const char * 33 at_syntax( 34 AttributeType *at ) 35 { 36 for ( ; at != NULL; at = at->sat_sup ) { 37 if ( at->sat_syntax_oid ) { 38 return at->sat_syntax_oid; 39 } 40 } 41 42 assert( 0 ); 43 44 return NULL; 45 } 46 47 int 48 is_at_syntax( 49 AttributeType *at, 50 const char *oid ) 51 { 52 const char *syn_oid = at_syntax( at ); 53 54 if ( syn_oid ) { 55 return strcmp( syn_oid, oid ) == 0; 56 } 57 58 return 0; 59 } 60 61 int is_at_subtype( 62 AttributeType *sub, 63 AttributeType *sup ) 64 { 65 for( ; sub != NULL; sub = sub->sat_sup ) { 66 if( sub == sup ) return 1; 67 } 68 69 return 0; 70 } 71 72 struct aindexrec { 73 struct berval air_name; 74 AttributeType *air_at; 75 }; 76 77 static Avlnode *attr_index = NULL; 78 static Avlnode *attr_cache = NULL; 79 static LDAP_STAILQ_HEAD(ATList, AttributeType) attr_list 80 = LDAP_STAILQ_HEAD_INITIALIZER(attr_list); 81 82 /* Last hardcoded attribute registered */ 83 AttributeType *at_sys_tail; 84 85 int at_oc_cache; 86 87 static int 88 attr_index_cmp( 89 const void *v_air1, 90 const void *v_air2 ) 91 { 92 const struct aindexrec *air1 = v_air1; 93 const struct aindexrec *air2 = v_air2; 94 int i = air1->air_name.bv_len - air2->air_name.bv_len; 95 if (i) return i; 96 return (strcasecmp( air1->air_name.bv_val, air2->air_name.bv_val )); 97 } 98 99 static int 100 attr_index_name_cmp( 101 const void *v_type, 102 const void *v_air ) 103 { 104 const struct berval *type = v_type; 105 const struct aindexrec *air = v_air; 106 int i = type->bv_len - air->air_name.bv_len; 107 if (i) return i; 108 return (strncasecmp( type->bv_val, air->air_name.bv_val, type->bv_len )); 109 } 110 111 AttributeType * 112 at_find( const char *name ) 113 { 114 struct berval bv; 115 116 bv.bv_val = (char *)name; 117 bv.bv_len = strlen( name ); 118 119 return at_bvfind( &bv ); 120 } 121 122 AttributeType * 123 at_bvfind( struct berval *name ) 124 { 125 struct aindexrec *air; 126 127 if ( attr_cache ) { 128 air = avl_find( attr_cache, name, attr_index_name_cmp ); 129 if ( air ) return air->air_at; 130 } 131 132 air = avl_find( attr_index, name, attr_index_name_cmp ); 133 134 if ( air ) { 135 if ( air->air_at->sat_flags & SLAP_AT_DELETED ) { 136 air = NULL; 137 } else if (( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) { 138 avl_insert( &attr_cache, (caddr_t) air, 139 attr_index_cmp, avl_dup_error ); 140 } 141 } 142 143 return air != NULL ? air->air_at : NULL; 144 } 145 146 int 147 at_append_to_list( 148 AttributeType *sat, 149 AttributeType ***listp ) 150 { 151 AttributeType **list; 152 AttributeType **list1; 153 int size; 154 155 list = *listp; 156 if ( !list ) { 157 size = 2; 158 list = ch_calloc(size, sizeof(AttributeType *)); 159 if ( !list ) { 160 return -1; 161 } 162 } else { 163 size = 0; 164 list1 = *listp; 165 while ( *list1 ) { 166 size++; 167 list1++; 168 } 169 size += 2; 170 list1 = ch_realloc(list, size*sizeof(AttributeType *)); 171 if ( !list1 ) { 172 return -1; 173 } 174 list = list1; 175 } 176 list[size-2] = sat; 177 list[size-1] = NULL; 178 *listp = list; 179 return 0; 180 } 181 182 int 183 at_delete_from_list( 184 int pos, 185 AttributeType ***listp ) 186 { 187 AttributeType **list; 188 AttributeType **list1; 189 int i; 190 int j; 191 192 if ( pos < 0 ) { 193 return -2; 194 } 195 list = *listp; 196 for ( i=0; list[i]; i++ ) 197 ; 198 if ( pos >= i ) { 199 return -2; 200 } 201 for ( i=pos, j=pos+1; list[j]; i++, j++ ) { 202 list[i] = list[j]; 203 } 204 list[i] = NULL; 205 /* Tell the runtime this can be shrinked */ 206 list1 = ch_realloc(list, (i+1)*sizeof(AttributeType **)); 207 if ( !list1 ) { 208 return -1; 209 } 210 *listp = list1; 211 return 0; 212 } 213 214 int 215 at_find_in_list( 216 AttributeType *sat, 217 AttributeType **list ) 218 { 219 int i; 220 221 if ( !list ) { 222 return -1; 223 } 224 for ( i=0; list[i]; i++ ) { 225 if ( sat == list[i] ) { 226 return i; 227 } 228 } 229 return -1; 230 } 231 232 static void 233 at_delete_names( AttributeType *at ) 234 { 235 char **names = at->sat_names; 236 237 if (!names) return; 238 239 while (*names) { 240 struct aindexrec tmpair, *air; 241 242 ber_str2bv( *names, 0, 0, &tmpair.air_name ); 243 tmpair.air_at = at; 244 air = (struct aindexrec *)avl_delete( &attr_index, 245 (caddr_t)&tmpair, attr_index_cmp ); 246 assert( air != NULL ); 247 ldap_memfree( air ); 248 names++; 249 } 250 } 251 252 /* Mark the attribute as deleted, remove from list, and remove all its 253 * names from the AVL tree. Leave the OID in the tree. 254 */ 255 void 256 at_delete( AttributeType *at ) 257 { 258 at->sat_flags |= SLAP_AT_DELETED; 259 260 LDAP_STAILQ_REMOVE(&attr_list, at, AttributeType, sat_next); 261 262 at_delete_names( at ); 263 } 264 265 static void 266 at_clean( AttributeType *a ) 267 { 268 if ( a->sat_equality ) { 269 MatchingRule *mr; 270 271 mr = mr_find( a->sat_equality->smr_oid ); 272 assert( mr != NULL ); 273 if ( mr != a->sat_equality ) { 274 ch_free( a->sat_equality ); 275 a->sat_equality = NULL; 276 } 277 } 278 279 assert( a->sat_syntax != NULL ); 280 if ( a->sat_syntax != NULL ) { 281 Syntax *syn; 282 283 syn = syn_find( a->sat_syntax->ssyn_oid ); 284 assert( syn != NULL ); 285 if ( syn != a->sat_syntax ) { 286 ch_free( a->sat_syntax ); 287 a->sat_syntax = NULL; 288 } 289 } 290 291 if ( a->sat_oidmacro ) { 292 ldap_memfree( a->sat_oidmacro ); 293 a->sat_oidmacro = NULL; 294 } 295 if ( a->sat_soidmacro ) { 296 ldap_memfree( a->sat_soidmacro ); 297 a->sat_soidmacro = NULL; 298 } 299 if ( a->sat_subtypes ) { 300 ldap_memfree( a->sat_subtypes ); 301 a->sat_subtypes = NULL; 302 } 303 } 304 305 static void 306 at_destroy_one( void *v ) 307 { 308 struct aindexrec *air = v; 309 AttributeType *a = air->air_at; 310 311 at_clean( a ); 312 ad_destroy(a->sat_ad); 313 ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex); 314 ldap_attributetype_free((LDAPAttributeType *)a); 315 ldap_memfree(air); 316 } 317 318 void 319 at_destroy( void ) 320 { 321 AttributeType *a; 322 323 while( !LDAP_STAILQ_EMPTY(&attr_list) ) { 324 a = LDAP_STAILQ_FIRST(&attr_list); 325 LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next); 326 327 at_delete_names( a ); 328 } 329 330 avl_free(attr_index, at_destroy_one); 331 332 if ( slap_schema.si_at_undefined ) { 333 ad_destroy(slap_schema.si_at_undefined->sat_ad); 334 } 335 336 if ( slap_schema.si_at_proxied ) { 337 ad_destroy(slap_schema.si_at_proxied->sat_ad); 338 } 339 } 340 341 int 342 at_start( AttributeType **at ) 343 { 344 assert( at != NULL ); 345 346 *at = LDAP_STAILQ_FIRST(&attr_list); 347 348 return (*at != NULL); 349 } 350 351 int 352 at_next( AttributeType **at ) 353 { 354 assert( at != NULL ); 355 356 #if 0 /* pedantic check: don't use this */ 357 { 358 AttributeType *tmp = NULL; 359 360 LDAP_STAILQ_FOREACH(tmp,&attr_list,sat_next) { 361 if ( tmp == *at ) { 362 break; 363 } 364 } 365 366 assert( tmp != NULL ); 367 } 368 #endif 369 370 *at = LDAP_STAILQ_NEXT(*at,sat_next); 371 372 return (*at != NULL); 373 } 374 375 /* 376 * check whether the two attributeTypes actually __are__ identical, 377 * or rather inconsistent 378 */ 379 static int 380 at_check_dup( 381 AttributeType *sat, 382 AttributeType *new_sat ) 383 { 384 if ( new_sat->sat_oid != NULL ) { 385 if ( sat->sat_oid == NULL ) { 386 return SLAP_SCHERR_ATTR_INCONSISTENT; 387 } 388 389 if ( strcmp( sat->sat_oid, new_sat->sat_oid ) != 0 ) { 390 return SLAP_SCHERR_ATTR_INCONSISTENT; 391 } 392 393 } else { 394 if ( sat->sat_oid != NULL ) { 395 return SLAP_SCHERR_ATTR_INCONSISTENT; 396 } 397 } 398 399 if ( new_sat->sat_names ) { 400 int i; 401 402 if ( sat->sat_names == NULL ) { 403 return SLAP_SCHERR_ATTR_INCONSISTENT; 404 } 405 406 for ( i = 0; new_sat->sat_names[ i ]; i++ ) { 407 if ( sat->sat_names[ i ] == NULL ) { 408 return SLAP_SCHERR_ATTR_INCONSISTENT; 409 } 410 411 if ( strcasecmp( sat->sat_names[ i ], 412 new_sat->sat_names[ i ] ) != 0 ) 413 { 414 return SLAP_SCHERR_ATTR_INCONSISTENT; 415 } 416 } 417 } else { 418 if ( sat->sat_names != NULL ) { 419 return SLAP_SCHERR_ATTR_INCONSISTENT; 420 } 421 } 422 423 return SLAP_SCHERR_ATTR_DUP; 424 } 425 426 static struct aindexrec *air_old; 427 428 static int 429 at_dup_error( void *left, void *right ) 430 { 431 air_old = left; 432 return -1; 433 } 434 435 static int 436 at_insert( 437 AttributeType **rat, 438 AttributeType *prev, 439 const char **err ) 440 { 441 struct aindexrec *air; 442 char **names = NULL; 443 AttributeType *sat = *rat; 444 445 if ( sat->sat_oid ) { 446 air = (struct aindexrec *) 447 ch_calloc( 1, sizeof(struct aindexrec) ); 448 ber_str2bv( sat->sat_oid, 0, 0, &air->air_name ); 449 air->air_at = sat; 450 air_old = NULL; 451 452 if ( avl_insert( &attr_index, (caddr_t) air, 453 attr_index_cmp, at_dup_error ) ) 454 { 455 AttributeType *old_sat; 456 int rc; 457 458 *err = sat->sat_oid; 459 460 assert( air_old != NULL ); 461 old_sat = air_old->air_at; 462 463 /* replacing a deleted definition? */ 464 if ( old_sat->sat_flags & SLAP_AT_DELETED ) { 465 AttributeType tmp; 466 AttributeDescription *ad; 467 468 /* Keep old oid, free new oid; 469 * Keep old ads, free new ads; 470 * Keep old ad_mutex, free new ad_mutex; 471 * Keep new everything else, free old 472 */ 473 tmp = *old_sat; 474 *old_sat = *sat; 475 old_sat->sat_oid = tmp.sat_oid; 476 tmp.sat_oid = sat->sat_oid; 477 old_sat->sat_ad = tmp.sat_ad; 478 tmp.sat_ad = sat->sat_ad; 479 old_sat->sat_ad_mutex = tmp.sat_ad_mutex; 480 tmp.sat_ad_mutex = sat->sat_ad_mutex; 481 *sat = tmp; 482 483 /* Check for basic ad pointing at old cname */ 484 for ( ad = old_sat->sat_ad; ad; ad=ad->ad_next ) { 485 if ( ad->ad_cname.bv_val == sat->sat_cname.bv_val ) { 486 ad->ad_cname = old_sat->sat_cname; 487 break; 488 } 489 } 490 491 at_clean( sat ); 492 at_destroy_one( air ); 493 494 air = air_old; 495 sat = old_sat; 496 *rat = sat; 497 } else { 498 ldap_memfree( air ); 499 500 rc = at_check_dup( old_sat, sat ); 501 502 return rc; 503 } 504 } 505 /* FIX: temporal consistency check */ 506 at_bvfind( &air->air_name ); 507 } 508 509 names = sat->sat_names; 510 if ( names ) { 511 while ( *names ) { 512 air = (struct aindexrec *) 513 ch_calloc( 1, sizeof(struct aindexrec) ); 514 ber_str2bv( *names, 0, 0, &air->air_name ); 515 air->air_at = sat; 516 if ( avl_insert( &attr_index, (caddr_t) air, 517 attr_index_cmp, avl_dup_error ) ) 518 { 519 AttributeType *old_sat; 520 int rc; 521 522 *err = *names; 523 524 old_sat = at_bvfind( &air->air_name ); 525 assert( old_sat != NULL ); 526 rc = at_check_dup( old_sat, sat ); 527 528 ldap_memfree(air); 529 530 while ( names > sat->sat_names ) { 531 struct aindexrec tmpair; 532 533 names--; 534 ber_str2bv( *names, 0, 0, &tmpair.air_name ); 535 tmpair.air_at = sat; 536 air = (struct aindexrec *)avl_delete( &attr_index, 537 (caddr_t)&tmpair, attr_index_cmp ); 538 assert( air != NULL ); 539 ldap_memfree( air ); 540 } 541 542 if ( sat->sat_oid ) { 543 struct aindexrec tmpair; 544 545 ber_str2bv( sat->sat_oid, 0, 0, &tmpair.air_name ); 546 tmpair.air_at = sat; 547 air = (struct aindexrec *)avl_delete( &attr_index, 548 (caddr_t)&tmpair, attr_index_cmp ); 549 assert( air != NULL ); 550 ldap_memfree( air ); 551 } 552 553 return rc; 554 } 555 /* FIX: temporal consistency check */ 556 at_bvfind(&air->air_name); 557 names++; 558 } 559 } 560 561 if ( sat->sat_oid ) { 562 slap_ad_undef_promote( sat->sat_oid, sat ); 563 } 564 565 names = sat->sat_names; 566 if ( names ) { 567 while ( *names ) { 568 slap_ad_undef_promote( *names, sat ); 569 names++; 570 } 571 } 572 573 if ( sat->sat_flags & SLAP_AT_HARDCODE ) { 574 prev = at_sys_tail; 575 at_sys_tail = sat; 576 } 577 if ( prev ) { 578 LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next ); 579 } else { 580 LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next ); 581 } 582 583 return 0; 584 } 585 586 int 587 at_add( 588 LDAPAttributeType *at, 589 int user, 590 AttributeType **rsat, 591 AttributeType *prev, 592 const char **err ) 593 { 594 AttributeType *sat = NULL; 595 MatchingRule *mr = NULL; 596 Syntax *syn = NULL; 597 int i; 598 int code = LDAP_SUCCESS; 599 char *cname = NULL; 600 char *oidm = NULL; 601 char *soidm = NULL; 602 603 if ( !at->at_oid ) { 604 *err = ""; 605 return SLAP_SCHERR_ATTR_INCOMPLETE; 606 } 607 608 if ( !OID_LEADCHAR( at->at_oid[0] )) { 609 char *oid; 610 611 /* Expand OID macros */ 612 oid = oidm_find( at->at_oid ); 613 if ( !oid ) { 614 *err = at->at_oid; 615 return SLAP_SCHERR_OIDM; 616 } 617 if ( oid != at->at_oid ) { 618 oidm = at->at_oid; 619 at->at_oid = oid; 620 } 621 } 622 623 if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) { 624 char *oid; 625 626 /* Expand OID macros */ 627 oid = oidm_find( at->at_syntax_oid ); 628 if ( !oid ) { 629 *err = at->at_syntax_oid; 630 code = SLAP_SCHERR_OIDM; 631 goto error_return; 632 } 633 if ( oid != at->at_syntax_oid ) { 634 soidm = at->at_syntax_oid; 635 at->at_syntax_oid = oid; 636 } 637 } 638 639 if ( at->at_names && at->at_names[0] ) { 640 int i; 641 642 for( i=0; at->at_names[i]; i++ ) { 643 if( !slap_valid_descr( at->at_names[i] ) ) { 644 *err = at->at_names[i]; 645 code = SLAP_SCHERR_BAD_DESCR; 646 goto error_return; 647 } 648 } 649 650 cname = at->at_names[0]; 651 652 } else { 653 cname = at->at_oid; 654 655 } 656 657 *err = cname; 658 659 if ( !at->at_usage && at->at_no_user_mod ) { 660 /* user attribute must be modifable */ 661 code = SLAP_SCHERR_ATTR_BAD_USAGE; 662 goto error_return; 663 } 664 665 if ( at->at_collective ) { 666 if( at->at_usage ) { 667 /* collective attributes cannot be operational */ 668 code = SLAP_SCHERR_ATTR_BAD_USAGE; 669 goto error_return; 670 } 671 672 if( at->at_single_value ) { 673 /* collective attributes cannot be single-valued */ 674 code = SLAP_SCHERR_ATTR_BAD_USAGE; 675 goto error_return; 676 } 677 } 678 679 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) ); 680 AC_MEMCPY( &sat->sat_atype, at, sizeof(LDAPAttributeType)); 681 682 sat->sat_cname.bv_val = cname; 683 sat->sat_cname.bv_len = strlen( cname ); 684 sat->sat_oidmacro = oidm; 685 sat->sat_soidmacro = soidm; 686 ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex); 687 688 if ( at->at_sup_oid ) { 689 AttributeType *supsat = at_find(at->at_sup_oid); 690 691 if ( supsat == NULL ) { 692 *err = at->at_sup_oid; 693 code = SLAP_SCHERR_ATTR_NOT_FOUND; 694 goto error_return; 695 } 696 697 sat->sat_sup = supsat; 698 699 if ( at_append_to_list(sat, &supsat->sat_subtypes) ) { 700 code = SLAP_SCHERR_OUTOFMEM; 701 goto error_return; 702 } 703 704 if ( sat->sat_usage != supsat->sat_usage ) { 705 /* subtypes must have same usage as their SUP */ 706 code = SLAP_SCHERR_ATTR_BAD_USAGE; 707 goto error_return; 708 } 709 710 if ( supsat->sat_obsolete && !sat->sat_obsolete ) { 711 /* subtypes must be obsolete if super is */ 712 code = SLAP_SCHERR_ATTR_BAD_SUP; 713 goto error_return; 714 } 715 716 if ( sat->sat_flags & SLAP_AT_FINAL ) { 717 /* cannot subtype a "final" attribute type */ 718 code = SLAP_SCHERR_ATTR_BAD_SUP; 719 goto error_return; 720 } 721 } 722 723 /* 724 * Inherit definitions from superiors. We only check the 725 * direct superior since that one has already inherited from 726 * its own superiorss 727 */ 728 if ( sat->sat_sup ) { 729 Syntax *syn = syn_find(sat->sat_sup->sat_syntax->ssyn_oid); 730 if ( syn != sat->sat_sup->sat_syntax ) { 731 sat->sat_syntax = ch_malloc( sizeof( Syntax )); 732 *sat->sat_syntax = *sat->sat_sup->sat_syntax; 733 } else { 734 sat->sat_syntax = sat->sat_sup->sat_syntax; 735 } 736 if ( sat->sat_sup->sat_equality ) { 737 MatchingRule *mr = mr_find( sat->sat_sup->sat_equality->smr_oid ); 738 if ( mr != sat->sat_sup->sat_equality ) { 739 sat->sat_equality = ch_malloc( sizeof( MatchingRule )); 740 *sat->sat_equality = *sat->sat_sup->sat_equality; 741 } else { 742 sat->sat_equality = sat->sat_sup->sat_equality; 743 } 744 } 745 sat->sat_approx = sat->sat_sup->sat_approx; 746 sat->sat_ordering = sat->sat_sup->sat_ordering; 747 sat->sat_substr = sat->sat_sup->sat_substr; 748 } 749 750 /* 751 * check for X-ORDERED attributes 752 */ 753 if ( sat->sat_extensions ) { 754 for (i=0; sat->sat_extensions[i]; i++) { 755 if (!strcasecmp( sat->sat_extensions[i]->lsei_name, 756 "X-ORDERED" ) && sat->sat_extensions[i]->lsei_values ) { 757 if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0], 758 "VALUES" )) { 759 sat->sat_flags |= SLAP_AT_ORDERED_VAL; 760 break; 761 } else if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0], 762 "SIBLINGS" )) { 763 sat->sat_flags |= SLAP_AT_ORDERED_SIB; 764 break; 765 } 766 } 767 } 768 } 769 770 if ( !user ) 771 sat->sat_flags |= SLAP_AT_HARDCODE; 772 773 if ( at->at_syntax_oid ) { 774 syn = syn_find(sat->sat_syntax_oid); 775 if ( syn == NULL ) { 776 *err = sat->sat_syntax_oid; 777 code = SLAP_SCHERR_SYN_NOT_FOUND; 778 goto error_return; 779 } 780 781 if ( sat->sat_syntax != NULL && sat->sat_syntax != syn ) { 782 /* BEWARE: no loop detection! */ 783 if ( syn_is_sup( sat->sat_syntax, syn ) ) { 784 code = SLAP_SCHERR_ATTR_BAD_SUP; 785 goto error_return; 786 } 787 } 788 789 sat->sat_syntax = syn; 790 791 } else if ( sat->sat_syntax == NULL ) { 792 code = SLAP_SCHERR_ATTR_INCOMPLETE; 793 goto error_return; 794 } 795 796 if ( sat->sat_equality_oid ) { 797 mr = mr_find(sat->sat_equality_oid); 798 799 if( mr == NULL ) { 800 *err = sat->sat_equality_oid; 801 code = SLAP_SCHERR_MR_NOT_FOUND; 802 goto error_return; 803 } 804 805 if(( mr->smr_usage & SLAP_MR_EQUALITY ) != SLAP_MR_EQUALITY ) { 806 *err = sat->sat_equality_oid; 807 code = SLAP_SCHERR_ATTR_BAD_MR; 808 goto error_return; 809 } 810 811 if( sat->sat_syntax != mr->smr_syntax ) { 812 if( mr->smr_compat_syntaxes == NULL ) { 813 *err = sat->sat_equality_oid; 814 code = SLAP_SCHERR_ATTR_BAD_MR; 815 goto error_return; 816 } 817 818 for(i=0; mr->smr_compat_syntaxes[i]; i++) { 819 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) { 820 i = -1; 821 break; 822 } 823 } 824 825 if( i >= 0 ) { 826 *err = sat->sat_equality_oid; 827 code = SLAP_SCHERR_ATTR_BAD_MR; 828 goto error_return; 829 } 830 } 831 832 sat->sat_equality = mr; 833 sat->sat_approx = mr->smr_associated; 834 } 835 836 if ( sat->sat_ordering_oid ) { 837 if( !sat->sat_equality ) { 838 *err = sat->sat_ordering_oid; 839 code = SLAP_SCHERR_ATTR_BAD_MR; 840 goto error_return; 841 } 842 843 mr = mr_find(sat->sat_ordering_oid); 844 845 if( mr == NULL ) { 846 *err = sat->sat_ordering_oid; 847 code = SLAP_SCHERR_MR_NOT_FOUND; 848 goto error_return; 849 } 850 851 if(( mr->smr_usage & SLAP_MR_ORDERING ) != SLAP_MR_ORDERING ) { 852 *err = sat->sat_ordering_oid; 853 code = SLAP_SCHERR_ATTR_BAD_MR; 854 goto error_return; 855 } 856 857 if( sat->sat_syntax != mr->smr_syntax ) { 858 if( mr->smr_compat_syntaxes == NULL ) { 859 *err = sat->sat_ordering_oid; 860 code = SLAP_SCHERR_ATTR_BAD_MR; 861 goto error_return; 862 } 863 864 for(i=0; mr->smr_compat_syntaxes[i]; i++) { 865 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) { 866 i = -1; 867 break; 868 } 869 } 870 871 if( i >= 0 ) { 872 *err = sat->sat_ordering_oid; 873 code = SLAP_SCHERR_ATTR_BAD_MR; 874 goto error_return; 875 } 876 } 877 878 sat->sat_ordering = mr; 879 } 880 881 if ( sat->sat_substr_oid ) { 882 if( !sat->sat_equality ) { 883 *err = sat->sat_substr_oid; 884 code = SLAP_SCHERR_ATTR_BAD_MR; 885 goto error_return; 886 } 887 888 mr = mr_find(sat->sat_substr_oid); 889 890 if( mr == NULL ) { 891 *err = sat->sat_substr_oid; 892 code = SLAP_SCHERR_MR_NOT_FOUND; 893 goto error_return; 894 } 895 896 if(( mr->smr_usage & SLAP_MR_SUBSTR ) != SLAP_MR_SUBSTR ) { 897 *err = sat->sat_substr_oid; 898 code = SLAP_SCHERR_ATTR_BAD_MR; 899 goto error_return; 900 } 901 902 /* due to funky LDAP builtin substring rules, 903 * we check against the equality rule assertion 904 * syntax and compat syntaxes instead of those 905 * associated with the substrings rule. 906 */ 907 if( sat->sat_syntax != sat->sat_equality->smr_syntax ) { 908 if( sat->sat_equality->smr_compat_syntaxes == NULL ) { 909 *err = sat->sat_substr_oid; 910 code = SLAP_SCHERR_ATTR_BAD_MR; 911 goto error_return; 912 } 913 914 for(i=0; sat->sat_equality->smr_compat_syntaxes[i]; i++) { 915 if( sat->sat_syntax == 916 sat->sat_equality->smr_compat_syntaxes[i] ) 917 { 918 i = -1; 919 break; 920 } 921 } 922 923 if( i >= 0 ) { 924 *err = sat->sat_substr_oid; 925 code = SLAP_SCHERR_ATTR_BAD_MR; 926 goto error_return; 927 } 928 } 929 930 sat->sat_substr = mr; 931 } 932 933 code = at_insert( &sat, prev, err ); 934 if ( code != 0 ) { 935 error_return:; 936 if ( sat ) { 937 ldap_pvt_thread_mutex_destroy( &sat->sat_ad_mutex ); 938 ch_free( sat ); 939 } 940 941 if ( oidm ) { 942 SLAP_FREE( at->at_oid ); 943 at->at_oid = oidm; 944 } 945 946 if ( soidm ) { 947 SLAP_FREE( at->at_syntax_oid ); 948 at->at_syntax_oid = soidm; 949 } 950 951 } else if ( rsat ) { 952 *rsat = sat; 953 } 954 955 return code; 956 } 957 958 #ifdef LDAP_DEBUG 959 #ifdef SLAPD_UNUSED 960 static int 961 at_index_printnode( void *v_air, void *ignore ) 962 { 963 struct aindexrec *air = v_air; 964 printf("%s = %s\n", 965 air->air_name.bv_val, 966 ldap_attributetype2str(&air->air_at->sat_atype) ); 967 return( 0 ); 968 } 969 970 static void 971 at_index_print( void ) 972 { 973 printf("Printing attribute type index:\n"); 974 (void) avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER ); 975 } 976 #endif 977 #endif 978 979 void 980 at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys ) 981 { 982 AttributeType *at; 983 int i, num; 984 struct berval bv, *bva = NULL, idx; 985 char ibuf[32]; 986 987 if ( !start ) 988 start = LDAP_STAILQ_FIRST( &attr_list ); 989 990 /* count the result size */ 991 i = 0; 992 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) { 993 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break; 994 i++; 995 if ( at == end ) break; 996 } 997 if (!i) return; 998 999 num = i; 1000 bva = ch_malloc( (num+1) * sizeof(struct berval) ); 1001 BER_BVZERO( bva ); 1002 idx.bv_val = ibuf; 1003 if ( sys ) { 1004 idx.bv_len = 0; 1005 ibuf[0] = '\0'; 1006 } 1007 i = 0; 1008 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) { 1009 LDAPAttributeType lat, *latp; 1010 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break; 1011 if ( at->sat_oidmacro || at->sat_soidmacro ) { 1012 lat = at->sat_atype; 1013 if ( at->sat_oidmacro ) 1014 lat.at_oid = at->sat_oidmacro; 1015 if ( at->sat_soidmacro ) 1016 lat.at_syntax_oid = at->sat_soidmacro; 1017 latp = ⪫ 1018 } else { 1019 latp = &at->sat_atype; 1020 } 1021 if ( ldap_attributetype2bv( latp, &bv ) == NULL ) { 1022 ber_bvarray_free( bva ); 1023 } 1024 if ( !sys ) { 1025 idx.bv_len = sprintf(idx.bv_val, "{%d}", i); 1026 } 1027 bva[i].bv_len = idx.bv_len + bv.bv_len; 1028 bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); 1029 strcpy( bva[i].bv_val, ibuf ); 1030 strcpy( bva[i].bv_val + idx.bv_len, bv.bv_val ); 1031 i++; 1032 bva[i].bv_val = NULL; 1033 ldap_memfree( bv.bv_val ); 1034 if ( at == end ) break; 1035 } 1036 *res = bva; 1037 } 1038 1039 int 1040 at_schema_info( Entry *e ) 1041 { 1042 AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes; 1043 AttributeType *at; 1044 struct berval val; 1045 struct berval nval; 1046 1047 LDAP_STAILQ_FOREACH(at,&attr_list,sat_next) { 1048 if( at->sat_flags & SLAP_AT_HIDE ) continue; 1049 1050 if ( ldap_attributetype2bv( &at->sat_atype, &val ) == NULL ) { 1051 return -1; 1052 } 1053 1054 ber_str2bv( at->sat_oid, 0, 0, &nval ); 1055 1056 if( attr_merge_one( e, ad_attributeTypes, &val, &nval ) ) 1057 { 1058 return -1; 1059 } 1060 ldap_memfree( val.bv_val ); 1061 } 1062 return 0; 1063 } 1064 1065 int 1066 register_at( const char *def, AttributeDescription **rad, int dupok ) 1067 { 1068 LDAPAttributeType *at; 1069 int code, freeit = 0; 1070 const char *err; 1071 AttributeDescription *ad = NULL; 1072 1073 at = ldap_str2attributetype( def, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); 1074 if ( !at ) { 1075 Debug( LDAP_DEBUG_ANY, 1076 "register_at: AttributeType \"%s\": %s, %s\n", 1077 def, ldap_scherr2str(code), err ); 1078 return code; 1079 } 1080 1081 code = at_add( at, 0, NULL, NULL, &err ); 1082 if ( code ) { 1083 if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) { 1084 freeit = 1; 1085 1086 } else { 1087 Debug( LDAP_DEBUG_ANY, 1088 "register_at: AttributeType \"%s\": %s, %s\n", 1089 def, scherr2str(code), err ); 1090 ldap_attributetype_free( at ); 1091 return code; 1092 } 1093 } 1094 code = slap_str2ad( at->at_names[0], &ad, &err ); 1095 if ( freeit || code ) { 1096 ldap_attributetype_free( at ); 1097 } else { 1098 ldap_memfree( at ); 1099 } 1100 if ( code ) { 1101 Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s\n", 1102 def, err, 0 ); 1103 } 1104 if ( rad ) *rad = ad; 1105 return code; 1106 } 1107