1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 * 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/acl.h> 30 #include <aclutils.h> 31 32 extern int yyinteractive; 33 extern acl_t *yyacl; 34 %} 35 36 37 %union { 38 char *str; 39 int val; 40 struct acl_perm_type acl_perm; 41 ace_t ace; 42 aclent_t aclent; 43 acl_t *acl; 44 } 45 46 47 %token USER_TOK GROUP_TOK MASK_TOK OTHER_TOK OWNERAT_TOK 48 %token GROUPAT_TOK EVERYONEAT_TOK DEFAULT_USER_TOK DEFAULT_GROUP_TOK 49 %token DEFAULT_MASK_TOK DEFAULT_OTHER_TOK COLON COMMA NL SLASH 50 %token <str> IDNAME PERM_TOK INHERIT_TOK 51 %token <val> ID ERROR ACE_PERM ACE_INHERIT ENTRY_TYPE ACCESS_TYPE 52 53 %type <str> idname 54 %type <acl_perm> perms perm aclent_perm ace_perms 55 %type <acl> acl_entry 56 %type <ace> ace 57 %type <aclent> aclent 58 %type <val> iflags verbose_iflag compact_iflag access_type id entry_type 59 60 %left ERROR COLON 61 62 %% 63 64 acl: acl_entry NL 65 { 66 yyacl = $1; 67 return (0); 68 } 69 70 /* This seems illegal, but the old aclfromtext() allows it */ 71 | acl_entry COMMA NL 72 { 73 yyacl = $1; 74 return (0); 75 } 76 | acl_entry COMMA acl 77 { 78 yyacl = $1; 79 return (0); 80 } 81 82 acl_entry: ace 83 { 84 ace_t *acep; 85 86 if (yyacl == NULL) { 87 yyacl = acl_alloc(ACE_T); 88 if (yyacl == NULL) 89 return (EACL_MEM_ERROR); 90 } 91 92 $$ = yyacl; 93 if ($$->acl_type == ACLENT_T) { 94 acl_error(gettext("Cannot have POSIX draft ACL entries" 95 " with NFSV4/ZFS ACL entries\n")); 96 acl_free(yyacl); 97 yyacl = NULL; 98 return (EACL_DIFF_TYPE); 99 } 100 101 $$->acl_aclp = realloc($$->acl_aclp, 102 ($$->acl_entry_size * ($$->acl_cnt + 1))); 103 if ($$->acl_aclp == NULL) { 104 free (yyacl); 105 return (EACL_MEM_ERROR); 106 } 107 acep = $$->acl_aclp; 108 acep[$$->acl_cnt] = $1; 109 $$->acl_cnt++; 110 } 111 | aclent 112 { 113 aclent_t *aclent; 114 115 if (yyacl == NULL) { 116 yyacl = acl_alloc(ACLENT_T); 117 if (yyacl == NULL) 118 return (EACL_MEM_ERROR); 119 } 120 121 $$ = yyacl; 122 if ($$->acl_type == ACE_T) { 123 acl_error(gettext("Cannot have NFSv4/ZFS ACL entries" 124 " with POSIX draft ACL entries\n")); 125 acl_free(yyacl); 126 yyacl = NULL; 127 return (EACL_DIFF_TYPE); 128 } 129 130 $$->acl_aclp = realloc($$->acl_aclp, 131 ($$->acl_entry_size * ($$->acl_cnt +1))); 132 if ($$->acl_aclp == NULL) { 133 free (yyacl); 134 return (EACL_MEM_ERROR); 135 } 136 aclent = $$->acl_aclp; 137 aclent[$$->acl_cnt] = $1; 138 $$->acl_cnt++; 139 } 140 141 ace: entry_type idname ace_perms access_type 142 { 143 int error; 144 int id; 145 int mask; 146 147 error = get_id($1, $2, &id); 148 if (error) { 149 acl_error(gettext("Invalid user %s specified\n"), $2); 150 free($2); 151 return (EACL_INVALID_USER_GROUP); 152 } 153 154 $$.a_who = id; 155 $$.a_flags = ace_entry_type($1); 156 free($2); 157 error = ace_perm_mask(&$3, &$$.a_access_mask); 158 if (error) 159 return (error); 160 $$.a_type = $4; 161 162 } 163 | entry_type idname ace_perms access_type COLON id 164 { 165 int error; 166 int id; 167 168 if (yyinteractive) { 169 acl_error(gettext("Extra fields on the end of " 170 "ACL specification\n")); 171 return (EACL_UNKNOWN_DATA); 172 } 173 error = get_id($1, $2, &id); 174 if (error) { 175 $$.a_who = $6; 176 } else { 177 $$.a_who = id; 178 } 179 $$.a_flags = ace_entry_type($1); 180 free($2); 181 error = ace_perm_mask(&$3, &$$.a_access_mask); 182 if (error) 183 return (error); 184 $$.a_type = $4; 185 } 186 | entry_type idname ace_perms iflags access_type 187 { 188 int error; 189 int id; 190 191 error = get_id($1, $2, &id); 192 if (error) { 193 acl_error(gettext("Invalid user %s specified\n"), $2); 194 free($2); 195 return (EACL_INVALID_USER_GROUP); 196 } 197 198 $$.a_who = id; 199 $$.a_flags = ace_entry_type($1); 200 free($2); 201 error = ace_perm_mask(&$3, &$$.a_access_mask); 202 if (error) 203 return (error); 204 $$.a_type = $5; 205 $$.a_flags |= $4; 206 } 207 | entry_type idname ace_perms iflags access_type COLON id 208 { 209 int error; 210 int id; 211 212 if (yyinteractive) { 213 acl_error(gettext("Extra fields on the end of " 214 "ACL specification\n")); 215 return (EACL_UNKNOWN_DATA); 216 } 217 error = get_id($1, $2, &id); 218 if (error) { 219 $$.a_who = $7; 220 } else { 221 $$.a_who = id; 222 } 223 224 $$.a_flags = ace_entry_type($1); 225 free($2); 226 error = ace_perm_mask(&$3, &$$.a_access_mask); 227 if (error) 228 return (error); 229 230 $$.a_type = $5; 231 $$.a_flags |= $4; 232 } 233 | entry_type ace_perms access_type 234 { 235 int error; 236 237 $$.a_who = -1; 238 $$.a_flags = ace_entry_type($1); 239 error = ace_perm_mask(&$2, &$$.a_access_mask); 240 if (error) { 241 return (error); 242 } 243 $$.a_type = $3; 244 } 245 | entry_type ace_perms access_type COLON id 246 { 247 if (yyinteractive) { 248 acl_error(gettext("Extra fields on the end of " 249 "ACL specification\n")); 250 return (EACL_UNKNOWN_DATA); 251 } 252 253 return (EACL_ENTRY_ERROR); 254 } 255 | entry_type ace_perms iflags access_type 256 { 257 int error; 258 259 $$.a_who = -1; 260 $$.a_flags = ace_entry_type($1); 261 error = ace_perm_mask(&$2, &$$.a_access_mask); 262 if (error) 263 return (error); 264 $$.a_type = $4; 265 $$.a_flags |= $3; 266 267 } 268 | entry_type ace_perms iflags access_type COLON id 269 { 270 if (yyinteractive) { 271 acl_error(gettext("Extra fields on the end of " 272 "ACL specification\n")); 273 return (EACL_UNKNOWN_DATA); 274 } 275 return (EACL_ENTRY_ERROR); 276 } 277 278 aclent: entry_type idname aclent_perm /* user or group */ 279 { 280 int error; 281 int id; 282 283 error = get_id($1, $2, &id); 284 if (error) { 285 acl_error(gettext("Invalid user '%s' specified\n"), 286 $2); 287 free($2); 288 return (EACL_INVALID_USER_GROUP); 289 } 290 291 error = compute_aclent_perms($3.perm_str, &$$.a_perm); 292 if (error) { 293 free($2); 294 acl_error(gettext( 295 "Invalid permission(s) '%s' specified\n"), 296 $3.perm_str); 297 return (error); 298 } 299 $$.a_id = id; 300 error = aclent_entry_type($1, 0, &$$.a_type); 301 free($2); 302 if (error) { 303 acl_error( 304 gettext("Invalid ACL entry type '%s' specified\n"), 305 $1); 306 return (error); 307 } 308 } 309 | entry_type COLON aclent_perm /* owner group other */ 310 { 311 int error; 312 313 error = compute_aclent_perms($3.perm_str, &$$.a_perm); 314 if (error) { 315 acl_error(gettext( 316 "Invalid permission(s) '%s' specified\n"), 317 $3.perm_str); 318 return (error); 319 } 320 $$.a_id = -1; 321 error = aclent_entry_type($1, 1, &$$.a_type); 322 if (error) { 323 acl_error( 324 gettext("Invalid ACL entry type '%s' specified\n"), 325 $1); 326 return (error); 327 } 328 } 329 | entry_type COLON aclent_perm COLON id 330 { 331 if (yyinteractive) { 332 acl_error(gettext("Extra fields on the end of " 333 "ACL specification\n")); 334 return (EACL_UNKNOWN_DATA); 335 } 336 return (EACL_ENTRY_ERROR); 337 } 338 | entry_type idname aclent_perm COLON id /* user or group */ 339 { 340 int error; 341 int id; 342 343 if (yyinteractive) { 344 acl_error(gettext("Extra fields on the end of " 345 "ACL specification\n")); 346 return (EACL_UNKNOWN_DATA); 347 } 348 error = compute_aclent_perms($3.perm_str, &$$.a_perm); 349 if (error) { 350 free($2); 351 acl_error(gettext( 352 "Invalid permission(s) '%s' specified\n"), 353 $3.perm_str); 354 return (error); 355 } 356 error = get_id($1, $2, &id); 357 if (error) 358 $$.a_id = $5; 359 else 360 $$.a_id = id; 361 362 error = aclent_entry_type($1, 0, &$$.a_type); 363 free($2); 364 if (error) { 365 acl_error( 366 gettext("Invalid ACL entry type '%s' specified\n"), 367 $1); 368 return (error); 369 } 370 } 371 | entry_type aclent_perm /* mask entry */ 372 { 373 int error; 374 375 error = compute_aclent_perms($2.perm_str, &$$.a_perm); 376 if (error) { 377 acl_error(gettext( 378 "Invalid permission(s) '%s' specified\n"), 379 $2.perm_str); 380 return (error); 381 } 382 $$.a_id = -1; 383 error = aclent_entry_type($1, 0, &$$.a_type); 384 if (error) { 385 acl_error( 386 gettext("Invalid ACL entry type specified %d\n"), 387 error); 388 return (error); 389 } 390 } 391 | entry_type aclent_perm COLON id 392 { 393 if (yyinteractive) { 394 acl_error(gettext("Extra fields on the end of " 395 "ACL specification\n")); 396 return (EACL_UNKNOWN_DATA); 397 } 398 return (EACL_ENTRY_ERROR); 399 } 400 401 iflags: compact_iflag COLON {$$ = $1;} 402 | verbose_iflag COLON {$$ = $1;} 403 | COLON {$$ = 0;} 404 405 compact_iflag : INHERIT_TOK 406 { 407 int error; 408 uint32_t iflags; 409 410 error = compute_ace_inherit($1, &iflags); 411 if (error) { 412 acl_error(gettext("Invalid inheritance flags " 413 "'%s' specified\n"), $1); 414 free($1); 415 return (error); 416 } 417 $$ = iflags; 418 } 419 | INHERIT_TOK SLASH verbose_iflag 420 { 421 acl_error(gettext("Can't mix compact inherit flags with" 422 " verbose inheritance flags\n")); 423 return (EACL_INHERIT_ERROR); 424 } 425 426 verbose_iflag: ACE_INHERIT {$$ |= $1;} 427 | ACE_INHERIT SLASH verbose_iflag {$$ = $1 | $3;} 428 | ACE_INHERIT SLASH compact_iflag 429 { 430 acl_error(gettext("Can't mix verbose inherit flags with" 431 " compact inheritance flags\n")); 432 return (EACL_INHERIT_ERROR); 433 } 434 | ACE_INHERIT SLASH ERROR {return ($3);} 435 436 aclent_perm: PERM_TOK 437 { 438 $$.perm_style = PERM_TYPE_UNKNOWN; 439 $$.perm_str = $1; 440 $$.perm_val = 0; 441 } 442 | PERM_TOK ERROR 443 { 444 acl_error(gettext("ACL entry permissions are incorrectly " 445 "specified\n")); 446 return ($2); 447 } 448 449 access_type: ACCESS_TYPE { $$ = $1;} 450 | ERROR {return ($1);} 451 452 id: ID {$$ = $1;} 453 | ERROR {return ($1);} 454 455 ace_perms: perm {$$ = $1;} 456 | aclent_perm COLON {$$ = $1;} 457 | ERROR {return ($1);} 458 459 perm: perms COLON {$$ = $1;} 460 | COLON {$$.perm_style = PERM_TYPE_EMPTY;} 461 462 perms: ACE_PERM 463 { 464 $$.perm_style = PERM_TYPE_ACE; 465 $$.perm_val |= $1; 466 } 467 | ACE_PERM SLASH perms 468 { 469 $$.perm_style = PERM_TYPE_ACE; 470 $$.perm_val = $1 | $3.perm_val; 471 } 472 | ACE_PERM SLASH aclent_perm 473 { 474 475 acl_error(gettext("Can't mix verbose permissions with" 476 " compact permission\n")); 477 return (EACL_PERM_MASK_ERROR); 478 479 } 480 481 idname: IDNAME {$$ = $1;} 482 483 entry_type: ENTRY_TYPE {$$ = $1;} 484 | ERROR {return ($1);} 485