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