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