xref: /illumos-gate/usr/src/lib/libsec/common/acl_lex.l (revision 4abb96737d15cd2d6530b0aa7b8404ec911ad940)
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 2006 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 %s TS NS PS AIS AS US ES
63 /*
64  * TS = type state
65  * NS = name state
66  * PS = Permission state
67  * AIS = Allow/deny/inheritance state
68  * AS = Allow state (only used when inheritance detected)
69  * US = UID/GID state
70  * ES = End state
71  */
72 
73 ID	[1-9][0-9]*
74 LOGNAME [a-z0-9A-Z]+:
75 BADLOGNAME [a-z0-9A-Z]+
76 PERM_STR [rRwWxpdDaAcCos-]+
77 INHERIT_STR [fdinFS-]+
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>{BADLOGNAME}	{
209 				acl_error(dgettext(TEXT_DOMAIN,
210 				    "Missing fields after "
211 				    "user/group '%s'.\n"), yytext);
212 				yylval.val = EACL_MISSING_FIELDS;
213 				return (ERROR);
214 			}
215 <NS>"\n"		{
216 				acl_error(dgettext(TEXT_DOMAIN,
217 				    "Missing user/group name"
218 				    " from ACL specification.\n"));
219 				yylval.val = EACL_MISSING_FIELDS;
220 				return (ERROR);
221 			}
222 <NS>.			{
223 				int error;
224 
225 				error = grab_string(":,\n");
226 				if (error != 0) {
227 					acl_error(dgettext(TEXT_DOMAIN,
228 					    "Invalid user/group "
229 					    "name specification.\n"));
230 					yylval.val = EACL_INVALID_USER_GROUP;
231 				} else {
232 					acl_error(dgettext(TEXT_DOMAIN,
233 					    "User/Group name "
234 					    "'%s' not specified correctly.\n"),
235 					    yylval.str);
236 					free(yylval.str);
237 					yylval.val = EACL_ENTRY_ERROR;
238 				}
239 				return (ERROR);
240 			}
241 <PS>read_data/[:/]	{
242 				yylval.val = ACE_READ_DATA;
243 				return (ACE_PERM);
244 			}
245 <PS>list_directory/[:/] {
246 				yylval.val = ACE_LIST_DIRECTORY;
247 			 	return (ACE_PERM);
248 			}
249 <PS>write_data/[:/]	{
250 				yylval.val = ACE_WRITE_DATA;
251 				return (ACE_PERM);
252 			}
253 <PS>add_file/[:/]	{
254 				yylval.val = ACE_ADD_FILE;
255 				return (ACE_PERM);
256 			}
257 <PS>append_data/[:/]	{
258 				yylval.val = ACE_APPEND_DATA;
259 				return (ACE_PERM);
260 			}
261 <PS>add_subdirectory/[:/] {
262 				yylval.val = ACE_ADD_SUBDIRECTORY;
263 				return (ACE_PERM);
264 			}
265 <PS>read_xattr/[:/]	{
266 				yylval.val = ACE_READ_NAMED_ATTRS;
267 				return (ACE_PERM);
268 			}
269 <PS>write_xattr/[:/]	{
270 				yylval.val = ACE_WRITE_NAMED_ATTRS;
271 				return (ACE_PERM);
272 			}
273 <PS>execute/[:/]	{
274 				yylval.val = ACE_EXECUTE;
275 				return (ACE_PERM);
276 			}
277 <PS>delete_child/[:/]	{
278 				yylval.val = ACE_DELETE_CHILD;
279 				return (ACE_PERM);
280 			}
281 <PS>read_attributes/[:/] {
282 				yylval.val = ACE_READ_ATTRIBUTES;
283 				return (ACE_PERM);
284 			}
285 <PS>write_attributes/[:/] {
286 				yylval.val = ACE_WRITE_ATTRIBUTES;
287 			 	return (ACE_PERM);
288 			}
289 <PS>delete/[:/]		{
290 				yylval.val = ACE_DELETE;
291 				return (ACE_PERM);
292 			}
293 <PS>read_acl/[:/]	{
294 				yylval.val = ACE_READ_ACL;
295 				return (ACE_PERM);
296 			}
297 <PS>write_acl/[:/]	{
298 				yylval.val = ACE_WRITE_ACL;
299 				return (ACE_PERM);
300 			}
301 <PS>write_owner/[:/]	{
302 				yylval.val = ACE_WRITE_OWNER;
303 				return (ACE_PERM);
304 			}
305 <PS>synchronize/[:/]	{
306 				yylval.val = ACE_SYNCHRONIZE;
307 				return (ACE_PERM);
308 			}
309 <PS>{PERM_STR}/[:,\n]	{
310 				int c;
311 
312 				c = input();
313 				unput(c);
314 				yylval.str = strdup(yytext);
315 				if (yylval.str == NULL) {
316 					yylval.val = EACL_MEM_ERROR;
317 					return (ERROR);
318 				}
319 
320 				/*
321 				 * aclent are done after permissions.
322 				 */
323 				if (isdigit(c))
324 					BEGIN US;
325 				else if (c != ':')
326 					BEGIN ES;
327 
328 				return (PERM_TOK);
329 			}
330 <PS>"/:"		{
331 				acl_error(dgettext(TEXT_DOMAIN,
332 				    "Invalid permission /: specified.\n"));
333 				yylval.val = EACL_ENTRY_ERROR;
334 				return (ERROR);
335 			}
336 <PS>:			{
337 				int c;
338 
339 				c = input();
340 				unput(c);
341 				if (isdigit(c))
342 					BEGIN (US);
343 				else
344 					BEGIN AIS;
345 				return (COLON);
346 			}
347 <PS>"/"			{
348 				return (SLASH);
349 			}
350 <PS>"\n"		{
351 				acl_error(dgettext(TEXT_DOMAIN,
352 				    "ACL entry is missing "
353 				    "permission fields.\n"));
354 				yylval.val = EACL_MISSING_FIELDS;
355 				return (ERROR);
356 			}
357 <PS>. 			{
358 				if (grab_string("/:,\n") != 0) {
359 					acl_error(dgettext(TEXT_DOMAIN,
360 					    "Failed to retrieve"
361 					    " error string.\n"));
362 					yylval.val = EACL_MEM_ERROR;
363 					return (ERROR);
364 				}
365 				acl_error(dgettext(TEXT_DOMAIN,
366 				    "Invalid permission(s) '%s' "
367 				    "specified.\n"), yylval.str);
368 				free(yylval.str);
369 				yylval.val = EACL_PERM_MASK_ERROR;
370 				return (ERROR);
371 			}
372 <AS>allow/[:,\n]	{
373 
374 				int c;
375 
376 				c = input();
377 				unput(c);
378 				if (c == ',' || c == '\n')
379 					BEGIN ES;
380 				else
381 					BEGIN US;
382 				yylval.val = ACE_ACCESS_ALLOWED_ACE_TYPE;
383 				return (ACCESS_TYPE);
384 			}
385 <AS>deny/[:,\n]		{
386 
387 				int c;
388 
389 				c = input();
390 				unput(c);
391 				if (c == ',' || c == '\n')
392 					BEGIN ES;
393 				else
394 					BEGIN US;
395 
396 				yylval.val = ACE_ACCESS_DENIED_ACE_TYPE;
397 				return (ACCESS_TYPE);
398 			}
399 <AS>:			{
400 
401 				acl_error(dgettext(TEXT_DOMAIN,
402 				    "Invalid Access type "
403 				    "specified.\nThe field is blank, when"
404 				    " it should be either allow or deny.\n"));
405 				yylval.val = EACL_INVALID_ACCESS_TYPE;
406 				return (ERROR);
407 			}
408 <AS>"\n"		{
409 				acl_error(dgettext(TEXT_DOMAIN,
410 				    "ACL access type must be specified.\n"));
411 				yylval.val = EACL_INVALID_ACCESS_TYPE;
412 				return (ERROR);
413 			}
414 <AS>.			{
415 				if (yytext[0] != '\n' && yytext[0] != '\0') {
416 					if (grab_string(":,\n") != 0) {
417 						acl_error(dgettext(TEXT_DOMAIN,
418 						    "Failed to "
419 						    "retrieve error "
420 						    "string.\n"));
421 						yylval.val = EACL_MEM_ERROR;
422 						return (ERROR);
423 					}
424 					acl_error(
425 					    dgettext(TEXT_DOMAIN,
426 					    "Invalid access "
427 					    "type '%s' specified.\n"),
428 					    yylval.str);
429 				} else {
430 					acl_error(
431 					    dgettext(TEXT_DOMAIN,
432 					    "No access "
433 					    "type specified.\n"), yylval.str);
434 				}
435 
436 				free(yylval.str);
437 				yylval.val = EACL_INVALID_ACCESS_TYPE;
438 				return (ERROR);
439 			}
440 <AIS>allow/[:,\n]	{
441 
442 				int c;
443 
444 				c = input();
445 				unput(c);
446 				if (c == ',' || c == '\n')
447 					BEGIN ES;
448 				else
449 					BEGIN US;
450 				yylval.val = ACE_ACCESS_ALLOWED_ACE_TYPE;
451 				return (ACCESS_TYPE);
452 			}
453 <AIS>deny/[:,\n]	{
454 
455 				int c;
456 
457 				c = input();
458 				unput(c);
459 				if (c == ',' || c == '\n')
460 					BEGIN ES;
461 				else
462 					BEGIN US;
463 
464 				yylval.val = ACE_ACCESS_DENIED_ACE_TYPE;
465 				return (ACCESS_TYPE);
466 			}
467 <AIS>file_inherit/[:/] {
468 				yylval.val = ACE_FILE_INHERIT_ACE;
469 				return (ACE_INHERIT);
470 			}
471 <AIS>dir_inherit/[:/]	{
472 				yylval.val = ACE_DIRECTORY_INHERIT_ACE;
473 				return (ACE_INHERIT);
474 			}
475 <AIS>no_propagate/[/:]	{
476 				yylval.val = ACE_NO_PROPAGATE_INHERIT_ACE;
477 				return (ACE_INHERIT);
478 			}
479 <AIS>inherit_only/[/:]	{
480 				yylval.val = ACE_INHERIT_ONLY_ACE;
481 				return (ACE_INHERIT);
482 			}
483 <AIS>{INHERIT_STR}/[:]	{
484 				yylval.str = strdup(yytext);
485 				if (yylval.str == NULL) {
486 					yylval.val = EACL_MEM_ERROR;
487 					return (ERROR);
488 				}
489 				return (INHERIT_TOK);
490 			}
491 <AIS>:			{
492 				/*
493 				 * Only inheritance fields should hit this.
494 				 * allow/deny fields match on ":" as part
495 				 * of the regexp.
496 				 */
497 				BEGIN AS;
498 				return (COLON);
499 			}
500 <AIS>"/"		{
501 				return (SLASH);
502 			}
503 <AIS>"\n"		{
504 				acl_error(
505 				    dgettext(TEXT_DOMAIN,
506 				    "Invalid ACL specification."
507 				    "\nWas expecting to find"
508 				    " access type or inheritance flags.\n"),
509 				    yylval.str);
510 				yylval.val = EACL_UNKNOWN_DATA;
511 				return (ERROR);
512 			}
513 <AIS>.			{
514 				if (yytext[0] != '\n' && yytext[0] != '\0') {
515 					if (grab_string(":,\n") != 0) {
516 						acl_error(dgettext(TEXT_DOMAIN,
517 						    "Failed to "
518 						    "retrieve error "
519 						    "string.\n"));
520 						yylval.val = EACL_MEM_ERROR;
521 						return (ERROR);
522 					}
523 					acl_error(
524 					    dgettext(TEXT_DOMAIN,
525 					    "Invalid inheritance or"
526 				    	    " access type '%s' specified.\n"),
527 				    	    yylval.str);
528 				} else {
529 					acl_error(
530 					    dgettext(TEXT_DOMAIN,
531 					    "No inheritance or "
532 					    "access type specified.\n"),
533 					    yylval.str);
534 				}
535 
536 				free(yylval.str);
537 				yylval.val = EACL_INVALID_ACCESS_TYPE;
538 				return (ERROR);
539 			}
540 <US>{ID}/[,\n]		{
541 				BEGIN ES;
542 				yylval.val = atoi(yytext);
543 				return (ID);
544 			}
545 <US>:			{
546 				return (COLON);
547 			}
548 <US>{INHERIT_STR}	{	/*
549 				 * Catch specific error to produce
550 				 * nice message for users who are trying
551 				 * to use old syntax format which had
552 				 * inheritance flags as the last field.
553 				 */
554 				acl_error(dgettext(TEXT_DOMAIN,
555 				    "Access type should be final"
556 				    " field in ACL specification.\n"));
557 				yylval.val = EACL_ENTRY_ERROR;
558 				return (ERROR);
559 			}
560 <US>.			{
561 				if (grab_string(",\n") != 0) {
562 					acl_error(dgettext(TEXT_DOMAIN,
563 					    "Failed to retrieve"
564 					    " error string.\n"));
565 					yylval.val = EACL_MEM_ERROR;
566 					return (ERROR);
567 				}
568 				acl_error(
569 				    dgettext(TEXT_DOMAIN,
570 				    "Invalid data ':%s' specified"
571 				    " on end of ACL.\n"), yylval.str);
572 				free(yylval.str);
573 				yylval.val = EACL_ENTRY_ERROR;
574 				return (ERROR);
575 			}
576 <US>"\n"		{
577 				acl_error(dgettext(TEXT_DOMAIN,
578 				    "Missing fields in ACL "
579 				    "specification.\nWas expecting to find "
580 				    "uid/gid.\n"));
581 				yylval.val = EACL_ENTRY_ERROR;
582 				return (ERROR);
583 			}
584 <ES>","			{
585 				BEGIN TS;
586 				return (COMMA);
587 			}
588 <ES>.			{
589 				if (grab_string("/:,\n") != 0) {
590 					acl_error(
591 					    dgettext(TEXT_DOMAIN,
592 					    "Failed to retrieve error"
593 				    	    " string.\n"));
594 					yylval.val = EACL_MEM_ERROR;
595 					return (ERROR);
596 				}
597 				acl_error(
598 				    dgettext(TEXT_DOMAIN,
599 				    "Unrecognized data '%s' found"
600 			    	    " in ACL specification.\n"), yylval.str);
601 				free(yylval.str);
602 				yylval.val = EACL_UNKNOWN_DATA;
603 				return (ERROR);
604 			}
605 <ES>"\n"		{
606 				return (NL);
607 			}
608 %%
609 
610 
611 /*
612  * Pull string up to terminator off of input string.
613  * used for retrieving illegal data in ACL specification.
614  *
615  * The first set of characters is retrieved from yytext.
616  * subseequent characters are pulled from the input stream,
617  * until either EOF or one of the requested terminators is scene.
618  * Result is returned in yylval.str which is malloced.
619  */
620 int
621 grab_string(char *terminators)
622 {
623 		int c;
624 		int done = 0;
625 		int cnt;
626 		int alloced;
627 		int error = 0;
628 		char *ptr;
629 
630 		cnt = strlen(yytext);
631 		yylval.str = calloc(cnt + 1, sizeof (char));
632 		if (yylval.str == NULL) {
633 			return (1);
634 		}
635 		alloced = cnt + 1;
636 		strcpy(yylval.str, yytext);
637 
638 		do {
639 			c = input();
640 			if (c == EOF)
641 				break;
642 
643 			for (ptr = terminators; *ptr; ptr++) {
644 				if (c == *ptr) {
645 					done = 1;
646 					break;
647 				}
648 			}
649 
650 			if (done)
651 				break;
652 
653 			if (cnt + 1 >= alloced) {
654 				yylval.str = realloc(yylval.str,
655 				    alloced + 80);
656 					alloced += 80;
657 				if (yylval.str == NULL)
658 					return (1);
659 
660 				memset(yylval.str + cnt, 0,
661 				    alloced - strlen(yylval.str));
662 			}
663 			yylval.str[strlen(yylval.str)] = c;
664 			cnt++;
665 		} while (!done);
666 
667 		return (error);
668 }
669 
670 static int
671 input(void)
672 {
673 	int c;
674 
675 	c = yybuf[yybufpos++];
676 	if (c == '\0') {
677 		return (EOF);
678 	}
679 
680 	return (c);
681 }
682 
683 static void
684 unput(int c)
685 {
686 	if (c == '\0') {
687 		return;
688 	}
689 
690 	if (yybufpos > 0) {
691 		--yybufpos;
692 	}
693 }
694 
695 /*
696  * return ACE entry type
697  */
698 int
699 ace_entry_type(int type)
700 {
701 	int ret = -1;
702 	switch (type) {
703 		case USER_TOK:
704 			ret = 0;
705 			break;
706 		case GROUP_TOK:
707 			ret = ACE_IDENTIFIER_GROUP;
708 			break;
709 		case OWNERAT_TOK:
710 			ret = ACE_OWNER;
711 			break;
712 		case GROUPAT_TOK:
713 			ret = ACE_IDENTIFIER_GROUP | ACE_GROUP;
714 			break;
715 		case EVERYONEAT_TOK:
716 			ret = ACE_EVERYONE;
717 			break;
718 	}
719 	return (ret);
720 }
721 
722 
723 /*
724  * return aclent entry type
725  */
726 int
727 aclent_entry_type(int type, int owning, int *ret)
728 {
729 
730 	*ret = 0;
731 
732 	switch (type) {
733 	case USER_TOK:
734 		*ret = (owning == 0) ? USER : USER_OBJ;
735 		break;
736 	case GROUP_TOK:
737 		*ret = (owning == 0) ? GROUP : GROUP_OBJ;
738 		break;
739 	case OTHER_TOK:
740 		*ret = OTHER_OBJ;
741 		break;
742 	case MASK_TOK:
743 		*ret = CLASS_OBJ;
744 		break;
745 	case DEFAULT_USER_TOK:
746 		*ret = (owning == 0) ? DEF_USER : DEF_USER_OBJ;
747 		break;
748 	case DEFAULT_GROUP_TOK:
749 		*ret = (owning == 0) ? DEF_GROUP : DEF_GROUP_OBJ;
750 		break;
751 	case DEFAULT_MASK_TOK:
752 		*ret = DEF_CLASS_OBJ;
753 		break;
754 	case DEFAULT_OTHER_TOK:
755 		*ret = DEF_OTHER_OBJ;
756 		break;
757 	default:
758 		return (EACL_ENTRY_ERROR);
759 	}
760 
761 	return (0);
762 }
763 
764 /*
765  * convert string into numeric id.
766  */
767 static int
768 acl_str_to_id(char *str, int *id)
769 {
770 	char *end;
771 	uid_t value;
772 
773 	errno = 0;
774 	value = strtol(str, &end, 10);
775 
776 	if (errno != 0 || *end != '\0')
777 		return (EACL_INVALID_USER_GROUP);
778 
779 	*id = value;
780 
781 	return (0);
782 }
783 
784 /*
785  * determine either uid/gid for given entry type
786  */
787 int
788 get_id(int entry_type, char *name, int *id)
789 {
790 	struct passwd *pw;
791 	struct group *gr;
792 	int error;
793 
794 	/*
795 	 * First see if uid/gid is an all-numeric value
796 	 * otherwise, try getpwnam/getgrnam.
797 	 */
798 	error = acl_str_to_id(name, id);
799 
800 	if (error != 0) {
801 		if (entry_type == USER_TOK || entry_type == DEFAULT_USER_TOK) {
802 			pw = getpwnam(name);
803 			if (pw) {
804 				*id = pw->pw_uid;
805 				error = 0;
806 			}
807 		} else {
808 			gr = getgrnam(name);
809 			if (gr) {
810 				*id = gr->gr_gid;
811 				error = 0;
812 			}
813 		}
814 	}
815 
816 	return (error);
817 }
818 /*
819  * reset beginning state to TS and set character position
820  * back to zero.
821  */
822 void
823 yyreset()
824 {
825 	yybufpos = 0;
826 	BEGIN TS;
827 }
828 
829