1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <ctype.h> 33 #include <fcntl.h> 34 #include <unistd.h> 35 #include <locale.h> 36 37 #include "ldap_parse.h" 38 #include "nis_parse_ldap_conf.h" 39 40 /* other attribute functions */ 41 static char *getIndex(const char **s_cur, const char *end_s); 42 static bool_t get_ttls(const char *s, const char *s_end, 43 __nis_table_mapping_t *t_mapping); 44 static __nis_object_dn_t *parse_object_dn(const char *s, const char *end); 45 static int parse_name_fields(const char *name_s, const char *name_s_end, 46 __nis_table_mapping_t *t_mapping); 47 static void get_mapping_rule(const char *s, int len, 48 __nis_table_mapping_t *tbl, bool_t to_ldap); 49 static bool_t get_deleteDisp(const char *s_begin, const char *s_end, 50 __nis_object_dn_t *obj_dn); 51 52 /* mapping rule functions */ 53 static const char *get_lhs(const char *s, const char *end_s, 54 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type); 55 static const char *get_lhs_match(const char *s, const char *end_s, 56 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type); 57 static const char *get_lhs_paren_item(const char *s, const char *end_s, 58 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type); 59 static const char *get_rhs(const char *s, const char *end_s, 60 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type); 61 static const char *get_mapping_item(const char *s, const char *end_s, 62 __nis_mapping_item_t *item, __nis_mapping_item_type_t type); 63 static const char *get_print_mapping_element(const char *s, 64 const char *end_s, char *fmt_string, __nis_mapping_element_t *e, 65 __nis_mapping_item_type_t item_type); 66 static const char *get_subElement(const char *s, const char *end_s, 67 __nis_mapping_sub_element_t *subelement, 68 __nis_mapping_item_type_t type); 69 static bool_t get_mapping_format(const char *fmt_string, 70 __nis_mapping_format_t **fmt, int *nfmt, int *numItems, 71 bool_t print_mapping); 72 extern __yp_domain_context_t ypDomains; 73 74 /* 75 * FUNCTION: add_mapping_attribute 76 * 77 * Adds the attribute value to __nis_table_mapping_t 78 * if the value is not yet set for the given database. 79 * 80 * RETURN VALUE: 0 on success, -1 on failure 81 * 82 * INPUT: attribute number and value 83 */ 84 85 int 86 add_mapping_attribute( 87 config_key attrib_num, 88 const char *attrib_val, 89 int attrib_len, 90 __nis_table_mapping_t **table_mapping) 91 { 92 const char *s; 93 const char *attrib_end; 94 const char *db_id_end; 95 const char *begin_token; 96 const char *end_token; 97 char *index_string; 98 __nis_object_dn_t *objectDN; 99 __nis_table_mapping_t *t_mapping; 100 __nis_table_mapping_t *t; 101 102 bool_t new_mapping = FALSE; 103 int nm; 104 char *tmp_dbId; 105 106 attrib_end = attrib_val + attrib_len; 107 for (s = attrib_val; s < attrib_end; s++) 108 if (*s == COLON_CHAR) 109 break; 110 111 if (s == attrib_end || *attrib_val == COLON_CHAR) { 112 p_error = parse_unexpected_data_end_rule; 113 return (-1); 114 } 115 116 db_id_end = s; 117 while (s > attrib_val && is_whitespace(s[-1])) 118 s--; 119 120 if (s == attrib_val) { 121 p_error = parse_unexpected_data_end_rule; 122 return (-1); 123 } 124 125 if (yp2ldap) { 126 tmp_dbId = s_strndup(attrib_val, s - attrib_val); 127 if (tmp_dbId == NULL) { 128 p_error = parse_no_mem_error; 129 return (-1); 130 } 131 if (strchr(tmp_dbId, COMMA_CHAR)) { 132 /* domain explicitly specified */ 133 nm = check_domain_specific_order(tmp_dbId, 134 attrib_num, *table_mapping, &ypDomains); 135 /* 136 * No logging is needed here, as 137 * check_domain_specific_order 138 * will log any appropriate errors. 139 */ 140 if (nm != 0) { 141 free(tmp_dbId); 142 return (-1); 143 } 144 } 145 free(tmp_dbId); 146 } 147 148 if ((t_mapping = find_table_mapping(attrib_val, 149 s - attrib_val, *table_mapping)) == NULL) { 150 /* No mapping with this id, create one */ 151 t_mapping = (__nis_table_mapping_t *) 152 s_calloc(1, sizeof (__nis_table_mapping_t)); 153 154 if (t_mapping == NULL) { 155 p_error = parse_no_mem_error; 156 return (-1); 157 } 158 (void) initialize_table_mapping(t_mapping); 159 160 /* dbId is the label before the colon */ 161 t_mapping->dbId = s_strndup(attrib_val, s - attrib_val); 162 if (t_mapping->dbId == NULL) { 163 p_error = parse_no_mem_error; 164 free(t_mapping); 165 return (-1); 166 } 167 new_mapping = TRUE; 168 } else { 169 /* a table mapping already exists, use it */ 170 new_mapping = FALSE; 171 } 172 173 s = db_id_end + 1; 174 while (s < attrib_end && is_whitespace(*s)) 175 s++; 176 177 switch (attrib_num) { 178 case key_yp_map_flags: 179 if (t_mapping->usedns_flag != 0 || 180 t_mapping->securemap_flag != 0) { 181 warn_duplicate_map(t_mapping->dbId, 182 attrib_num); 183 break; 184 } 185 while (is_whitespace(*s) && s < attrib_end) 186 s++; 187 while (s < attrib_end) { 188 if (s < attrib_end && *s == 'b') 189 t_mapping->usedns_flag = 1; 190 if (s < attrib_end && *s == 's') 191 t_mapping->securemap_flag = 1; 192 s++; 193 } 194 break; 195 case key_yp_comment_char: 196 if (t_mapping->commentChar != 197 DEFAULT_COMMENT_CHAR) { 198 warn_duplicate_map(t_mapping->dbId, attrib_num); 199 break; 200 } 201 while (is_whitespace(*s) && s < attrib_end) 202 s++; 203 if (s < attrib_end && (s+1) < attrib_end && 204 (s+2) <= attrib_end) { 205 while (is_whitespace(attrib_end[-1])) 206 attrib_end--; 207 while (*s != SINGLE_QUOTE_CHAR) 208 s++; 209 if (*s == SINGLE_QUOTE_CHAR && 210 *(s+2) == SINGLE_QUOTE_CHAR) { 211 t_mapping->commentChar = *(s+1); 212 } else if (*s == SINGLE_QUOTE_CHAR && 213 *(s+1) == SINGLE_QUOTE_CHAR) { 214 t_mapping->commentChar = NULL; 215 } else { 216 /* anything else is an error */ 217 p_error = parse_bad_yp_comment_error; 218 } 219 break; 220 } else { 221 p_error = parse_bad_yp_comment_error; 222 break; 223 } 224 case key_yp_repeated_field_separators: 225 while (s < attrib_end && is_whitespace(*s)) 226 s++; 227 if (s < attrib_end) { 228 while (is_whitespace(attrib_end[-1])) 229 attrib_end--; 230 while (s < attrib_end && 231 *s != DOUBLE_QUOTE_CHAR) 232 s++; 233 s++; 234 begin_token = s; 235 while (s < attrib_end && 236 *s != DOUBLE_QUOTE_CHAR) { 237 if (*s == ESCAPE_CHAR) 238 s++; 239 s++; 240 } 241 t_mapping->separatorStr = 242 s_strndup(begin_token, s - begin_token); 243 if (t_mapping->separatorStr == NULL) 244 break; 245 } else { 246 p_error = parse_bad_field_separator_error; 247 } 248 break; 249 case key_yp_name_fields: 250 case key_yp_split_field: 251 if (t_mapping->e || t_mapping->numSplits > 0) { 252 warn_duplicate_map(t_mapping->dbId, 253 attrib_num); 254 break; 255 } 256 if (parse_name_fields(s, attrib_end, t_mapping)) { 257 p_error = parse_bad_name_field; 258 } 259 break; 260 case key_yp_db_id_map: 261 case key_db_id_map: 262 if (t_mapping->objName != NULL) { 263 warn_duplicate_map(t_mapping->dbId, attrib_num); 264 break; 265 } 266 267 if (s < attrib_end && *s == OPEN_BRACKET) { 268 index_string = getIndex(&s, attrib_end); 269 if (index_string == NULL) 270 break; 271 (void) parse_index(index_string, 272 index_string + strlen(index_string), 273 &t_mapping->index); 274 free(index_string); 275 if (p_error != no_parse_error) 276 break; 277 } 278 while (is_whitespace(*s) && s < attrib_end) 279 s++; 280 if (s < attrib_end) { 281 while (is_whitespace(attrib_end[-1])) 282 attrib_end--; 283 t_mapping->objName = 284 s_strndup_esc(s, attrib_end - s); 285 } else { 286 if (yp2ldap) { 287 p_error = parse_bad_map_error; 288 } else { 289 t_mapping->objName = s_strndup(s, 0); 290 } 291 } 292 break; 293 294 case key_yp_entry_ttl: 295 case key_entry_ttl: 296 if (t_mapping->initTtlLo != (time_t)NO_VALUE_SET) { 297 warn_duplicate_map(t_mapping->dbId, attrib_num); 298 break; 299 } 300 301 if (!get_ttls(s, attrib_end, t_mapping)) 302 p_error = parse_bad_ttl_format_error; 303 break; 304 305 case key_yp_ldap_object_dn: 306 case key_ldap_object_dn: 307 if (t_mapping->objectDN != NULL) { 308 warn_duplicate_map(t_mapping->dbId, attrib_num); 309 break; 310 } 311 objectDN = parse_object_dn(s, attrib_end); 312 if (objectDN == NULL) 313 break; 314 t_mapping->objectDN = objectDN; 315 t_mapping->seq_num = seq_num++; 316 break; 317 318 case key_nis_to_ldap_map: 319 case key_nisplus_to_ldap_map: 320 if (t_mapping->ruleToLDAP != 0) { 321 warn_duplicate_map(t_mapping->dbId, attrib_num); 322 break; 323 } 324 325 get_mapping_rule(s, attrib_end - s, t_mapping, TRUE); 326 break; 327 328 case key_ldap_to_nis_map: 329 case key_ldap_to_nisplus_map: 330 if (t_mapping->ruleFromLDAP != NULL) { 331 warn_duplicate_map(t_mapping->dbId, attrib_num); 332 break; 333 } 334 335 get_mapping_rule(s, attrib_end - s, t_mapping, FALSE); 336 break; 337 338 default: 339 p_error = parse_internal_error; 340 break; 341 } 342 if (p_error == no_parse_error) { 343 if (new_mapping) { 344 if (*table_mapping == NULL) 345 *table_mapping = t_mapping; 346 else { 347 for (t = *table_mapping; t->next != NULL; 348 t = t->next) 349 ; 350 t->next = t_mapping; 351 } 352 } 353 } else { 354 if (new_mapping) 355 free_table_mapping(t_mapping); 356 } 357 return (p_error == no_parse_error ? 0 : -1); 358 } 359 360 /* 361 * FUNCTION: add_ypdomains_attribute 362 * 363 * Adds the yp domains information to the __yp_domain_context_t 364 * structure. 365 * 366 * RETURN: 0 on success, -1 on failure 367 * 368 * INPUT: attribute number and value 369 */ 370 371 int 372 add_ypdomains_attribute( 373 config_key attrib_num, 374 const char *attrib_val, 375 int attrib_len, 376 __yp_domain_context_t *ypDomains) 377 { 378 const char *s; 379 const char *attrib_end; 380 int numDomains = 0; 381 int i; 382 char *tmp_str; 383 int ret = 0; 384 385 attrib_end = attrib_val + attrib_len; 386 for (s = attrib_val; s < attrib_end; s++) { 387 if (*s == COLON_CHAR) { 388 break; 389 } 390 } 391 while (s > attrib_val && is_whitespace(s[-1])) 392 s--; 393 394 if (s == attrib_val) { 395 p_error = parse_unexpected_data_end_rule; 396 return (-1); 397 } 398 399 if (ypDomains == NULL) { 400 /* 401 * No point allocating. We cant return the resulting structure, 402 * so just return failure. Should not ever happen because we 403 * are always called with a pointer to the global ypDomains 404 * structure. 405 */ 406 return (-1); 407 } 408 409 switch (attrib_num) { 410 case key_yp_domain_context: 411 numDomains = ypDomains->numDomains; 412 ypDomains->domainLabels = 413 (char **)s_realloc(ypDomains->domainLabels, 414 (numDomains + 1) * 415 sizeof (ypDomains->domainLabels[0])); 416 if (ypDomains->domainLabels == NULL) { 417 p_error = parse_no_mem_error; 418 free_yp_domain_context(ypDomains); 419 break; 420 } 421 ypDomains->domainLabels[numDomains] = 422 s_strndup(attrib_val, s - attrib_val); 423 if (ypDomains->domainLabels[numDomains] == NULL) { 424 p_error = parse_no_mem_error; 425 free_yp_domain_context(ypDomains); 426 break; 427 } 428 ypDomains->numDomains = numDomains + 1; 429 while (s < attrib_end && is_whitespace(*s)) 430 s++; 431 if (*s == COLON_CHAR) 432 s++; 433 while (s < attrib_end && is_whitespace(*s)) 434 s++; 435 ypDomains->domains = 436 (char **)s_realloc(ypDomains->domains, 437 (numDomains + 1) * 438 sizeof (ypDomains->domains[0])); 439 if (ypDomains->domains == NULL) { 440 p_error = parse_no_mem_error; 441 free_yp_domain_context(ypDomains); 442 break; 443 } 444 445 if (s < attrib_end) { 446 while (is_whitespace(attrib_end[-1])) 447 attrib_end--; 448 ypDomains->domains[numDomains] = 449 s_strndup_esc(s, attrib_end - s); 450 if (ypDomains->domains[numDomains] == NULL) { 451 p_error = parse_no_mem_error; 452 free_yp_domain_context(ypDomains); 453 break; 454 } 455 } else { 456 p_error = parse_unexpected_yp_domain_end_error; 457 free(ypDomains->domainLabels[numDomains]); 458 ypDomains->domainLabels[numDomains] = NULL; 459 ypDomains->numDomains--; 460 free_yp_domain_context(ypDomains); 461 } 462 break; 463 case key_yppasswdd_domains: 464 ypDomains->yppasswddDomainLabels = 465 (char **)s_realloc( 466 ypDomains->yppasswddDomainLabels, 467 (ypDomains->numYppasswdd + 1) * 468 sizeof (ypDomains->yppasswddDomainLabels[0])); 469 if (ypDomains->yppasswddDomainLabels == NULL) { 470 p_error = parse_no_mem_error; 471 break; 472 } 473 ypDomains->yppasswddDomainLabels 474 [ypDomains->numYppasswdd] = 475 s_strndup(attrib_val, s - attrib_val); 476 if (ypDomains->yppasswddDomainLabels 477 [ypDomains->numYppasswdd] == NULL) { 478 p_error = parse_no_mem_error; 479 } 480 ypDomains->numYppasswdd++; 481 break; 482 } 483 484 return (p_error == no_parse_error ? 0 : -1); 485 } 486 487 /* 488 * FUNCTION: get_ttls 489 * 490 * Parse time to live attribute 491 * 492 * RETURN VALUE: TRUE on success, FALSE on failure 493 * 494 * INPUT: the attribute value 495 */ 496 497 static bool_t 498 get_ttls( 499 const char *s, 500 const char *s_end, 501 __nis_table_mapping_t *t_mapping) 502 { 503 time_t initTtlHi = 0; 504 time_t initTtlLo = 0; 505 time_t ttl = 0; 506 time_t digit; 507 508 /* 509 * attribute should be of the form 510 * initialTTLlo ":" initialTTLhi ":" runningTTL 511 */ 512 513 if (s == s_end) { 514 p_error = parse_bad_ttl_format_error; 515 return (FALSE); 516 } 517 518 if (isdigit(*s)) { 519 while (s < s_end && isdigit(*s)) { 520 digit = (*s++) - '0'; 521 if (WILL_OVERFLOW_TIME(initTtlLo, digit)) 522 initTtlLo = TIME_MAX; 523 else 524 initTtlLo = initTtlLo * 10 + digit; 525 } 526 } else { 527 initTtlLo = ONE_HOUR; 528 } 529 530 while (s < s_end && is_whitespace(*s)) 531 s++; 532 if (s + 1 >= s_end || *s++ != COLON_CHAR) { 533 p_error = parse_bad_ttl_format_error; 534 return (FALSE); 535 } 536 537 while (s < s_end && is_whitespace(*s)) 538 s++; 539 if (isdigit(*s)) { 540 while (s < s_end && isdigit(*s)) { 541 digit = (*s++) - '0'; 542 if (WILL_OVERFLOW_TIME(initTtlHi, digit)) 543 initTtlHi = TIME_MAX; 544 else 545 initTtlHi = initTtlHi * 10 + digit; 546 } 547 } else { 548 initTtlHi = initTtlLo; 549 } 550 551 while (s < s_end && is_whitespace(*s)) 552 s++; 553 if (s >= s_end || *s++ != COLON_CHAR) { 554 p_error = parse_bad_ttl_format_error; 555 return (FALSE); 556 } 557 558 while (s < s_end && is_whitespace(*s)) 559 s++; 560 if (isdigit(*s)) { 561 while (s < s_end && isdigit(*s)) { 562 digit = (*s++) - '0'; 563 if (WILL_OVERFLOW_TIME(ttl, digit)) 564 ttl = TIME_MAX; 565 else 566 ttl = ttl * 10 + digit; 567 } 568 } else { 569 ttl = ONE_HOUR; 570 } 571 while (s < s_end && is_whitespace(*s)) 572 s++; 573 if (s != s_end) { 574 p_error = parse_bad_ttl_format_error; 575 return (FALSE); 576 } 577 578 t_mapping->initTtlLo = initTtlLo; 579 t_mapping->initTtlHi = initTtlHi; 580 t_mapping->ttl = ttl; 581 return (TRUE); 582 } 583 584 /* 585 * FUNCTION: parse_name_fields 586 * 587 * Parse yp name fields 588 * 589 * RETURN VALUE: 0 on success, non-zero on failure 590 * 591 * INPUTS: attrib_value and attribute_end pointers. 592 */ 593 594 static int 595 parse_name_fields(const char *name_s, 596 const char *name_s_end, 597 __nis_table_mapping_t *t_map) 598 { 599 int i, n = 0; 600 int nElements = 0; 601 int numSplits = 0; 602 int parse_next_line = 1; 603 int itm_count = 0; 604 const char *begin_fmt; 605 const char *end_fmt; 606 const char *begin_token; 607 const char *end_token; 608 char *fmt_string = NULL; 609 __nis_mapping_format_t *base = NULL; 610 __nis_mapping_item_t *item = NULL; 611 __nis_mapping_element_t *elmnt = NULL; 612 __nis_mapping_item_type_t item_type = mit_nisplus; 613 token_type token; 614 615 t_map->numColumns = 0; 616 617 for (; parse_next_line > 0; parse_next_line--) { 618 nElements = 0; 619 item = NULL; 620 base = NULL; 621 while (name_s < name_s_end && *name_s != OPEN_PAREN_CHAR) 622 name_s++; 623 if (name_s == name_s_end) { 624 p_error = parse_unexpected_data_end_rule; 625 return (1); 626 } 627 while (name_s < name_s_end && *name_s != DOUBLE_QUOTE_CHAR) 628 name_s++; 629 if (name_s == name_s_end) { 630 p_error = parse_unexpected_data_end_rule; 631 return (1); 632 } 633 begin_fmt = ++name_s; /* start of format string */ 634 while (name_s < name_s_end && *name_s != DOUBLE_QUOTE_CHAR) 635 name_s++; 636 if (name_s == name_s_end) { 637 p_error = parse_unexpected_data_end_rule; 638 return (1); 639 } 640 end_fmt = name_s; 641 fmt_string = s_strndup(begin_fmt, end_fmt - begin_fmt); 642 if (fmt_string == NULL) { 643 p_error = parse_no_mem_error; 644 return (2); 645 } 646 if (!get_mapping_format(fmt_string, &base, &n, NULL, FALSE)) { 647 p_error = parse_internal_error; 648 free(fmt_string); 649 fmt_string = NULL; 650 return (3); 651 } 652 free(fmt_string); 653 fmt_string = NULL; 654 for (n = 0; base[n].type != mmt_end; n++) { 655 if (base[n].type != mmt_item && base[n].type 656 != mmt_berstring) { 657 if (base[n].type == mmt_berstring_null) 658 base[n].type = mmt_berstring; 659 continue; 660 } 661 while (name_s < name_s_end && *name_s != COMMA_CHAR) 662 name_s++; 663 name_s++; /* now at comma char */ 664 while (name_s < name_s_end && is_whitespace(*name_s)) 665 name_s++; 666 begin_token = name_s++; 667 end_token = name_s_end; 668 name_s = get_next_token( 669 &begin_token, &end_token, &token); 670 if (name_s == NULL) { 671 p_error = parse_item_expected_error; 672 return (4); 673 } 674 if (token != string_token) { 675 p_error = parse_item_expected_error; 676 return (5); 677 } 678 item = (__nis_mapping_item_t *)s_realloc(item, 679 (nElements + 1) * 680 sizeof (__nis_mapping_item_t)); 681 if (item == NULL) { 682 p_error = parse_no_mem_error; 683 return (2); 684 } 685 name_s = get_mapping_item(begin_token, name_s_end, 686 &item[nElements], item_type); 687 if (name_s == NULL) { 688 p_error = parse_unmatched_escape; 689 for (n = 0; n < (nElements + 1); n++) 690 free_mapping_item(&item[n]); 691 free_mapping_format(base); 692 return (4); 693 } 694 nElements++; 695 } 696 if (p_error != no_parse_error) { 697 for (n = 0; n < (nElements + 1); n++) 698 free_mapping_item(&item[n]); 699 free_mapping_format(base); 700 return (6); 701 } 702 name_s = skip_token(name_s, name_s_end, close_paren_token); 703 if (name_s == NULL) { 704 p_error = parse_close_paren_expected_error; 705 for (n = 0; n < (nElements + 1); n++) 706 free_mapping_item(&item[n]); 707 free_mapping_format(base); 708 return (4); 709 } 710 while (name_s < name_s_end && is_whitespace(*name_s)) 711 name_s++; 712 if (*name_s == COMMA_CHAR) 713 parse_next_line++; 714 715 if (nElements == 0) { 716 p_error = parse_no_match_item; 717 for (n = 0; n < (nElements + 1); n++) 718 free_mapping_item(&item[n]); 719 free_mapping_format(base); 720 return (7); 721 } 722 elmnt = (__nis_mapping_element_t *)s_realloc(elmnt, 723 (numSplits + 1) * 724 sizeof (__nis_mapping_element_t)); 725 if (elmnt == NULL) { 726 for (n = 0; n < (nElements + 1); n++) 727 free_mapping_item(&item[n]); 728 free_mapping_format(base); 729 p_error = parse_no_mem_error; 730 return (2); 731 } 732 elmnt[numSplits].type = me_match; 733 elmnt[numSplits].element.match.numItems = nElements; 734 elmnt[numSplits].element.match.item = item; 735 elmnt[numSplits].element.match.fmt = base; 736 item = NULL; 737 base = NULL; 738 739 t_map->e = elmnt; 740 t_map->numSplits = numSplits; 741 n = t_map->numColumns; 742 743 for (i = n, itm_count = 0; i < n + nElements; i++) { 744 if (t_map->e[numSplits].element. 745 match.item[itm_count].name) { 746 if (!add_column(t_map, 747 t_map->e[numSplits].element. 748 match.item[itm_count].name)) 749 return (1); 750 itm_count++; 751 } else { 752 p_error = parse_internal_error; 753 for (n = 0; n < (nElements + 1); n++) 754 free_mapping_item(&item[n]); 755 free_mapping_format(base); 756 free_mapping_element(elmnt); 757 return (1); 758 } 759 } 760 numSplits++; 761 } 762 elmnt = NULL; 763 764 if (item != NULL) { 765 for (n = 0; n < t_map->numColumns; n++) { 766 free_mapping_item(&item[n]); 767 } 768 free(item); 769 } 770 if (elmnt != NULL) 771 free_mapping_element(elmnt); 772 if (base != NULL) 773 free_mapping_format(base); 774 775 return (p_error == no_parse_error ? 0 : -1); 776 } 777 778 /* 779 * FUNCTION: parse_object_dn 780 * 781 * Parse object dn attribute 782 * 783 * RETURN VALUE: __nis_object_dn_t on success 784 * NULL on failure 785 * 786 * INPUT: the attribute value 787 */ 788 789 static __nis_object_dn_t * 790 parse_object_dn(const char *s, const char *end) 791 { 792 const char *s_begin; 793 const char *s_end; 794 object_dn_token token; 795 parse_object_dn_state dn_state = dn_begin_parse; 796 __nis_object_dn_t *obj_dn = NULL; 797 __nis_object_dn_t *next = NULL; 798 __nis_object_dn_t *last = NULL; 799 800 /* 801 * The attribute should be of form 802 * objectDN *( ";" objectDN ) 803 * objectDN = readObjectSpec [":"[writeObjectSpec]] 804 * readObjectSpec = [baseAndScope [filterAttrValList]] 805 * writeObjectSpec = [baseAndScope [attrValList [":" deleteDisp]]] 806 */ 807 808 while (s < end) { 809 s_begin = s; 810 s_end = end; 811 s = get_next_object_dn_token(&s_begin, &s_end, &token); 812 if (s == NULL) 813 break; 814 815 if (token == dn_no_token || token == dn_semi_token) { 816 if (obj_dn == NULL) 817 obj_dn = next; 818 else 819 last->next = next; 820 last = next; 821 next = NULL; 822 if (token == dn_no_token) 823 break; 824 dn_state = dn_begin_parse; 825 } 826 if (next == NULL) { 827 next = (__nis_object_dn_t *) 828 s_calloc(1, sizeof (__nis_object_dn_t)); 829 if (next == NULL) 830 break; 831 next->read.scope = LDAP_SCOPE_ONELEVEL; 832 next->write.scope = LDAP_SCOPE_UNKNOWN; 833 next->delDisp = dd_always; 834 } 835 if (token == dn_semi_token) 836 continue; 837 838 switch (dn_state) { 839 case dn_begin_parse: 840 if (token == dn_ques_token) 841 dn_state = dn_got_read_q_scope; 842 else if (token == dn_colon_token) { 843 dn_state = dn_got_write_colon; 844 next->write.scope = LDAP_SCOPE_ONELEVEL; 845 } else { 846 if (!validate_dn(s_begin, s_end - s_begin)) 847 break; 848 next->read.base = 849 s_strndup_esc(s_begin, s_end - s_begin); 850 dn_state = dn_got_read_dn; 851 } 852 break; 853 case dn_got_read_dn: 854 if (token == dn_ques_token) 855 dn_state = dn_got_read_q_scope; 856 else if (token == dn_colon_token) { 857 dn_state = dn_got_write_colon; 858 next->write.scope = LDAP_SCOPE_ONELEVEL; 859 } else 860 p_error = parse_object_dn_syntax_error; 861 break; 862 case dn_got_read_q_scope: 863 if (token == dn_ques_token) 864 dn_state = dn_got_read_q_filter; 865 else if (token == dn_colon_token) { 866 dn_state = dn_got_write_colon; 867 next->write.scope = LDAP_SCOPE_ONELEVEL; 868 } else if (token == dn_base_token) { 869 next->read.scope = LDAP_SCOPE_BASE; 870 dn_state = dn_got_read_scope; 871 } else if (token == dn_one_token) { 872 next->read.scope = LDAP_SCOPE_ONELEVEL; 873 dn_state = dn_got_read_scope; 874 } else if (token == dn_sub_token) { 875 next->read.scope = LDAP_SCOPE_SUBTREE; 876 dn_state = dn_got_read_scope; 877 } else { 878 p_error = parse_invalid_scope; 879 } 880 break; 881 case dn_got_read_scope: 882 if (token == dn_ques_token) 883 dn_state = dn_got_read_q_filter; 884 else if (token == dn_colon_token) { 885 dn_state = dn_got_write_colon; 886 next->write.scope = LDAP_SCOPE_ONELEVEL; 887 } else 888 p_error = parse_object_dn_syntax_error; 889 break; 890 case dn_got_read_q_filter: 891 if (token == dn_ques_token) { 892 p_error = parse_object_dn_syntax_error; 893 } else if (token == dn_colon_token) { 894 dn_state = dn_got_write_colon; 895 next->write.scope = LDAP_SCOPE_ONELEVEL; 896 } else { 897 if (!validate_ldap_filter(s_begin, s_end)) 898 break; 899 next->read.attrs = 900 s_strndup_esc(s_begin, s_end - s_begin); 901 dn_state = dn_got_read_filter; 902 } 903 break; 904 case dn_got_read_filter: 905 if (token == dn_ques_token) { 906 p_error = parse_object_dn_syntax_error; 907 } else if (token == dn_colon_token) { 908 dn_state = dn_got_write_colon; 909 next->write.scope = LDAP_SCOPE_ONELEVEL; 910 } else 911 p_error = parse_object_dn_syntax_error; 912 break; 913 case dn_got_write_colon: 914 if (token == dn_ques_token) 915 dn_state = dn_got_write_q_scope; 916 else if (token == dn_colon_token) { 917 dn_state = dn_got_delete_colon; 918 } else { 919 if (!validate_dn(s_begin, s_end - s_begin)) 920 break; 921 next->write.base = 922 s_strndup_esc(s_begin, s_end - s_begin); 923 dn_state = dn_got_write_dn; 924 } 925 break; 926 case dn_got_write_dn: 927 if (token == dn_ques_token) 928 dn_state = dn_got_write_q_scope; 929 else if (token == dn_colon_token) { 930 dn_state = dn_got_delete_colon; 931 } else 932 p_error = parse_object_dn_syntax_error; 933 break; 934 case dn_got_write_q_scope: 935 if (token == dn_ques_token) 936 dn_state = dn_got_write_q_filter; 937 else if (token == dn_colon_token) { 938 dn_state = dn_got_delete_colon; 939 } else if (token == dn_base_token) { 940 next->write.scope = LDAP_SCOPE_BASE; 941 dn_state = dn_got_write_scope; 942 } else if (token == dn_one_token) { 943 next->write.scope = LDAP_SCOPE_ONELEVEL; 944 dn_state = dn_got_write_scope; 945 } else if (token == dn_sub_token) { 946 next->write.scope = LDAP_SCOPE_SUBTREE; 947 dn_state = dn_got_write_scope; 948 } else { 949 p_error = parse_invalid_scope; 950 } 951 break; 952 case dn_got_write_scope: 953 if (token == dn_ques_token) 954 dn_state = dn_got_write_q_filter; 955 else if (token == dn_colon_token) { 956 dn_state = dn_got_delete_colon; 957 } else 958 p_error = parse_object_dn_syntax_error; 959 break; 960 case dn_got_write_q_filter: 961 if (token == dn_ques_token) { 962 p_error = parse_object_dn_syntax_error; 963 } else if (token == dn_colon_token) { 964 dn_state = dn_got_delete_colon; 965 } else { 966 if (!validate_ldap_filter(s_begin, s_end)) 967 break; 968 next->write.attrs = 969 s_strndup_esc(s_begin, s_end - s_begin); 970 dn_state = dn_got_write_filter; 971 } 972 break; 973 case dn_got_write_filter: 974 if (token == dn_ques_token) { 975 p_error = parse_object_dn_syntax_error; 976 } else if (token == dn_colon_token) { 977 dn_state = dn_got_delete_colon; 978 979 } else 980 p_error = parse_semi_expected_error; 981 break; 982 case dn_got_delete_colon: 983 if (token == dn_ques_token) { 984 p_error = parse_object_dn_syntax_error; 985 } else if (token == dn_colon_token) { 986 p_error = parse_object_dn_syntax_error; 987 } else { 988 if (!get_deleteDisp(s_begin, s_end, next)) 989 break; 990 dn_state = dn_got_delete_dsp; 991 } 992 break; 993 case dn_got_delete_dsp: 994 p_error = parse_object_dn_syntax_error; 995 break; 996 } 997 998 if (p_error != no_parse_error) 999 break; 1000 } 1001 if (p_error != no_parse_error) { 1002 if (obj_dn != NULL) 1003 free_object_dn(obj_dn); 1004 if (next != NULL) 1005 free_object_dn(next); 1006 obj_dn = NULL; 1007 } else if (next != NULL) { 1008 if (obj_dn == NULL) 1009 obj_dn = next; 1010 else 1011 last->next = next; 1012 } else if (obj_dn == NULL) 1013 obj_dn = (__nis_object_dn_t *) 1014 s_calloc(1, sizeof (__nis_object_dn_t)); 1015 1016 return (obj_dn); 1017 } 1018 1019 /* 1020 * FUNCTION: get_mapping_rule 1021 * 1022 * Parse mapping rule attributes 1023 * 1024 * RETURN VALUE: None. Errors determined by p_error 1025 * 1026 * INPUT: the attribute value and mapping rule type 1027 */ 1028 1029 static void 1030 get_mapping_rule( 1031 const char *s, 1032 int len, 1033 __nis_table_mapping_t *tbl, 1034 bool_t to_ldap) 1035 { 1036 const char *end_s = s + len; 1037 const char *begin_token; 1038 const char *end_token; 1039 __nis_mapping_rule_t **rule = NULL; 1040 __nis_mapping_rule_t *next = NULL; 1041 /* __nis_mapping_rule_t **r; */ 1042 token_type t; 1043 int nRules = 0; 1044 const char *s1; 1045 int i; 1046 1047 /* 1048 * The attribute value is of the form 1049 * colattrspec *("," colattrspec) 1050 * colattrspec = lhs "=" rhs 1051 * lhs = lval | namespeclist 1052 * rhs = rval | [namespec] 1053 */ 1054 1055 for (;;) { 1056 if ((next = (__nis_mapping_rule_t *) 1057 s_calloc(1, sizeof (__nis_mapping_rule_t))) == NULL) 1058 break; 1059 1060 s = get_lhs(s, end_s, &next->lhs, 1061 to_ldap ? mit_ldap : mit_nisplus); 1062 if (s == NULL) 1063 break; 1064 1065 begin_token = s; 1066 end_token = end_s; 1067 s1 = get_next_token(&begin_token, &end_token, &t); 1068 if (s1 == NULL) 1069 break; 1070 if (!(to_ldap && (t == comma_token || t == no_token))) { 1071 s = get_rhs(s, end_s, &next->rhs, 1072 to_ldap ? mit_nisplus : mit_ldap); 1073 if (s == NULL) 1074 break; 1075 } 1076 1077 if (next->lhs.numElements > 1 && 1078 (next->rhs.numElements != 1 || 1079 next->rhs.element[0].type != me_split)) { 1080 p_error = parse_lhs_rhs_type_mismatch; 1081 break;