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
yyerror(const char * s)45 yyerror(const char *s)
46 {
47 return (0);
48 }
49
50 int
yywrap(void)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
input(void)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
unput(int c)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
ace_entry_type(int type)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
aclent_entry_type(int type,int owning,int * ret)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
acl_str_to_id(char * str,uid_t * id)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
get_id(int entry_type,char * name,uid_t * id)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
get_id_nofail(int entry_type,char * name)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
yyreset()988 yyreset()
989 {
990 yybufpos = 0;
991 memset(&yystrings, 0, sizeof (yystrings));
992 BEGIN TS;
993 }
994
995 void
yycleanup()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