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