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