8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libsec / common / acl.y
blobfe3a1416052070ee3467615f22a5ea06e3fcdc5e
1 %{
2 /*
3 * CDDL HEADER START
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <acl_common.h>
27 #include <aclutils.h>
29 extern int yyinteractive;
30 extern acl_t *yyacl;
33 %union {
34 char *str;
35 int val;
36 struct acl_perm_type acl_perm;
37 ace_t ace;
38 aclent_t aclent;
39 acl_t *acl;
43 %token USER_TOK USER_SID_TOK GROUP_TOK GROUP_SID_TOK MASK_TOK OTHER_TOK
44 %token OWNERAT_TOK GROUPAT_TOK EVERYONEAT_TOK DEFAULT_USER_TOK
45 %token DEFAULT_GROUP_TOK DEFAULT_MASK_TOK DEFAULT_OTHER_TOK
46 %token COLON COMMA NL SLASH
47 %token <str> ID IDNAME PERM_TOK INHERIT_TOK SID
48 %token <val> ERROR ACE_PERM ACE_INHERIT ENTRY_TYPE ACCESS_TYPE
50 %type <str> idname id
51 %type <acl_perm> perms perm aclent_perm ace_perms
52 %type <acl> acl_entry
53 %type <ace> ace
54 %type <aclent> aclent
55 %type <val> iflags verbose_iflag compact_iflag access_type entry_type
57 %left ERROR COLON
61 acl: acl_entry NL
63 yyacl = $1;
64 return (0);
67 /* This seems illegal, but the old aclfromtext() allows it */
68 | acl_entry COMMA NL
70 yyacl = $1;
71 return (0);
73 | acl_entry COMMA acl
75 yyacl = $1;
76 return (0);
79 acl_entry: ace
81 ace_t *acep;
83 if (yyacl == NULL) {
84 yyacl = acl_alloc(ACE_T);
85 if (yyacl == NULL) {
86 yycleanup();
87 return (EACL_MEM_ERROR);
91 $$ = yyacl;
92 if ($$->acl_type == ACLENT_T) {
93 acl_error(dgettext(TEXT_DOMAIN,
94 "Cannot have POSIX draft ACL entries"
95 " with NFSv4/ZFS ACL entries.\n"));
96 acl_free(yyacl);
97 yyacl = NULL;
98 yycleanup();
99 return (EACL_DIFF_TYPE);
102 $$->acl_aclp = realloc($$->acl_aclp,
103 ($$->acl_entry_size * ($$->acl_cnt + 1)));
104 if ($$->acl_aclp == NULL) {
105 free (yyacl);
106 yycleanup();
107 return (EACL_MEM_ERROR);
109 acep = $$->acl_aclp;
110 acep[$$->acl_cnt] = $1;
111 $$->acl_cnt++;
112 yycleanup();
114 | aclent
116 aclent_t *aclent;
118 if (yyacl == NULL) {
119 yyacl = acl_alloc(ACLENT_T);
120 if (yyacl == NULL) {
121 yycleanup();
122 return (EACL_MEM_ERROR);
126 $$ = yyacl;
127 if ($$->acl_type == ACE_T) {
128 acl_error(dgettext(TEXT_DOMAIN,
129 "Cannot have NFSv4/ZFS ACL entries"
130 " with POSIX draft ACL entries.\n"));
131 acl_free(yyacl);
132 yyacl = NULL;
133 yycleanup();
134 return (EACL_DIFF_TYPE);
137 $$->acl_aclp = realloc($$->acl_aclp,
138 ($$->acl_entry_size * ($$->acl_cnt +1)));
139 if ($$->acl_aclp == NULL) {
140 free (yyacl);
141 yycleanup();
142 return (EACL_MEM_ERROR);
144 aclent = $$->acl_aclp;
145 aclent[$$->acl_cnt] = $1;
146 $$->acl_cnt++;
147 yycleanup();
150 ace: entry_type idname ace_perms access_type
152 int error;
153 uid_t id;
154 int mask;
156 error = get_id($1, $2, &id);
157 if (error) {
158 bad_entry_type($1, $2);
159 yycleanup();
160 return (EACL_INVALID_USER_GROUP);
163 $$.a_who = id;
164 $$.a_flags = ace_entry_type($1);
165 error = ace_perm_mask(&$3, &$$.a_access_mask);
166 if (error) {
167 yycleanup();
168 return (error);
170 $$.a_type = $4;
173 | entry_type idname ace_perms access_type COLON id
175 int error;
176 uid_t id;
178 if (yyinteractive) {
179 acl_error(dgettext(TEXT_DOMAIN,
180 "Extra fields on the end of "
181 "ACL specification.\n"));
182 yycleanup();
183 return (EACL_UNKNOWN_DATA);
185 error = get_id($1, $2, &id);
186 if (error) {
187 $$.a_who = get_id_nofail($1, $6);
188 } else {
189 $$.a_who = id;
191 $$.a_flags = ace_entry_type($1);
192 error = ace_perm_mask(&$3, &$$.a_access_mask);
193 if (error) {
194 yycleanup();
195 return (error);
197 $$.a_type = $4;
199 | entry_type idname ace_perms iflags access_type
201 int error;
202 uid_t id;
204 error = get_id($1, $2, &id);
205 if (error) {
206 bad_entry_type($1, $2);
207 yycleanup();
208 return (EACL_INVALID_USER_GROUP);
211 $$.a_who = id;
212 $$.a_flags = ace_entry_type($1);
213 error = ace_perm_mask(&$3, &$$.a_access_mask);
214 if (error) {
215 yycleanup();
216 return (error);
218 $$.a_type = $5;
219 $$.a_flags |= $4;
221 | entry_type idname ace_perms iflags access_type COLON id
223 int error;
224 uid_t id;
226 if (yyinteractive) {
227 acl_error(dgettext(TEXT_DOMAIN,
228 "Extra fields on the end of "
229 "ACL specification.\n"));
230 yycleanup();
231 return (EACL_UNKNOWN_DATA);
233 error = get_id($1, $2, &id);
234 if (error) {
235 $$.a_who = get_id_nofail($1, $7);
236 } else {
237 $$.a_who = id;
240 $$.a_flags = ace_entry_type($1);
241 error = ace_perm_mask(&$3, &$$.a_access_mask);
242 if (error) {
243 yycleanup();
244 return (error);
247 $$.a_type = $5;
248 $$.a_flags |= $4;
250 | entry_type ace_perms access_type
252 int error;
254 $$.a_who = -1;
255 $$.a_flags = ace_entry_type($1);
256 error = ace_perm_mask(&$2, &$$.a_access_mask);
257 if (error) {
258 yycleanup();
259 return (error);
261 $$.a_type = $3;
263 | entry_type ace_perms access_type COLON id
265 yycleanup();
266 if (yyinteractive) {
267 acl_error(dgettext(TEXT_DOMAIN,
268 "Extra fields on the end of "
269 "ACL specification.\n"));
270 return (EACL_UNKNOWN_DATA);
273 return (EACL_ENTRY_ERROR);
275 | entry_type ace_perms iflags access_type
277 int error;
279 $$.a_who = -1;
280 $$.a_flags = ace_entry_type($1);
281 error = ace_perm_mask(&$2, &$$.a_access_mask);
282 if (error) {
283 yycleanup();
284 return (error);
286 $$.a_type = $4;
287 $$.a_flags |= $3;
290 | entry_type ace_perms iflags access_type COLON id
292 yycleanup();
293 if (yyinteractive) {
294 acl_error(dgettext(TEXT_DOMAIN,
295 "Extra fields on the end of "
296 "ACL specification.\n"));
297 return (EACL_UNKNOWN_DATA);
299 return (EACL_ENTRY_ERROR);
302 aclent: entry_type idname aclent_perm /* user or group */
304 int error;
305 uid_t id;
307 error = get_id($1, $2, &id);
308 if (error) {
309 bad_entry_type($1, $2);
310 yycleanup();
311 return (EACL_INVALID_USER_GROUP);
314 error = compute_aclent_perms($3.perm_str, &$$.a_perm);
315 if (error) {
316 acl_error(dgettext(TEXT_DOMAIN,
317 "Invalid permission(s) '%s' specified.\n"),
318 $3.perm_str);
319 yycleanup();
320 return (error);
322 $$.a_id = id;
323 error = aclent_entry_type($1, 0, &$$.a_type);
324 if (error) {
325 acl_error(
326 dgettext(TEXT_DOMAIN,
327 "Invalid ACL entry type '%s' specified.\n"), $1);
328 yycleanup();
329 return (error);
332 | entry_type COLON aclent_perm /* owner group other */
334 int error;
336 error = compute_aclent_perms($3.perm_str, &$$.a_perm);
337 if (error) {
338 acl_error(dgettext(TEXT_DOMAIN,
339 "Invalid permission(s) '%s' specified.\n"),
340 $3.perm_str);
341 yycleanup();
342 return (error);
344 $$.a_id = -1;
345 error = aclent_entry_type($1, 1, &$$.a_type);
346 if (error) {
347 acl_error(
348 dgettext(TEXT_DOMAIN,
349 "Invalid ACL entry type '%s' specified.\n"), $1);
350 yycleanup();
351 return (error);
354 | entry_type COLON aclent_perm COLON id
356 yycleanup();
357 if (yyinteractive) {
358 acl_error(dgettext(TEXT_DOMAIN,
359 "Extra fields on the end of ACL specification.\n"));
360 return (EACL_UNKNOWN_DATA);
362 return (EACL_ENTRY_ERROR);
364 | entry_type idname aclent_perm COLON id /* user or group */
366 int error;
367 uid_t id;
369 if (yyinteractive) {
370 acl_error(dgettext(TEXT_DOMAIN,
371 "Extra fields on the end of ACL specification.\n"));
372 yycleanup();
373 return (EACL_UNKNOWN_DATA);
375 error = compute_aclent_perms($3.perm_str, &$$.a_perm);
376 if (error) {
377 acl_error(dgettext(TEXT_DOMAIN,
378 "Invalid permission(s) '%s' specified.\n"),
379 $3.perm_str);
380 yycleanup();
381 return (error);
383 error = get_id($1, $2, &id);
384 if (error) {
385 $$.a_id = get_id_nofail($1, $5);
386 } else
387 $$.a_id = id;
389 error = aclent_entry_type($1, 0, &$$.a_type);
390 if (error) {
391 acl_error(
392 dgettext(TEXT_DOMAIN,
393 "Invalid ACL entry type '%s' specified.\n"), $1);
394 yycleanup();
395 return (error);
398 | entry_type aclent_perm /* mask entry */
400 int error;
402 error = compute_aclent_perms($2.perm_str, &$$.a_perm);
403 if (error) {
404 acl_error(dgettext(TEXT_DOMAIN,
405 "Invalid permission(s) '%s' specified.\n"),
406 $2.perm_str);
407 yycleanup();
408 return (error);
410 $$.a_id = -1;
411 error = aclent_entry_type($1, 0, &$$.a_type);
412 if (error) {
413 acl_error(
414 dgettext(TEXT_DOMAIN,
415 "Invalid ACL entry type specified %d.\n"),
416 error);
417 yycleanup();
418 return (error);
421 | entry_type aclent_perm COLON id
423 yycleanup();
424 if (yyinteractive) {
425 acl_error(dgettext(TEXT_DOMAIN,
426 "Extra fields on the end of ACL specification.\n"));
427 return (EACL_UNKNOWN_DATA);
429 return (EACL_ENTRY_ERROR);
432 iflags: compact_iflag COLON {$$ = $1;}
433 | verbose_iflag COLON {$$ = $1;}
434 | COLON {$$ = 0;}
436 compact_iflag : INHERIT_TOK
438 int error;
439 uint32_t iflags;
441 error = compute_ace_inherit($1, &iflags);
442 if (error) {
443 acl_error(dgettext(TEXT_DOMAIN,
444 "Invalid inheritance flags '%s' specified.\n"), $1);
445 yycleanup();
446 return (error);
448 $$ = iflags;
450 | INHERIT_TOK SLASH verbose_iflag
452 acl_error(dgettext(TEXT_DOMAIN,
453 "Can't mix compact inherit flags with"
454 " verbose inheritance flags.\n"));
455 yycleanup();
456 return (EACL_INHERIT_ERROR);
459 verbose_iflag: ACE_INHERIT {$$ |= $1;}
460 | ACE_INHERIT SLASH verbose_iflag {$$ = $1 | $3;}
461 | ACE_INHERIT SLASH compact_iflag
463 acl_error(dgettext(TEXT_DOMAIN,
464 "Can't mix verbose inherit flags with"
465 " compact inheritance flags.\n"));
466 yycleanup();
467 return (EACL_INHERIT_ERROR);
469 | ACE_INHERIT SLASH ACCESS_TYPE
471 acl_error(dgettext(TEXT_DOMAIN,
472 "Inheritance flags can't be mixed with access type.\n"));
473 yycleanup();
474 return (EACL_INHERIT_ERROR);
476 | ACE_INHERIT SLASH ERROR
478 yycleanup();
479 return ($3);
482 aclent_perm: PERM_TOK
484 $$.perm_style = PERM_TYPE_UNKNOWN;
485 $$.perm_str = $1;
486 $$.perm_val = 0;
488 | PERM_TOK ERROR
490 acl_error(dgettext(TEXT_DOMAIN,
491 "ACL entry permissions are incorrectly specified.\n"));
492 yycleanup();
493 return ($2);
496 access_type: ACCESS_TYPE {$$ = $1;}
497 | ERROR
499 yycleanup();
500 return ($1);
503 id: ID {$$ = $1;}
504 | SID {$$ = $1;}
505 | COLON
507 acl_error(dgettext(TEXT_DOMAIN,
508 "Invalid uid/gid specified.\nThe field"
509 " should be a numeric value.\n"));
510 yycleanup();
511 return (EACL_UNKNOWN_DATA);
513 | ERROR
515 yycleanup();
516 return ($1);
519 ace_perms: perm {$$ = $1;}
520 | aclent_perm COLON {$$ = $1;}
521 | ERROR
523 yycleanup();
524 return ($1);
527 perm: perms COLON {$$ = $1;}
528 | COLON {$$.perm_style = PERM_TYPE_EMPTY;}
530 perms: ACE_PERM
532 $$.perm_style = PERM_TYPE_ACE;
533 $$.perm_val |= $1;
535 | ACE_PERM SLASH perms
537 $$.perm_style = PERM_TYPE_ACE;
538 $$.perm_val = $1 | $3.perm_val;
540 | ACE_PERM SLASH aclent_perm
543 acl_error(dgettext(TEXT_DOMAIN,
544 "Can't mix verbose permissions with"
545 " compact permission.\n"));
546 yycleanup();
547 return (EACL_PERM_MASK_ERROR);
550 | ACE_PERM SLASH ERROR
552 yycleanup();
553 return ($3);
557 idname: IDNAME {$$ = $1;}
559 entry_type: ENTRY_TYPE {$$ = $1;}
560 | ERROR
562 yycleanup();
563 return ($1);
567 static void
568 bad_entry_type(int toketype, char *str)
570 switch(toketype) {
571 case USER_TOK:
572 case DEFAULT_USER_TOK:
573 acl_error(dgettext(TEXT_DOMAIN,
574 "Invalid user %s specified.\n"), str);
575 break;
577 case GROUP_TOK:
578 case DEFAULT_GROUP_TOK:
579 acl_error(dgettext(TEXT_DOMAIN,
580 "Invalid group %s specified.\n"), str);
581 break;
583 case USER_SID_TOK:
584 acl_error(dgettext(TEXT_DOMAIN,
585 "Invalid user SID %s specified.\n"), str);
586 break;
588 case GROUP_SID_TOK:
589 acl_error(dgettext(TEXT_DOMAIN,
590 "Invalid group SID %s specified.\n"), str);