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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 * 24 * Copyright 2022 RackTop Systems, Inc. 25 */ 26 27 %{ 28 #include <sys/acl.h> 29 #include <aclutils.h> 30 #include <idmap.h> 31 #include <errno.h> 32 #include "acl.tab.h" 33 34 #ifdef input 35 #undef input 36 #endif 37 38 #ifdef unput 39 #undef unput 40 #endif 41 42 int grab_string(char *terminators); 43 static int input(); 44 static void unput(int); 45 46 int 47 yyerror(const char *s) 48 { 49 return (0); 50 } 51 52 int 53 yywrap(void) 54 { 55 return (1); 56 } 57 58 extern char *yybuf; 59 int yybufpos; 60 61 /* 62 * Used for tracking allocated strings while walking through an ACL. 63 */ 64 struct yystrings { 65 char *y_logname; /* user/group name from LOGNAME */ 66 char *y_perms; /* permssions from PERM_TOK */ 67 char *y_iflags; /* iflags from INHERIT_TOK */ 68 char *y_idstr; /* string of appened id */ 69 } yystrings; 70 71 %} 72 73 %e 1500 74 %s TS NS PS AIS AS US ES 75 %p 5000 76 77 /* 78 * TS = type state 79 * NS = name state 80 * PS = Permission state 81 * AIS = Allow/deny/inheritance state 82 * AS = Allow state (only used when inheritance detected) 83 * US = UID/GID state 84 * ES = End state 85 */ 86 87 ID [0-9]+ 88 SID S-[^:,\n]+ 89 LOGNAME [^:]+: 90 PERM_STR [rRwWxpdDaAcCos-]+ 91 INHERIT_STR [fdinFSI-]+ 92 93 %% 94 95 <TS>user: { 96 BEGIN NS; 97 yylval.val = USER_TOK; 98 return (ENTRY_TYPE); 99 } 100 <TS>usersid: { 101 BEGIN NS; 102 yylval.val = USER_SID_TOK; 103 return (ENTRY_TYPE); 104 } 105 <TS>owner@: { 106 BEGIN PS; 107 yylval.val = OWNERAT_TOK; 108 return (ENTRY_TYPE); 109 } 110 <TS>group@: { 111 BEGIN PS; 112 yylval.val = GROUPAT_TOK; 113 return (ENTRY_TYPE); 114 } 115 <TS>everyone@: { 116 BEGIN PS; 117 yylval.val = EVERYONEAT_TOK; 118 return (ENTRY_TYPE); 119 } 120 <TS>group: { 121 BEGIN NS; 122 yylval.val = GROUP_TOK; 123 return (ENTRY_TYPE); 124 } 125 <TS>groupsid: { 126 BEGIN NS; 127 yylval.val = GROUP_SID_TOK; 128 return (ENTRY_TYPE); 129 } 130 <TS>sid: { 131 BEGIN NS; 132 yylval.val = BARE_SID_TOK; 133 return (ENTRY_TYPE); 134 } 135 <TS>mask: { 136 BEGIN PS; 137 yylval.val = MASK_TOK; 138 return (ENTRY_TYPE); 139 } 140 <TS>mask:: { 141 BEGIN PS; 142 yylval.val = MASK_TOK; 143 return (ENTRY_TYPE); 144 } 145 <TS>other: { 146 BEGIN PS; 147 yylval.val = OTHER_TOK; 148 return (ENTRY_TYPE); 149 } 150 <TS>other:: { 151 BEGIN PS; 152 yylval.val = OTHER_TOK; 153 return (ENTRY_TYPE); 154 } 155 <TS>defaultuser: { 156 BEGIN NS; 157 yylval.val = DEFAULT_USER_TOK; 158 return (ENTRY_TYPE); 159 } 160 <TS>default:user: { 161 BEGIN NS; 162 yylval.val = DEFAULT_USER_TOK; 163 return (ENTRY_TYPE); 164 } 165 <TS>defaultgroup: { 166 BEGIN NS; 167 yylval.val = DEFAULT_GROUP_TOK; 168 return (ENTRY_TYPE); 169 } 170 <TS>default:group: { 171 BEGIN NS; 172 yylval.val = DEFAULT_GROUP_TOK; 173 return (ENTRY_TYPE); 174 } 175 <TS>defaultother: { 176 BEGIN PS; 177 yylval.val = DEFAULT_OTHER_TOK; 178 return (ENTRY_TYPE); 179 } 180 <TS>defaultother:: { 181 BEGIN PS; 182 yylval.val = DEFAULT_OTHER_TOK; 183 return (ENTRY_TYPE); 184 } 185 <TS>default:other: { 186 BEGIN PS; 187 yylval.val = DEFAULT_OTHER_TOK; 188 return (ENTRY_TYPE); 189 } 190 <TS>defaultmask: { 191 BEGIN PS; 192 yylval.val = DEFAULT_MASK_TOK; 193 return (ENTRY_TYPE); 194 } 195 <TS>defaultmask:: { 196 BEGIN PS; 197 yylval.val = DEFAULT_MASK_TOK; 198 return (ENTRY_TYPE); 199 } 200 <TS>default:mask: { 201 BEGIN PS; 202 yylval.val = DEFAULT_MASK_TOK; 203 return (ENTRY_TYPE); 204 } 205 <TS>"\n" { 206 return (NL); 207 } 208 <TS>. { 209 if (grab_string(":,\n") != 0) { 210 acl_error(dgettext(TEXT_DOMAIN, 211 "Failed to retrieve" 212 " error string.\n")); 213 yylval.val = EACL_MEM_ERROR; 214 return (ERROR); 215 } 216 acl_error(dgettext(TEXT_DOMAIN, 217 "Invalid ACL entry " 218 "type '%s' specified.\n"), yylval.str); 219 free(yylval.str); 220 yylval.val = EACL_ENTRY_ERROR; 221 return (ERROR); 222 } 223 <NS>: { 224 BEGIN PS; 225 return (COLON); 226 } 227 <NS>{LOGNAME} { 228 yylval.str = strdup(yytext); 229 if (yylval.str == NULL) { 230 yylval.val = EACL_MEM_ERROR; 231 return (ERROR); 232 } 233 yylval.str[strlen(yylval.str) -1] = '\0'; 234 yystrings.y_logname = yylval.str; 235 BEGIN PS; 236 return (IDNAME); 237 } 238 <NS>"\n" { 239 acl_error(dgettext(TEXT_DOMAIN, 240 "Missing user/group name" 241 " from ACL specification.\n")); 242 yylval.val = EACL_MISSING_FIELDS; 243 return (ERROR); 244 } 245 <NS>. { 246 int error; 247 248 error = grab_string(":,\n"); 249 if (error != 0) { 250 acl_error(dgettext(TEXT_DOMAIN, 251 "Invalid user/group " 252 "name specification.\n")); 253 yylval.val = EACL_INVALID_USER_GROUP; 254 } else { 255 acl_error(dgettext(TEXT_DOMAIN, 256 "User/Group name " 257 "'%s' not specified correctly.\n"), 258 yylval.str); 259 free(yylval.str); 260 yylval.val = EACL_ENTRY_ERROR; 261 } 262 return (ERROR); 263 } 264 <PS>read_data/[:/,] { 265 yylval.val = ACE_READ_DATA; 266 return (ACE_PERM); 267 } 268 <PS>list_directory/[:/,] { 269 yylval.val = ACE_LIST_DIRECTORY; 270 return (ACE_PERM); 271 } 272 <PS>write_data/[:/,] { 273 yylval.val = ACE_WRITE_DATA; 274 return (ACE_PERM); 275 } 276 <PS>add_file/[:/,] { 277 yylval.val = ACE_ADD_FILE; 278 return (ACE_PERM); 279 } 280 <PS>append_data/[:/,] { 281 yylval.val = ACE_APPEND_DATA; 282 return (ACE_PERM); 283 } 284 <PS>add_subdirectory/[:/,] { 285 yylval.val = ACE_ADD_SUBDIRECTORY; 286 return (ACE_PERM); 287 } 288 <PS>read_xattr/[:/,] { 289 yylval.val = ACE_READ_NAMED_ATTRS; 290 return (ACE_PERM); 291 } 292 <PS>write_xattr/[:/,] { 293 yylval.val = ACE_WRITE_NAMED_ATTRS; 294 return (ACE_PERM); 295 } 296 <PS>execute/[:/,] { 297 yylval.val = ACE_EXECUTE; 298 return (ACE_PERM); 299 } 300 <PS>delete_child/[:/,] { 301 yylval.val = ACE_DELETE_CHILD; 302 return (ACE_PERM); 303 } 304 <PS>read_attributes/[:/,] { 305 yylval.val = ACE_READ_ATTRIBUTES; 306 return (ACE_PERM); 307 } 308 <PS>write_attributes/[:/,] { 309 yylval.val = ACE_WRITE_ATTRIBUTES; 310 return (ACE_PERM); 311 } 312 <PS>delete/[:/,] { 313 yylval.val = ACE_DELETE; 314 return (ACE_PERM); 315 } 316 <PS>read_acl/[:/,] { 317 yylval.val = ACE_READ_ACL; 318 return (ACE_PERM); 319 } 320 <PS>write_acl/[:/,] { 321 yylval.val = ACE_WRITE_ACL; 322 return (ACE_PERM); 323 } 324 <PS>write_owner/[:/,] { 325 yylval.val = ACE_WRITE_OWNER; 326 return (ACE_PERM); 327 } 328 <PS>synchronize/[:/,] { 329 yylval.val = ACE_SYNCHRONIZE; 330 return (ACE_PERM); 331 } 332 <PS>read_set/[:/,] { 333 yylval.val = ACE_READ_PERMS; 334 return (ACE_PERM); 335 } 336 <PS>write_set/[:/,] { 337 yylval.val = ACE_WRITE_PERMS; 338 return (ACE_PERM); 339 } 340 <PS>modify_set/[:/,] { 341 yylval.val = ACE_MODIFY_PERMS; 342 return (ACE_PERM); 343 } 344 <PS>full_set/[:/,] { 345 yylval.val = ACE_ALL_PERMS; 346 return (ACE_PERM); 347 } 348 <PS>{PERM_STR}/[:,\n] { 349 int c; 350 351 c = input(); 352 unput(c); 353 yylval.str = strdup(yytext); 354 if (yylval.str == NULL) { 355 yylval.val = EACL_MEM_ERROR; 356 return (ERROR); 357 } 358 yystrings.y_perms = yylval.str; 359 360 /* 361 * aclent are done after permissions. 362 */ 363 if (isdigit(c)) 364 BEGIN US; 365 else if (c != ':') 366 BEGIN ES; 367 368 return (PERM_TOK); 369 } 370 <PS>"/:" { 371 acl_error(dgettext(TEXT_DOMAIN, 372 "Invalid permission /: specified.\n")); 373 yylval.val = EACL_ENTRY_ERROR; 374 return (ERROR); 375 } 376 <PS>: { 377 int c; 378 379 c = input(); 380 unput(c); 381 if (isdigit(c)) 382 BEGIN (US); 383 else 384 BEGIN AIS; 385 return (COLON); 386 } 387 <PS>"/" { 388 return (SLASH); 389 } 390 <PS>"\n" { 391 acl_error(dgettext(TEXT_DOMAIN, 392 "ACL entry is missing " 393 "permission fields.\n")); 394 yylval.val = EACL_MISSING_FIELDS; 395 return (ERROR); 396 } 397 <PS>"," { 398 acl_error( 399 dgettext(TEXT_DOMAIN, 400 "The ',' is not a valid permission field " 401 "separator.\nThe comma is used to separate " 402 "access control entries.\nSee acl(7) for " 403 "examples of specifying ACL entries.\n")); 404 yylval.val = EACL_PERM_MASK_ERROR; 405 return (ERROR); 406 } 407 <PS>. { 408 if (grab_string("/:,\n") != 0) { 409 acl_error(dgettext(TEXT_DOMAIN, 410 "Failed to retrieve" 411 " error string.\n")); 412 yylval.val = EACL_MEM_ERROR; 413 return (ERROR); 414 } 415 acl_error(dgettext(TEXT_DOMAIN, 416 "Invalid permission(s) '%s' " 417 "specified.\n"), yylval.str); 418 free(yylval.str); 419 yylval.val = EACL_PERM_MASK_ERROR; 420 return (ERROR); 421 } 422 <AS>allow/[:,\n] { 423 424 int c; 425 426 c = input(); 427 unput(c); 428 if (c == ',' || c == '\n') 429 BEGIN ES; 430 else 431 BEGIN US; 432 yylval.val = ACE_ACCESS_ALLOWED_ACE_TYPE; 433 return (ACCESS_TYPE); 434 } 435 <AS>deny/[:,\n] { 436 437 int c; 438 439 c = input(); 440 unput(c); 441 if (c == ',' || c == '\n') 442 BEGIN ES; 443 else 444 BEGIN US; 445 446 yylval.val = ACE_ACCESS_DENIED_ACE_TYPE; 447 return (ACCESS_TYPE); 448 } 449 <AS>audit/[:,\n] { 450 int c; 451 452 c = input(); 453 unput(c); 454 if (c == ',' || c == '\n') 455 BEGIN ES; 456 else 457 BEGIN US; 458 459 yylval.val = ACE_SYSTEM_AUDIT_ACE_TYPE; 460 return (ACCESS_TYPE); 461 } 462 <AS>alarm/[:,\n] { 463 int c; 464 465 c = input(); 466 unput(c); 467 if (c == ',' || c == '\n') 468 BEGIN ES; 469 else 470 BEGIN US; 471 472 yylval.val = ACE_SYSTEM_ALARM_ACE_TYPE; 473 return (ACCESS_TYPE); 474 } 475 <AS>: { 476 477 acl_error(dgettext(TEXT_DOMAIN, 478 "Invalid Access type " 479 "specified.\nThe field is blank, when" 480 " it should be either allow or deny.\n")); 481 yylval.val = EACL_INVALID_ACCESS_TYPE; 482 return (ERROR); 483 } 484 <AS>"\n" { 485 acl_error(dgettext(TEXT_DOMAIN, 486 "ACL access type must be specified.\n")); 487 yylval.val = EACL_INVALID_ACCESS_TYPE; 488 return (ERROR); 489 } 490 <AS>. { 491 if (yytext[0] != '\n' && yytext[0] != '\0') { 492 if (grab_string(":,\n") != 0) { 493 acl_error(dgettext(TEXT_DOMAIN, 494 "Failed to " 495 "retrieve error " 496 "string.\n")); 497 yylval.val = EACL_MEM_ERROR; 498 return (ERROR); 499 } 500 acl_error( 501 dgettext(TEXT_DOMAIN, 502 "Invalid access " 503 "type '%s' specified.\n"), 504 yylval.str); 505 } else { 506 acl_error( 507 dgettext(TEXT_DOMAIN, 508 "No access " 509 "type specified.\n"), yylval.str); 510 } 511 512 free(yylval.str); 513 yylval.val = EACL_INVALID_ACCESS_TYPE; 514 return (ERROR); 515 } 516 <AIS>allow/[:,\n] { 517 518 int c; 519 520 c = input(); 521 unput(c); 522 if (c == ',' || c == '\n') 523 BEGIN ES; 524 else 525 BEGIN US; 526 yylval.val = ACE_ACCESS_ALLOWED_ACE_TYPE; 527 return (ACCESS_TYPE); 528 } 529 <AIS>deny/[:,\n] { 530 531 int c; 532 533 c = input(); 534 unput(c); 535 if (c == ',' || c == '\n') 536 BEGIN ES; 537 else 538 BEGIN US; 539 540 yylval.val = ACE_ACCESS_DENIED_ACE_TYPE; 541 return (ACCESS_TYPE); 542 } 543 <AIS>audit/[:,\n] { 544 int c; 545 546 c = input(); 547 unput(c); 548 if (c == ',' || c == '\n') 549 BEGIN ES; 550 else 551 BEGIN US; 552 553 yylval.val = ACE_SYSTEM_AUDIT_ACE_TYPE; 554 return (ACCESS_TYPE); 555 } 556 <AIS>alarm/[:,\n] { 557 558 int c; 559 560 c = input(); 561 unput(c); 562 if (c == ',' || c == '\n') 563 BEGIN ES; 564 else 565 BEGIN US; 566 567 yylval.val = ACE_SYSTEM_ALARM_ACE_TYPE; 568 return (ACCESS_TYPE); 569 } 570 <AIS>file_inherit/[:/,] { 571 yylval.val = ACE_FILE_INHERIT_ACE; 572 return (ACE_INHERIT); 573 } 574 <AIS>dir_inherit/[:/,] { 575 yylval.val = ACE_DIRECTORY_INHERIT_ACE; 576 return (ACE_INHERIT); 577 } 578 <AIS>no_propagate/[/:,] { 579 yylval.val = ACE_NO_PROPAGATE_INHERIT_ACE; 580 return (ACE_INHERIT); 581 } 582 <AIS>inherit_only/[/:,] { 583 yylval.val = ACE_INHERIT_ONLY_ACE; 584 return (ACE_INHERIT); 585 } 586 587 <AIS>successful_access/[/:,] { 588 yylval.val = ACE_SUCCESSFUL_ACCESS_ACE_FLAG; 589 return (ACE_INHERIT); 590 } 591 <AIS>failed_access/[/:,] { 592 yylval.val = ACE_FAILED_ACCESS_ACE_FLAG; 593 return (ACE_INHERIT); 594 } 595 <AIS>inherited/[/:,] { 596 yylval.val = ACE_INHERITED_ACE; 597 return (ACE_INHERIT); 598 } 599 <AIS>{INHERIT_STR}/[:] { 600 yylval.str = strdup(yytext); 601 if (yylval.str == NULL) { 602 yylval.val = EACL_MEM_ERROR; 603 return (ERROR); 604 } 605 yystrings.y_iflags = yylval.str; 606 return (INHERIT_TOK); 607 } 608 <AIS>: { 609 /* 610 * Only inheritance fields should hit this. 611 * allow/deny fields match on ":" as part 612 * of the regexp. 613 */ 614 BEGIN AS; 615 return (COLON); 616 } 617 <AIS>"/" { 618 return (SLASH); 619 } 620 <AIS>"\n" { 621 acl_error( 622 dgettext(TEXT_DOMAIN, 623 "Invalid ACL specification." 624 "\nWas expecting to find" 625 " access type or inheritance flags.\n"), 626 yylval.str); 627 yylval.val = EACL_UNKNOWN_DATA; 628 return (ERROR); 629 } 630 <AIS>"," { 631 acl_error( 632 dgettext(TEXT_DOMAIN, 633 "The ',' is not a valid inheritance field " 634 "separator.\nThe comma is used to separate " 635 "access control entries.\nSee acl(7) for " 636 "examples of specifying ACL entries.\n")); 637 yylval.val = EACL_INVALID_ACCESS_TYPE; 638 return (ERROR); 639 } 640 <AIS>. { 641 if (yytext[0] != '\n' && yytext[0] != '\0') { 642 if (grab_string(":,\n") != 0) { 643 acl_error(dgettext(TEXT_DOMAIN, 644 "Failed to " 645 "retrieve error " 646 "string.\n")); 647 yylval.val = EACL_MEM_ERROR; 648 return (ERROR); 649 } 650 acl_error( 651 dgettext(TEXT_DOMAIN, 652 "Invalid inheritance or" 653 " access type '%s' specified.\n"), 654 yylval.str); 655 } else { 656 acl_error( 657 dgettext(TEXT_DOMAIN, 658 "No inheritance or " 659 "access type specified.\n"), 660 yylval.str); 661 } 662 663 free(yylval.str); 664 yylval.val = EACL_INVALID_ACCESS_TYPE; 665 return (ERROR); 666 } 667 <US>{ID}/[,\n] { 668 BEGIN ES; 669 yylval.str = strdup(yytext); 670 if (yylval.str == NULL) { 671 yylval.val = EACL_MEM_ERROR; 672 return (ERROR); 673 } 674 yystrings.y_idstr = yylval.str; 675 return (ID); 676 } 677 <US>{SID}/[,\n] { 678 BEGIN ES; 679 yylval.str = strdup(yytext); 680 if (yylval.str == NULL) { 681 yylval.val = EACL_MEM_ERROR; 682 return (ERROR); 683 } 684 yystrings.y_idstr = yylval.str; 685 return (SID); 686 } 687 <US>: { 688 return (COLON); 689 } 690 <US>{INHERIT_STR} { /* 691 * Catch specific error to produce 692 * nice message for users who are trying 693 * to use old syntax format which had 694 * inheritance flags as the last field. 695 */ 696 acl_error(dgettext(TEXT_DOMAIN, 697 "Access type should be final" 698 " field in ACL specification.\n")); 699 yylval.val = EACL_ENTRY_ERROR; 700 return (ERROR); 701 } 702 <US>. { 703 if (grab_string(",\n") != 0) { 704 acl_error(dgettext(TEXT_DOMAIN, 705 "Failed to retrieve" 706 " error string.\n")); 707 yylval.val = EACL_MEM_ERROR; 708 return (ERROR); 709 } 710 acl_error( 711 dgettext(TEXT_DOMAIN, 712 "Invalid data ':%s' specified" 713 " on end of ACL.\n"), yylval.str); 714 free(yylval.str); 715 yylval.val = EACL_ENTRY_ERROR; 716 return (ERROR); 717 } 718 <US>"\n" { 719 acl_error(dgettext(TEXT_DOMAIN, 720 "Missing fields in ACL " 721 "specification.\nWas expecting to find " 722 "uid/gid.\n")); 723 yylval.val = EACL_ENTRY_ERROR; 724 return (ERROR); 725 } 726 <ES>"," { 727 BEGIN TS; 728 return (COMMA); 729 } 730 <ES>. { 731 if (grab_string("/:,\n") != 0) { 732 acl_error( 733 dgettext(TEXT_DOMAIN, 734 "Failed to retrieve error" 735 " string.\n")); 736 yylval.val = EACL_MEM_ERROR; 737 return (ERROR); 738 } 739 acl_error( 740 dgettext(TEXT_DOMAIN, 741 "Unrecognized data '%s' found" 742 " in ACL specification.\n"), yylval.str); 743 free(yylval.str); 744 yylval.val = EACL_UNKNOWN_DATA; 745 return (ERROR); 746 } 747 <ES>"\n" { 748 return (NL); 749 } 750 %% 751 752 753 /* 754 * Pull string up to terminator off of input string. 755 * used for retrieving illegal data in ACL specification. 756 * 757 * The first set of characters is retrieved from yytext. 758 * subsequent characters are pulled from the input stream, 759 * until either EOF or one of the requested terminators is scene. 760 * Result is returned in yylval.str which is malloced. 761 */ 762 int 763 grab_string(char *terminators) 764 { 765 int c; 766 int done = 0; 767 int cnt; 768 int alloced; 769 int error = 0; 770 char *ptr; 771 772 cnt = strlen(yytext); 773 yylval.str = calloc(cnt + 1, sizeof (char)); 774 if (yylval.str == NULL) { 775 return (1); 776 } 777 alloced = cnt + 1; 778 strcpy(yylval.str, yytext); 779 780 do { 781 c = input(); 782 if (c == EOF) 783 break; 784 785 for (ptr = terminators; *ptr; ptr++) { 786 if (c == *ptr) { 787 done = 1; 788 break; 789 } 790 } 791 792 if (done) 793 break; 794 795 if (cnt + 1 >= alloced) { 796 yylval.str = realloc(yylval.str, 797 alloced + 80); 798 alloced += 80; 799 if (yylval.str == NULL) 800 return (1); 801 802 memset(yylval.str + cnt, 0, 803 alloced - strlen(yylval.str)); 804 } 805 yylval.str[strlen(yylval.str)] = c; 806 cnt++; 807 } while (!done); 808 809 return (error); 810 } 811 812 static int 813 input(void) 814 { 815 int c; 816 817 c = yybuf[yybufpos++]; 818 if (c == '\0') { 819 return (EOF); 820 } 821 822 return (c); 823 } 824 825 static void 826 unput(int c) 827 { 828 if (c == '\0') { 829 return; 830 } 831 832 if (yybufpos > 0) { 833 --yybufpos; 834 } 835 } 836 837 static int sid_isuser = 0; 838 839 /* 840 * return ACE entry type 841 */ 842 int 843 ace_entry_type(int type) 844 { 845 int ret = -1; 846 switch (type) { 847 case BARE_SID_TOK: 848 if (sid_isuser == 0) 849 ret = ACE_IDENTIFIER_GROUP; 850 else 851 ret = 0; 852 break; 853 case USER_TOK: 854 case USER_SID_TOK: 855 ret = 0; 856 break; 857 case GROUP_TOK: 858 case GROUP_SID_TOK: 859 ret = ACE_IDENTIFIER_GROUP; 860 break; 861 case OWNERAT_TOK: 862 ret = ACE_OWNER; 863 break; 864 case GROUPAT_TOK: 865 ret = ACE_IDENTIFIER_GROUP | ACE_GROUP; 866 break; 867 case EVERYONEAT_TOK: 868 ret = ACE_EVERYONE; 869 break; 870 } 871 return (ret); 872 } 873 874 875 /* 876 * return aclent entry type 877 */ 878 int 879 aclent_entry_type(int type, int owning, int *ret) 880 { 881 882 *ret = 0; 883 884 switch (type) { 885 case USER_TOK: 886 *ret = (owning == 0) ? USER : USER_OBJ; 887 break; 888 case GROUP_TOK: 889 *ret = (owning == 0) ? GROUP : GROUP_OBJ; 890 break; 891 case OTHER_TOK: 892 *ret = OTHER_OBJ; 893 break; 894 case MASK_TOK: 895 *ret = CLASS_OBJ; 896 break; 897 case DEFAULT_USER_TOK: 898 *ret = (owning == 0) ? DEF_USER : DEF_USER_OBJ; 899 break; 900 case DEFAULT_GROUP_TOK: 901 *ret = (owning == 0) ? DEF_GROUP : DEF_GROUP_OBJ; 902 break; 903 case DEFAULT_MASK_TOK: 904 *ret = DEF_CLASS_OBJ; 905 break; 906 case DEFAULT_OTHER_TOK: 907 *ret = DEF_OTHER_OBJ; 908 break; 909 default: 910 return (EACL_ENTRY_ERROR); 911 } 912 913 return (0); 914 } 915 916 /* 917 * convert string into numeric id. 918 */ 919 static int 920 acl_str_to_id(char *str, uid_t *id) 921 { 922 char *end; 923 uid_t value; 924 925 errno = 0; 926 value = strtoul(str, &end, 10); 927 928 if (errno != 0 || *end != '\0') 929 return (EACL_INVALID_USER_GROUP); 930 931 *id = value; 932 933 return (0); 934 } 935 936 /* 937 * determine either uid/gid for given entry type 938 */ 939 int 940 get_id(int entry_type, char *name, uid_t *id) 941 { 942 struct passwd *pw; 943 struct group *gr; 944 int error = 0; 945 946 switch (entry_type) { 947 case USER_TOK: 948 case DEFAULT_USER_TOK: 949 if ((error = acl_str_to_id(name, id)) == 0) 950 break; 951 pw = getpwnam(name); 952 if (pw) { 953 *id = pw->pw_uid; 954 error = 0; 955 } 956 break; 957 958 case GROUP_TOK: 959 case DEFAULT_GROUP_TOK: 960 if ((error = acl_str_to_id(name, id)) == 0) 961 break; 962 gr = getgrnam(name); 963 if (gr) { 964 *id = gr->gr_gid; 965 error = 0; 966 } 967 break; 968 case USER_SID_TOK: 969 if (sid_to_id(name, B_TRUE, id)) 970 error = EACL_INVALID_USER_GROUP; 971 break; 972 973 case GROUP_SID_TOK: 974 if (sid_to_id(name, B_FALSE, id)) 975 error = EACL_INVALID_USER_GROUP; 976 break; 977 978 case BARE_SID_TOK: 979 if (sid_to_xid(name, &sid_isuser, id)) 980 error = EACL_INVALID_USER_GROUP; 981 break; 982 } 983 984 return (error); 985 } 986 987 int 988 get_id_nofail(int entry_type, char *name) 989 { 990 uid_t id; 991 992 if (get_id(entry_type, name, &id)) 993 return (UID_NOBODY); 994 else 995 return (id); 996 } 997 998 /* 999 * reset beginning state to TS and set character position 1000 * back to zero. 1001 */ 1002 void 1003 yyreset() 1004 { 1005 yybufpos = 0; 1006 memset(&yystrings, 0, sizeof (yystrings)); 1007 BEGIN TS; 1008 } 1009 1010 void 1011 yycleanup() 1012 { 1013 if (yystrings.y_logname) 1014 free(yystrings.y_logname); 1015 if (yystrings.y_perms) 1016 free(yystrings.y_perms); 1017 if (yystrings.y_iflags) 1018 free(yystrings.y_iflags); 1019 if (yystrings.y_idstr) 1020 free(yystrings.y_idstr); 1021 yystrings.y_logname = NULL; 1022 yystrings.y_perms = NULL; 1023 yystrings.y_iflags = NULL; 1024 yystrings.y_idstr = NULL; 1025 } 1026