8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libsec / common / acl_lex.l
blob0c388f28329acf5c5de94fd03cf296283fd9fe76
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  */
26 #include <sys/acl.h>
27 #include <aclutils.h>
28 #include <idmap.h>
29 #include <errno.h>
30 #include "acl.tab.h"
32 #ifdef input
33 #undef input
34 #endif
36 #ifdef unput
37 #undef unput
38 #endif
40 int grab_string(char *terminators);
41 static int input();
42 static void unput(int);
44 int 
45 yyerror(const char *s)
47         return (0);
50 int
51 yywrap(void)
53         return (1);
56 extern char *yybuf;
57 int yybufpos;
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;
71 %e 1500
72 %s TS NS PS AIS AS US ES
73 %p 5000
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  */
85 ID      [0-9]+
86 SID     S-[^:,\n]+
87 LOGNAME [^:]+:
88 PERM_STR [rRwWxpdDaAcCos-]+
89 INHERIT_STR [fdinFSI-]+
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;
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;
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;
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]        {
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]         {
435                                 int c;
436                                 
437                                 c = input();
438                                 unput(c);
439                                 if (c == ',' || c == '\n')
440                                         BEGIN ES;
441                                 else
442                                         BEGIN US;
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;
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;
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                                 }
510                                 free(yylval.str);
511                                 yylval.val = EACL_INVALID_ACCESS_TYPE;
512                                 return (ERROR);
513                         }
514 <AIS>allow/[:,\n]       {
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]        {
529                                 int c;
530                                 
531                                 c = input();
532                                 unput(c);
533                                 if (c == ',' || c == '\n')
534                                         BEGIN ES;
535                                 else
536                                         BEGIN US;
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;
551                                 yylval.val = ACE_SYSTEM_AUDIT_ACE_TYPE;
552                                 return (ACCESS_TYPE);
553                         }
554 <AIS>alarm/[:,\n]       {
556                                 int c;
557                                 
558                                 c = input();
559                                 unput(c);
560                                 if (c == ',' || c == '\n')
561                                         BEGIN ES;
562                                 else
563                                         BEGIN US;
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                         }
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                                 }
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                         }
752  * Pull string up to terminator off of input string.
753  * used for retrieving illegal data in ACL specification.
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  */
761 grab_string(char *terminators)
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);
778                 do {
779                         c = input();
780                         if (c == EOF) 
781                                 break;
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);
800                                 memset(yylval.str + cnt, 0,
801                                     alloced - strlen(yylval.str));
802                         }
803                         yylval.str[strlen(yylval.str)] = c;
804                         cnt++;
805                 } while (!done);
807                 return (error);
810 static int
811 input(void)
813         int c;
815         c = yybuf[yybufpos++];
816         if (c == '\0') {
817                 return (EOF);
818         }
820         return (c);     
823 static void
824 unput(int c)
826         if (c == '\0') {
827                 return;
828         }
830         if (yybufpos > 0) {
831                 --yybufpos;
832         }
836  * return ACE entry type
837  */
839 ace_entry_type(int type)
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);
866  * return aclent entry type
867  */
869 aclent_entry_type(int type, int owning, int *ret)
872         *ret = 0;
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         }
903         return (0);
907  * convert string into numeric id.
908  */
909 static int
910 acl_str_to_id(char *str, uid_t *id)
912         char *end;
913         uid_t value;
915         errno = 0;
916         value = strtoul(str, &end, 10);
918         if (errno != 0 || *end != '\0')
919                 return (EACL_INVALID_USER_GROUP);
921         *id = value;
923         return (0);
927  * determine either uid/gid for given entry type
928  */
930 get_id(int entry_type, char *name, uid_t *id)
932         struct passwd *pw;
933         struct group *gr;
934         int error = 0;
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;
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;
963         case GROUP_SID_TOK:
964                 if (sid_to_id(name, B_FALSE, id))
965                         error = EACL_INVALID_USER_GROUP;
966                 break;
967         }
969         return (error);
973 get_id_nofail(int entry_type, char *name)
975         uid_t id;
977         if (get_id(entry_type, name, &id))
978                 return (UID_NOBODY);
979         else
980                 return (id);
984  * reset beginning state to TS and set character position
985  * back to zero.
986  */
987 void
988 yyreset()
990         yybufpos = 0;
991         memset(&yystrings, 0, sizeof (yystrings));
992         BEGIN TS;
995 void
996 yycleanup()
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;