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 #pragma ident "%Z%%M% %I% %E% SMI" 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 } yystrings; 69 70 %} 71 72 %e 1500 73 %s TS NS PS AIS AS US ES 74 %p 5000 75 76 /* 77 * TS = type state 78 * NS = name state 79 * PS = Permission state 80 * AIS = Allow/deny/inheritance state 81 * AS = Allow state (only used when inheritance detected) 82 * US = UID/GID state 83 * ES = End state 84 */ 85 86 ID [0-9]+ 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.val = atoi(yytext); 668 return (ID); 669 } 670 <US>: { 671 return (COLON); 672 } 673 <US>{INHERIT_STR} { /* 674 * Catch specific error to produce 675 * nice message for users who are trying 676 * to use old syntax format which had 677 * inheritance flags as the last field. 678 */ 679 acl_error(dgettext(TEXT_DOMAIN, 680 "Access type should be final" 681 " field in ACL specification.\n")); 682 yylval.val = EACL_ENTRY_ERROR; 683 return (ERROR); 684 } 685 <US>. { 686 if (grab_string(",\n") != 0) { 687 acl_error(dgettext(TEXT_DOMAIN, 688 "Failed to retrieve" 689 " error string.\n")); 690 yylval.val = EACL_MEM_ERROR; 691 return (ERROR); 692 } 693 acl_error( 694 dgettext(TEXT_DOMAIN, 695 "Invalid data ':%s' specified" 696 " on end of ACL.\n"), yylval.str); 697 free(yylval.str); 698 yylval.val = EACL_ENTRY_ERROR; 699 return (ERROR); 700 } 701 <US>"\n" { 702 acl_error(dgettext(TEXT_DOMAIN, 703 "Missing fields in ACL " 704 "specification.\nWas expecting to find " 705 "uid/gid.\n")); 706 yylval.val = EACL_ENTRY_ERROR; 707 return (ERROR); 708 } 709 <ES>"," { 710 BEGIN TS; 711 return (COMMA); 712 } 713 <ES>. { 714 if (grab_string("/:,\n") != 0) { 715 acl_error( 716 dgettext(TEXT_DOMAIN, 717 "Failed to retrieve error" 718 " string.\n")); 719 yylval.val = EACL_MEM_ERROR; 720 return (ERROR); 721 } 722 acl_error( 723 dgettext(TEXT_DOMAIN, 724 "Unrecognized data '%s' found" 725 " in ACL specification.\n"), yylval.str); 726 free(yylval.str); 727 yylval.val = EACL_UNKNOWN_DATA; 728 return (ERROR); 729 } 730 <ES>"\n" { 731 return (NL); 732 } 733 %% 734 735 736 /* 737 * Pull string up to terminator off of input string. 738 * used for retrieving illegal data in ACL specification. 739 * 740 * The first set of characters is retrieved from yytext. 741 * subsequent characters are pulled from the input stream, 742 * until either EOF or one of the requested terminators is scene. 743 * Result is returned in yylval.str which is malloced. 744 */ 745 int 746 grab_string(char *terminators) 747 { 748 int c; 749 int done = 0; 750 int cnt; 751 int alloced; 752 int error = 0; 753 char *ptr; 754 755 cnt = strlen(yytext); 756 yylval.str = calloc(cnt + 1, sizeof (char)); 757 if (yylval.str == NULL) { 758 return (1); 759 } 760 alloced = cnt + 1; 761 strcpy(yylval.str, yytext); 762 763 do { 764 c = input(); 765 if (c == EOF) 766 break; 767 768 for (ptr = terminators; *ptr; ptr++) { 769 if (c == *ptr) { 770 done = 1; 771 break; 772 } 773 } 774 775 if (done) 776 break; 777 778 if (cnt + 1 >= alloced) { 779 yylval.str = realloc(yylval.str, 780 alloced + 80); 781 alloced += 80; 782 if (yylval.str == NULL) 783 return (1); 784 785 memset(yylval.str + cnt, 0, 786 alloced - strlen(yylval.str)); 787 } 788 yylval.str[strlen(yylval.str)] = c; 789 cnt++; 790 } while (!done); 791 792 return (error); 793 } 794 795 static int 796 input(void) 797 { 798 int c; 799 800 c = yybuf[yybufpos++]; 801 if (c == '\0') { 802 return (EOF); 803 } 804 805 return (c); 806 } 807 808 static void 809 unput(int c) 810 { 811 if (c == '\0') { 812 return; 813 } 814 815 if (yybufpos > 0) { 816 --yybufpos; 817 } 818 } 819 820 /* 821 * return ACE entry type 822 */ 823 int 824 ace_entry_type(int type) 825 { 826 int ret = -1; 827 switch (type) { 828 case USER_TOK: 829 case USER_SID_TOK: 830 ret = 0; 831 break; 832 case GROUP_TOK: 833 case GROUP_SID_TOK: 834 ret = ACE_IDENTIFIER_GROUP; 835 break; 836 case OWNERAT_TOK: 837 ret = ACE_OWNER; 838 break; 839 case GROUPAT_TOK: 840 ret = ACE_IDENTIFIER_GROUP | ACE_GROUP; 841 break; 842 case EVERYONEAT_TOK: 843 ret = ACE_EVERYONE; 844 break; 845 } 846 return (ret); 847 } 848 849 850 /* 851 * return aclent entry type 852 */ 853 int 854 aclent_entry_type(int type, int owning, int *ret) 855 { 856 857 *ret = 0; 858 859 switch (type) { 860 case USER_TOK: 861 *ret = (owning == 0) ? USER : USER_OBJ; 862 break; 863 case GROUP_TOK: 864 *ret = (owning == 0) ? GROUP : GROUP_OBJ; 865 break; 866 case OTHER_TOK: 867 *ret = OTHER_OBJ; 868 break; 869 case MASK_TOK: 870 *ret = CLASS_OBJ; 871 break; 872 case DEFAULT_USER_TOK: 873 *ret = (owning == 0) ? DEF_USER : DEF_USER_OBJ; 874 break; 875 case DEFAULT_GROUP_TOK: 876 *ret = (owning == 0) ? DEF_GROUP : DEF_GROUP_OBJ; 877 break; 878 case DEFAULT_MASK_TOK: 879 *ret = DEF_CLASS_OBJ; 880 break; 881 case DEFAULT_OTHER_TOK: 882 *ret = DEF_OTHER_OBJ; 883 break; 884 default: 885 return (EACL_ENTRY_ERROR); 886 } 887 888 return (0); 889 } 890 891 /* 892 * convert string into numeric id. 893 */ 894 static int 895 acl_str_to_id(char *str, uid_t *id) 896 { 897 char *end; 898 uid_t value; 899 900 errno = 0; 901 value = strtoul(str, &end, 10); 902 903 if (errno != 0 || *end != '\0') 904 return (EACL_INVALID_USER_GROUP); 905 906 *id = value; 907 908 return (0); 909 } 910 911 /* 912 * determine either uid/gid for given entry type 913 */ 914 int 915 get_id(int entry_type, char *name, uid_t *id) 916 { 917 struct passwd *pw; 918 struct group *gr; 919 int error = 0; 920 921 switch (entry_type) { 922 case USER_TOK: 923 case DEFAULT_USER_TOK: 924 if ((error = acl_str_to_id(name, id)) == 0) 925 break; 926 pw = getpwnam(name); 927 if (pw) { 928 *id = pw->pw_uid; 929 error = 0; 930 } 931 break; 932 933 case GROUP_TOK: 934 case DEFAULT_GROUP_TOK: 935 if ((error = acl_str_to_id(name, id)) == 0) 936 break; 937 gr = getgrnam(name); 938 if (gr) { 939 *id = gr->gr_gid; 940 error = 0; 941 } 942 break; 943 case USER_SID_TOK: 944 if (sid_to_id(name, B_TRUE, id)) 945 error = EACL_INVALID_USER_GROUP; 946 break; 947 948 case GROUP_SID_TOK: 949 if (sid_to_id(name, B_FALSE, id)) 950 error = EACL_INVALID_USER_GROUP; 951 break; 952 } 953 954 return (error); 955 } 956 957 /* 958 * reset beginning state to TS and set character position 959 * back to zero. 960 */ 961 void 962 yyreset() 963 { 964 yybufpos = 0; 965 memset(&yystrings, 0, sizeof (yystrings)); 966 BEGIN TS; 967 } 968 969 void 970 yycleanup() 971 { 972 if (yystrings.y_logname) 973 free(yystrings.y_logname); 974 if (yystrings.y_perms) 975 free(yystrings.y_perms); 976 if (yystrings.y_iflags) 977 free(yystrings.y_iflags); 978 yystrings.y_logname = NULL; 979 yystrings.y_perms = NULL; 980 yystrings.y_iflags = NULL; 981 } 982