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 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/acl.h> 29 #include <acl/acl_common.h> 30 #include <smbsrv/smb_sid.h> 31 #include <smbsrv/smb_fsops.h> 32 #include <smbsrv/smb_idmap.h> 33 #include <smbsrv/smb_kproto.h> 34 #include <smbsrv/ntstatus.h> 35 #include <smbsrv/ntaccess.h> 36 37 #define ACE_FD_INHERIT_ACE (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE) 38 39 #define ZACE_IS_OWNER(zace) ((zace->a_flags & ACE_TYPE_FLAGS) == ACE_OWNER) 40 #define ZACE_IS_OWNGRP(zace) \ 41 ((zace->a_flags & ACE_TYPE_FLAGS) == (ACE_IDENTIFIER_GROUP|ACE_GROUP)) 42 43 #define ZACE_IS_USER(zace) \ 44 (((zace->a_flags & ACE_TYPE_FLAGS) == 0) || (ZACE_IS_OWNER(zace))) 45 #define ZACE_IS_GROUP(zace) (zace->a_flags & ACE_IDENTIFIER_GROUP) 46 #define ZACE_IS_EVERYONE(zace) (zace->a_flags & ACE_EVERYONE) 47 48 #define ZACE_IS_PROPAGATE(zace) \ 49 ((zace->a_flags & ACE_NO_PROPAGATE_INHERIT_ACE) == 0) 50 51 #define ZACE_IS_CREATOR_OWNER(zace) \ 52 (ZACE_IS_USER(zace) && (zace->a_who == IDMAP_WK_CREATOR_OWNER_UID)) 53 54 #define ZACE_IS_CREATOR_GROUP(zace) \ 55 (ZACE_IS_GROUP(zace) && (zace->a_who == IDMAP_WK_CREATOR_GROUP_GID)) 56 57 #define ZACE_IS_CREATOR(zace) \ 58 (ZACE_IS_CREATOR_OWNER(zace) || ZACE_IS_CREATOR_GROUP(zace)) 59 60 /* 61 * ACE groups within a DACL 62 * 63 * This is from lower to higher ACE order priority 64 */ 65 #define SMB_AG_START 0 66 #define SMB_AG_ALW_INHRT 0 67 #define SMB_AG_DNY_INHRT 1 68 #define SMB_AG_ALW_DRCT 2 69 #define SMB_AG_DNY_DRCT 3 70 #define SMB_AG_NUM 4 71 72 /* 73 * SID for Everyone group: S-1-1-0. 74 */ 75 smb_sid_t everyone_sid = { 76 NT_SID_REVISION, 77 1, 78 NT_SECURITY_WORLD_AUTH, 79 { 0 } 80 }; 81 82 #define DEFAULT_DACL_ACENUM 2 83 /* 84 * Default ACL: 85 * owner: full access 86 * SYSTEM: full access 87 */ 88 static ace_t default_dacl[DEFAULT_DACL_ACENUM] = { 89 { (uid_t)-1, ACE_ALL_PERMS, 0, ACE_ACCESS_ALLOWED_ACE_TYPE }, 90 { IDMAP_WK_LOCAL_SYSTEM_GID, ACE_ALL_PERMS, ACE_IDENTIFIER_GROUP, 91 ACE_ACCESS_ALLOWED_ACE_TYPE } 92 }; 93 94 /* 95 * Note: 96 * 97 * smb_acl_xxx functions work with smb_acl_t which represents the CIFS format 98 * smb_fsacl_xxx functions work with acl_t which represents the Solaris native 99 * format 100 */ 101 102 static idmap_stat smb_acl_getsids(smb_idmap_batch_t *, acl_t *, uid_t, gid_t); 103 static acl_t *smb_acl_null_empty(boolean_t null); 104 105 static int smb_fsacl_inheritable(acl_t *, int); 106 107 108 static void smb_ace_inherit(ace_t *, ace_t *, int); 109 static boolean_t smb_ace_isvalid(smb_ace_t *, int); 110 static uint16_t smb_ace_len(smb_ace_t *); 111 static uint32_t smb_ace_mask_g2s(uint32_t); 112 static uint16_t smb_ace_flags_tozfs(uint8_t, int); 113 static uint8_t smb_ace_flags_fromzfs(uint16_t); 114 115 smb_acl_t * 116 smb_acl_alloc(uint8_t revision, uint16_t bsize, uint16_t acecnt) 117 { 118 smb_acl_t *acl; 119 int size; 120 121 size = sizeof (smb_acl_t) + (acecnt * sizeof (smb_ace_t)); 122 acl = kmem_zalloc(size, KM_SLEEP); 123 acl->sl_revision = revision; 124 acl->sl_bsize = bsize; 125 acl->sl_acecnt = acecnt; 126 acl->sl_aces = (smb_ace_t *)(acl + 1); 127 128 list_create(&acl->sl_sorted, sizeof (smb_ace_t), 129 offsetof(smb_ace_t, se_sln)); 130 return (acl); 131 } 132 133 void 134 smb_acl_free(smb_acl_t *acl) 135 { 136 int i, size; 137 void *ace; 138 139 if (acl == NULL) 140 return; 141 142 for (i = 0; i < acl->sl_acecnt; i++) 143 smb_sid_free(acl->sl_aces[i].se_sid); 144 145 while ((ace = list_head(&acl->sl_sorted)) != NULL) 146 list_remove(&acl->sl_sorted, ace); 147 list_destroy(&acl->sl_sorted); 148 149 size = sizeof (smb_acl_t) + (acl->sl_acecnt * sizeof (smb_ace_t)); 150 kmem_free(acl, size); 151 } 152 153 /* 154 * smb_acl_len 155 * 156 * Returns the size of given ACL in bytes. Note that this 157 * is not an in-memory size, it's the ACL's size as it would 158 * appear on the wire 159 */ 160 uint16_t 161 smb_acl_len(smb_acl_t *acl) 162 { 163 if (acl == NULL) 164 return (0); 165 166 return (acl->sl_bsize); 167 } 168 169 boolean_t 170 smb_acl_isvalid(smb_acl_t *acl, int which_acl) 171 { 172 int i; 173 174 if (acl->sl_bsize < SMB_ACL_HDRSIZE) 175 return (B_FALSE); 176 177 if (acl->sl_revision != ACL_REVISION) { 178 /* 179 * we are rejecting ACLs with object-specific ACEs for now 180 */ 181 return (B_FALSE); 182 } 183 184 for (i = 0; i < acl->sl_acecnt; i++) { 185 if (!smb_ace_isvalid(&acl->sl_aces[i], which_acl)) 186 return (B_FALSE); 187 } 188 189 return (B_TRUE); 190 } 191 192 /* 193 * smb_acl_sort 194 * 195 * Sorts the given ACL in place if it needs to be sorted. 196 * 197 * The following is an excerpt from MSDN website. 198 * 199 * Order of ACEs in a DACL 200 * 201 * For Windows NT versions 4.0 and earlier, the preferred order of ACEs 202 * is simple: In a DACL, all access-denied ACEs should precede any 203 * access-allowed ACEs. 204 * 205 * For Windows 2000 or later, the proper order of ACEs is more complicated 206 * because of the introduction of object-specific ACEs and automatic 207 * inheritance. 208 * 209 * The following describes the preferred order: 210 * 211 * To ensure that noninherited ACEs have precedence over inherited ACEs, 212 * place all noninherited ACEs in a group before any inherited ACEs. This 213 * ordering ensures, for example, that a noninherited access-denied ACE 214 * is enforced regardless of any inherited ACE that allows access. 215 * Within the groups of noninherited ACEs and inherited ACEs, order ACEs 216 * according to ACE type, as the following shows: 217 * . Access-denied ACEs that apply to the object itself 218 * . Access-denied ACEs that apply to a subobject of the 219 * object, such as a property set or property 220 * . Access-allowed ACEs that apply to the object itself 221 * . Access-allowed ACEs that apply to a subobject of the object 222 * 223 * So, here is the desired ACE order 224 * 225 * deny-direct, allow-direct, deny-inherited, allow-inherited 226 * 227 * Of course, not all ACE types are required in an ACL. 228 */ 229 void 230 smb_acl_sort(smb_acl_t *acl) 231 { 232 list_t ace_grps[SMB_AG_NUM]; 233 list_t *alist; 234 smb_ace_t *ace; 235 uint8_t ace_flags; 236 int ag, i; 237 238 ASSERT(acl); 239 240 if (acl->sl_acecnt == 0) { 241 /* 242 * ACL with no entry is a valid ACL and it means 243 * no access for anybody. 244 */ 245 return; 246 } 247 248 for (i = SMB_AG_START; i < SMB_AG_NUM; i++) { 249 list_create(&ace_grps[i], sizeof (smb_ace_t), 250 offsetof(smb_ace_t, se_sln)); 251 } 252 253 for (i = 0, ace = acl->sl_aces; i < acl->sl_acecnt; ++i, ace++) { 254 ace_flags = ace->se_hdr.se_flags; 255 256 switch (ace->se_hdr.se_type) { 257 case ACCESS_DENIED_ACE_TYPE: 258 ag = (ace_flags & INHERITED_ACE) ? 259 SMB_AG_DNY_INHRT : SMB_AG_DNY_DRCT; 260 break; 261 262 case ACCESS_ALLOWED_ACE_TYPE: 263 ag = (ace_flags & INHERITED_ACE) ? 264 SMB_AG_ALW_INHRT : SMB_AG_ALW_DRCT; 265 break; 266 267 default: 268 /* 269 * This is the lowest priority group so we put 270 * evertything unknown here. 271 */ 272 ag = SMB_AG_ALW_INHRT; 273 break; 274 } 275 276 /* Add the ACE to the selected group */ 277 list_insert_tail(&ace_grps[ag], ace); 278 } 279 280 /* 281 * start with highest priority ACE group and append 282 * the ACEs to the ACL. 283 */ 284 for (i = SMB_AG_NUM - 1; i >= SMB_AG_START; i--) { 285 alist = &ace_grps[i]; 286 while ((ace = list_head(alist)) != NULL) { 287 list_remove(alist, ace); 288 list_insert_tail(&acl->sl_sorted, ace); 289 } 290 list_destroy(alist); 291 } 292 } 293 294 /* 295 * smb_acl_from_zfs 296 * 297 * Converts given ZFS ACL to a Windows ACL. 298 * 299 * A pointer to allocated memory for the Win ACL will be 300 * returned upon successful conversion. 301 */ 302 smb_acl_t * 303 smb_acl_from_zfs(acl_t *zacl, uid_t uid, gid_t gid) 304 { 305 ace_t *zace; 306 int numaces; 307 smb_acl_t *acl; 308 smb_ace_t *ace; 309 smb_idmap_batch_t sib; 310 smb_idmap_t *sim; 311 idmap_stat idm_stat; 312 313 idm_stat = smb_idmap_batch_create(&sib, zacl->acl_cnt, 314 SMB_IDMAP_ID2SID); 315 if (idm_stat != IDMAP_SUCCESS) 316 return (NULL); 317 318 if (smb_acl_getsids(&sib, zacl, uid, gid) != IDMAP_SUCCESS) { 319 smb_idmap_batch_destroy(&sib); 320 return (NULL); 321 } 322 323 acl = smb_acl_alloc(ACL_REVISION, SMB_ACL_HDRSIZE, zacl->acl_cnt); 324 325 sim = sib.sib_maps; 326 for (numaces = 0, zace = zacl->acl_aclp; 327 numaces < zacl->acl_cnt; 328 zace++, numaces++, sim++) { 329 ASSERT(sim->sim_sid); 330 if (sim->sim_sid == NULL) { 331 smb_acl_free(acl); 332 acl = NULL; 333 break; 334 } 335 336 ace = &acl->sl_aces[numaces]; 337 ace->se_hdr.se_type = zace->a_type; 338 ace->se_hdr.se_flags = smb_ace_flags_fromzfs(zace->a_flags); 339 ace->se_mask = zace->a_access_mask; 340 ace->se_sid = smb_sid_dup(sim->sim_sid); 341 ace->se_hdr.se_bsize = smb_ace_len(ace); 342 343 acl->sl_bsize += ace->se_hdr.se_bsize; 344 } 345 346 smb_idmap_batch_destroy(&sib); 347 return (acl); 348 } 349 350 /* 351 * smb_acl_to_zfs 352 * 353 * Converts given Windows ACL to a ZFS ACL. 354 * 355 * fs_acl will contain a pointer to the created ZFS ACL. 356 * The allocated memory should be freed by calling 357 * smb_fsacl_free(). 358 * 359 * Since the output parameter, fs_acl, is allocated in this 360 * function, the caller has to make sure *fs_acl is NULL which 361 * means it's not pointing to any memory. 362 */ 363 uint32_t 364 smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) 365 { 366 smb_ace_t *ace; 367 acl_t *zacl; 368 ace_t *zace; 369 smb_idmap_batch_t sib; 370 smb_idmap_t *sim; 371 idmap_stat idm_stat; 372 int i, isdir; 373 374 ASSERT(fs_acl); 375 ASSERT(*fs_acl == NULL); 376 377 if (acl && !smb_acl_isvalid(acl, which_acl)) 378 return (NT_STATUS_INVALID_ACL); 379 380 if ((acl == NULL) || (acl->sl_acecnt == 0)) { 381 if (which_acl == SMB_DACL_SECINFO) { 382 *fs_acl = smb_acl_null_empty(acl == NULL); 383 } 384 385 return (NT_STATUS_SUCCESS); 386 } 387 388 idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt, 389 SMB_IDMAP_SID2ID); 390 if (idm_stat != IDMAP_SUCCESS) 391 return (NT_STATUS_INTERNAL_ERROR); 392 393 isdir = ((flags & ACL_IS_DIR) == ACL_IS_DIR); 394 395 zacl = smb_fsacl_alloc(acl->sl_acecnt, flags); 396 397 zace = zacl->acl_aclp; 398 ace = acl->sl_aces; 399 sim = sib.sib_maps; 400 401 for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { 402 zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES; 403 zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask); 404 zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags, 405 isdir); 406 407 if (smb_sid_cmp(ace->se_sid, &everyone_sid)) 408 zace->a_flags |= ACE_EVERYONE; 409 else { 410 sim->sim_id = &zace->a_who; 411 idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, 412 ace->se_sid, -1); 413 414 if (idm_stat != IDMAP_SUCCESS) { 415 smb_fsacl_free(zacl); 416 smb_idmap_batch_destroy(&sib); 417 return (NT_STATUS_INTERNAL_ERROR); 418 } 419 } 420 } 421 422 idm_stat = smb_idmap_batch_getmappings(&sib); 423 if (idm_stat != IDMAP_SUCCESS) { 424 smb_fsacl_free(zacl); 425 smb_idmap_batch_destroy(&sib); 426 return (NT_STATUS_NONE_MAPPED); 427 } 428 429 /* 430 * Set the ACEs group flag based on the type of ID returned. 431 */ 432 zace = zacl->acl_aclp; 433 ace = acl->sl_aces; 434 sim = sib.sib_maps; 435 for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { 436 if (zace->a_flags & ACE_EVERYONE) 437 continue; 438 439 if (sim->sim_idtype == SMB_IDMAP_GROUP) 440 zace->a_flags |= ACE_IDENTIFIER_GROUP; 441 } 442 443 smb_idmap_batch_destroy(&sib); 444 445 *fs_acl = zacl; 446 return (NT_STATUS_SUCCESS); 447 } 448 449 /* 450 * smb_acl_getsids 451 * 452 * Batch all the uid/gid in given ZFS ACL to get their corresponding SIDs. 453 */ 454 static idmap_stat 455 smb_acl_getsids(smb_idmap_batch_t *sib, acl_t *zacl, uid_t uid, gid_t gid) 456 { 457 ace_t *zace; 458 idmap_stat idm_stat; 459 smb_idmap_t *sim; 460 uid_t id; 461 int i, idtype; 462 463 sim = sib->sib_maps; 464 465 for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt; 466 zace++, i++, sim++) { 467 switch (zace->a_flags & ACE_TYPE_FLAGS) { 468 case ACE_OWNER: 469 id = uid; 470 idtype = SMB_IDMAP_USER; 471 break; 472 473 case (ACE_GROUP | ACE_IDENTIFIER_GROUP): 474 /* owning group */ 475 id = gid; 476 idtype = SMB_IDMAP_GROUP; 477 break; 478 479 case ACE_IDENTIFIER_GROUP: 480 /* regular group */ 481 id = zace->a_who; 482 idtype = SMB_IDMAP_GROUP; 483 break; 484 485 case ACE_EVERYONE: 486 idtype = SMB_IDMAP_EVERYONE; 487 break; 488 489 default: 490 /* user entry */ 491 id = zace->a_who; 492 idtype = SMB_IDMAP_USER; 493 } 494 495 idm_stat = smb_idmap_batch_getsid(sib->sib_idmaph, sim, 496 id, idtype); 497 498 if (idm_stat != IDMAP_SUCCESS) { 499 return (idm_stat); 500 } 501 } 502 503 idm_stat = smb_idmap_batch_getmappings(sib); 504 return (idm_stat); 505 } 506 507 /* 508 * smb_acl_null_empty 509 * 510 * NULL DACL means everyone full-access 511 * Empty DACL means everyone full-deny 512 * 513 * ZFS ACL must have at least one entry so smb server has 514 * to simulate the aforementioned expected behavior by adding 515 * an entry in case the requested DACL is null or empty. Adding 516 * a everyone full-deny entry has proved to be problematic in 517 * tests since a deny entry takes precedence over allow entries. 518 * So, instead of adding a everyone full-deny, an owner ACE with 519 * owner implicit permissions will be set. 520 */ 521 static acl_t * 522 smb_acl_null_empty(boolean_t null) 523 { 524 acl_t *zacl; 525 ace_t *zace; 526 527 zacl = smb_fsacl_alloc(1, ACL_AUTO_INHERIT); 528 zace = zacl->acl_aclp; 529 530 zace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; 531 if (null) { 532 zace->a_access_mask = ACE_ALL_PERMS; 533 zace->a_flags = ACE_EVERYONE; 534 } else { 535 zace->a_access_mask = ACE_READ_ACL | ACE_WRITE_ACL | 536 ACE_READ_ATTRIBUTES; 537 zace->a_flags = ACE_OWNER; 538 } 539 540 return (zacl); 541 } 542 543 /* 544 * FS ACL (acl_t) Functions 545 */ 546 acl_t * 547 smb_fsacl_alloc(int acenum, int flags) 548 { 549 acl_t *acl; 550 551 acl = acl_alloc(ACE_T); 552 acl->acl_cnt = acenum; 553 acl->acl_aclp = kmem_zalloc(acl->acl_entry_size * acenum, KM_SLEEP); 554 acl->acl_flags = flags; 555 return (acl); 556 } 557 558 void 559 smb_fsacl_free(acl_t *acl) 560 { 561 if (acl) 562 acl_free(acl); 563 } 564 565 /* 566 * smb_fsop_aclmerge 567 * 568 * smb_fsop_aclread/write routines which interact with filesystem 569 * work with single ACL. This routine merges given DACL and SACL 570 * which might have been created during CIFS to FS conversion into 571 * one single ACL. 572 */ 573 acl_t * 574 smb_fsacl_merge(acl_t *dacl, acl_t *sacl) 575 { 576 acl_t *acl; 577 int dacl_size; 578 579 ASSERT(dacl); 580 ASSERT(sacl); 581 582 acl = smb_fsacl_alloc(dacl->acl_cnt + sacl->acl_cnt, dacl->acl_flags); 583 dacl_size = dacl->acl_cnt * dacl->acl_entry_size; 584 bcopy(dacl->acl_aclp, acl->acl_aclp, dacl_size); 585 bcopy(sacl->acl_aclp, (char *)acl->acl_aclp + dacl_size, 586 sacl->acl_cnt * sacl->acl_entry_size); 587 588 return (acl); 589 } 590 591 /* 592 * smb_fsacl_split 593 * 594 * splits the given ACE_T ACL (zacl) to one or two ACLs (DACL/SACL) based on 595 * the 'which_acl' parameter. Note that output dacl/sacl parameters could be 596 * NULL even if they're specified in 'which_acl', which means the target 597 * doesn't have any access and/or audit ACEs. 598 */ 599 void 600 smb_fsacl_split(acl_t *zacl, acl_t **dacl, acl_t **sacl, int which_acl) 601 { 602 ace_t *zace; 603 ace_t *access_ace; 604 ace_t *audit_ace; 605 int naccess, naudit; 606 int get_dacl, get_sacl; 607 int i; 608 609 *dacl = *sacl = NULL; 610 naccess = naudit = 0; 611 get_dacl = (which_acl & SMB_DACL_SECINFO); 612 get_sacl = (which_acl & SMB_SACL_SECINFO); 613 614 for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt; zace++, i++) { 615 if (get_dacl && smb_ace_is_access(zace->a_type)) 616 naccess++; 617 else if (get_sacl && smb_ace_is_audit(zace->a_type)) 618 naudit++; 619 } 620 621 if (naccess) { 622 *dacl = smb_fsacl_alloc(naccess, zacl->acl_flags); 623 access_ace = (*dacl)->acl_aclp; 624 } 625 626 if (naudit) { 627 *sacl = smb_fsacl_alloc(naudit, zacl->acl_flags); 628 audit_ace = (*sacl)->acl_aclp; 629 } 630 631 for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt; zace++, i++) { 632 if (get_dacl && smb_ace_is_access(zace->a_type)) { 633 *access_ace = *zace; 634 access_ace++; 635 } else if (get_sacl && smb_ace_is_audit(zace->a_type)) { 636 *audit_ace = *zace; 637 audit_ace++; 638 } 639 } 640 } 641 642 /* 643 * ACE Inheritance Rules 644 * 645 * The system propagates inheritable ACEs to child objects according to a 646 * set of inheritance rules. The system places inherited ACEs in the child's 647 * DACL according to the preferred order of ACEs in a DACL. For Windows 648 * 2000 or later, the system sets the INHERITED_ACE flag in all inherited ACEs. 649 * 650 * The following table shows the ACEs inherited by container and noncontainer 651 * child objects for different combinations of inheritance flags. These 652 * inheritance rules work the same for both DACLs and SACLs. 653 * 654 * Parent ACE type Effect on Child ACL 655 * ----------------------- ------------------- 656 * OBJECT_INHERIT_ACE only Noncontainer child objects: 657 * Inherited as an effective ACE. 658 * Container child objects: 659 * Containers inherit an inherit-only ACE 660 * unless the NO_PROPAGATE_INHERIT_ACE bit 661 * flag is also set. 662 * 663 * CONTAINER_INHERIT_ACE only Noncontainer child objects: 664 * No effect on the child object. 665 * Container child objects: 666 * The child object inherits an effective ACE. 667 * The inherited ACE is inheritable unless the 668 * NO_PROPAGATE_INHERIT_ACE bit flag is also set. 669 * 670 * CONTAINER_INHERIT_ACE and 671 * OBJECT_INHERIT_ACE Noncontainer child objects: 672 * Inherited as an effective ACE. 673 * Container child objects: 674 * The child object inherits an effective ACE. 675 * The inherited ACE is inheritable unless the 676 * NO_PROPAGATE_INHERIT_ACE bit flag is also set 677 * 678 * No inheritance flags set No effect on child container or noncontainer 679 * objects. 680 * 681 * If an inherited ACE is an effective ACE for the child object, the system 682 * maps any generic rights to the specific rights for the child object. 683 * Similarly, the system maps generic SIDs, such as CREATOR_OWNER, to the 684 * appropriate SID. If an inherited ACE is an inherit-only ACE, any generic 685 * rights or generic SIDs are left unchanged so that they can be mapped 686 * appropriately when the ACE is inherited by the next generation of child 687 * objects. 688 * 689 * For a case in which a container object inherits an ACE that is both 690 * effective on the container and inheritable by its descendants, the 691 * container may inherit two ACEs. This occurs if the inheritable ACE 692 * contains generic information. The container inherits an inherit-only 693 * ACE containing the generic information and an effective-only ACE in 694 * which the generic information has been mapped. 695 */ 696 697 /* 698 * smb_fsacl_inherit 699 * 700 * Manufacture the inherited ACL from the given ACL considering 701 * the new object type (file/dir) specified by 'is_dir'. The 702 * returned ACL is used in smb_fsop_create/smb_fsop_mkdir functions. 703 * This function implements Windows inheritance rules explained above. 704 * 705 * Note that the in/out ACLs are ZFS ACLs not Windows ACLs 706 */ 707 acl_t * 708 smb_fsacl_inherit(acl_t *dir_zacl, int is_dir, int which_acl, uid_t owner_uid) 709 { 710 boolean_t use_default = B_FALSE; 711 int num_inheritable = 0; 712 int numaces; 713 ace_t *dir_zace; 714 acl_t *new_zacl; 715 ace_t *new_zace; 716 717 num_inheritable = smb_fsacl_inheritable(dir_zacl, is_dir); 718 719 if (num_inheritable == 0) { 720 if (which_acl == SMB_DACL_SECINFO) { 721 /* No inheritable access ACEs -> default DACL */ 722 num_inheritable = DEFAULT_DACL_ACENUM; 723 use_default = B_TRUE; 724 } else { 725 return (NULL); 726 } 727 } 728 729 new_zacl = smb_fsacl_alloc(num_inheritable, ACL_AUTO_INHERIT); 730 new_zace = new_zacl->acl_aclp; 731 732 if (use_default) { 733 bcopy(default_dacl, new_zacl->acl_aclp, sizeof (default_dacl)); 734 new_zace->a_who = owner_uid; 735 return (new_zacl); 736 } 737 738 for (numaces = 0, dir_zace = dir_zacl->acl_aclp; 739 numaces < dir_zacl->acl_cnt; 740 dir_zace++, numaces++) { 741 switch (dir_zace->a_flags & ACE_FD_INHERIT_ACE) { 742 case (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE): 743 /* 744 * Files inherit an effective ACE. 745 * 746 * Dirs inherit an effective ACE. 747 * The inherited ACE is inheritable unless the 748 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set 749 */ 750 smb_ace_inherit(dir_zace, new_zace, is_dir); 751 new_zace++; 752 753 if (is_dir && ZACE_IS_CREATOR(dir_zace) && 754 (ZACE_IS_PROPAGATE(dir_zace))) { 755 *new_zace = *dir_zace; 756 new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE | 757 ACE_INHERITED_ACE); 758 new_zace++; 759 } 760 break; 761 762 case ACE_FILE_INHERIT_ACE: 763 /* 764 * Files inherit as an effective ACE. 765 * 766 * Dirs inherit an inherit-only ACE 767 * unless the ACE_NO_PROPAGATE_INHERIT_ACE bit 768 * flag is also set. 769 */ 770 if (is_dir == 0) { 771 smb_ace_inherit(dir_zace, new_zace, is_dir); 772 new_zace++; 773 } else if (ZACE_IS_PROPAGATE(dir_zace)) { 774 *new_zace = *dir_zace; 775 new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE | 776 ACE_INHERITED_ACE); 777 new_zace++; 778 } 779 break; 780 781 case ACE_DIRECTORY_INHERIT_ACE: 782 /* 783 * No effect on files 784 * 785 * Dirs inherit an effective ACE. 786 * The inherited ACE is inheritable unless the 787 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set. 788 */ 789 if (is_dir == 0) 790 break; 791 792 smb_ace_inherit(dir_zace, new_zace, is_dir); 793 new_zace++; 794 795 if (ZACE_IS_CREATOR(dir_zace) && 796 (ZACE_IS_PROPAGATE(dir_zace))) { 797 *new_zace = *dir_zace; 798 new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE | 799 ACE_INHERITED_ACE); 800 new_zace++; 801 } 802 803 break; 804 805 default: 806 break; 807 } 808 } 809 810 return (new_zacl); 811 } 812 813 /* 814 * smb_fsacl_from_vsa 815 * 816 * Converts given vsecattr_t structure to a acl_t structure. 817 * 818 * The allocated memory for retuned acl_t should be freed by 819 * calling acl_free(). 820 */ 821 acl_t * 822 smb_fsacl_from_vsa(vsecattr_t *vsecattr, acl_type_t acl_type) 823 { 824 int aclbsize = 0; /* size of acl list in bytes */ 825 int dfaclbsize = 0; /* size of default acl list in bytes */ 826 int numacls; 827 acl_t *acl_info; 828 829 ASSERT(vsecattr); 830 831 acl_info = acl_alloc(acl_type); 832 if (acl_info == NULL) 833 return (NULL); 834 835 acl_info->acl_flags = 0; 836 837 switch (acl_type) { 838 839 case ACLENT_T: 840 numacls = vsecattr->vsa_aclcnt + vsecattr->vsa_dfaclcnt; 841 aclbsize = vsecattr->vsa_aclcnt * sizeof (aclent_t); 842 dfaclbsize = vsecattr->vsa_dfaclcnt * sizeof (aclent_t); 843 844 acl_info->acl_cnt = numacls; 845 acl_info->acl_aclp = kmem_alloc(aclbsize + dfaclbsize, 846 KM_SLEEP); 847 (void) memcpy(acl_info->acl_aclp, vsecattr->vsa_aclentp, 848 aclbsize); 849 (void) memcpy((char *)acl_info->acl_aclp + aclbsize, 850 vsecattr->vsa_dfaclentp, dfaclbsize); 851 852 if (acl_info->acl_cnt <= MIN_ACL_ENTRIES) 853 acl_info->acl_flags |= ACL_IS_TRIVIAL; 854 855 break; 856 857 case ACE_T: 858 aclbsize = vsecattr->vsa_aclcnt * sizeof (ace_t); 859 acl_info->acl_cnt = vsecattr->vsa_aclcnt; 860 acl_info->acl_flags = vsecattr->vsa_aclflags; 861 acl_info->acl_aclp = kmem_alloc(aclbsize, KM_SLEEP); 862 (void) memcpy(acl_info->acl_aclp, vsecattr->vsa_aclentp, 863 aclbsize); 864 if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0) 865 acl_info->acl_flags |= ACL_IS_TRIVIAL; 866 867 break; 868 869 default: 870 acl_free(acl_info); 871 return (NULL); 872 } 873 874 if (aclbsize && vsecattr->vsa_aclentp) 875 kmem_free(vsecattr->vsa_aclentp, aclbsize); 876 if (dfaclbsize && vsecattr->vsa_dfaclentp) 877 kmem_free(vsecattr->vsa_dfaclentp, dfaclbsize); 878 879 return (acl_info); 880 } 881 882 /* 883 * smb_fsacl_to_vsa 884 * 885 * Converts given acl_t structure to a vsecattr_t structure. 886 * 887 * IMPORTANT: 888 * Upon successful return the memory allocated for vsa_aclentp 889 * should be freed by calling kmem_free(). The size is returned 890 * in aclbsize. 891 */ 892 int 893 smb_fsacl_to_vsa(acl_t *acl_info, vsecattr_t *vsecattr, int *aclbsize) 894 { 895 int error = 0; 896 int numacls; 897 aclent_t *aclp; 898 899 ASSERT(acl_info); 900 ASSERT(vsecattr); 901 ASSERT(aclbsize); 902 903 bzero(vsecattr, sizeof (vsecattr_t)); 904 *aclbsize = 0; 905 906 switch (acl_info->acl_type) { 907 case ACLENT_T: 908 numacls = acl_info->acl_cnt; 909 /* 910 * Minimum ACL size is three entries so might as well 911 * bail out here. Also limit request size to prevent user 912 * from allocating too much kernel memory. Maximum size 913 * is MAX_ACL_ENTRIES for the ACL part and MAX_ACL_ENTRIES 914 * for the default ACL part. 915 */ 916 if (numacls < 3 || numacls > (MAX_ACL_ENTRIES * 2)) { 917 error = EINVAL; 918 break; 919 } 920 921 vsecattr->vsa_mask = VSA_ACL; 922 923 vsecattr->vsa_aclcnt = numacls; 924 *aclbsize = numacls * sizeof (aclent_t); 925 vsecattr->vsa_aclentp = kmem_alloc(*aclbsize, KM_SLEEP); 926 (void) memcpy(vsecattr->vsa_aclentp, acl_info->acl_aclp, 927 *aclbsize); 928 929 /* Sort the acl list */ 930 ksort((caddr_t)vsecattr->vsa_aclentp, 931 vsecattr->vsa_aclcnt, sizeof (aclent_t), cmp2acls); 932 933 /* Break into acl and default acl lists */ 934 for (numacls = 0, aclp = vsecattr->vsa_aclentp; 935 numacls < vsecattr->vsa_aclcnt; 936 aclp++, numacls++) { 937 if (aclp->a_type & ACL_DEFAULT) 938 break; 939 } 940 941 /* Find where defaults start (if any) */ 942 if (numacls < vsecattr->vsa_aclcnt) { 943 vsecattr->vsa_mask |= VSA_DFACL; 944 vsecattr->vsa_dfaclcnt = vsecattr->vsa_aclcnt - numacls; 945 vsecattr->vsa_dfaclentp = aclp; 946 vsecattr->vsa_aclcnt = numacls; 947 } 948 949 /* Adjust if they're all defaults */ 950 if (vsecattr->vsa_aclcnt == 0) { 951 vsecattr->vsa_mask &= ~VSA_ACL; 952 vsecattr->vsa_aclentp = NULL; 953 } 954 955 /* Only directories can have defaults */ 956 if (vsecattr->vsa_dfaclcnt && 957 (acl_info->acl_flags & ACL_IS_DIR)) { 958 error = ENOTDIR; 959 } 960 961 break; 962 963 case ACE_T: 964 if (acl_info->acl_cnt < 1 || 965 acl_info->acl_cnt > MAX_ACL_ENTRIES) { 966 error = EINVAL; 967 break; 968 } 969 970 vsecattr->vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS; 971 vsecattr->vsa_aclcnt = acl_info->acl_cnt; 972 vsecattr->vsa_aclflags = acl_info->acl_flags & ACL_FLAGS_ALL; 973 *aclbsize = vsecattr->vsa_aclcnt * sizeof (ace_t); 974 vsecattr->vsa_aclentsz = *aclbsize; 975 vsecattr->vsa_aclentp = kmem_alloc(*aclbsize, KM_SLEEP); 976 (void) memcpy(vsecattr->vsa_aclentp, acl_info->acl_aclp, 977 *aclbsize); 978 979 break; 980 981 default: 982 error = EINVAL; 983 } 984 985 return (error); 986 } 987 988 /* 989 * smb_fsacl_inheritable 990 * 991 * Checks to see if there are any inheritable ACEs in the 992 * given ZFS ACL. Returns the number of inheritable ACEs. 993 * 994 * The inherited ACL could be different based on the type of 995 * new object (file/dir) specified by 'is_dir'. 996 * 997 * Note that the input ACL is a ZFS ACL not Windows ACL. 998 * 999 * Any ACE except creator owner/group: 1000 * 1001 * FI DI NP #F #D 1002 * ---- ---- ---- ---- ---- 1003 * - - ? 0 0 1004 * X - - 1 1 1005 * X - X 1 0 1006 * - X - 0 1 1007 * - X X 0 1 1008 * X X - 1 1 1009 * X X X 1 1 1010 * 1011 * Creator owner/group ACE: 1012 * 1013 * FI DI NP #F #D 1014 * ---- ---- ---- ---- ---- 1015 * - - ? 0 0 1016 * X - - 1r 1c 1017 * X - X 1r 0 1018 * - X - 0 2 1019 * - X X 0 1r 1020 * X X - 1r 2 1021 * X X X 1r 1r 1022 * 1023 * Legend: 1024 * 1025 * FI: File Inherit 1026 * DI: Dir Inherit 1027 * NP: No Propagate 1028 * #F: #ACE for a new file 1029 * #D: #ACE for a new dir 1030 * 1031 * X: bit is set 1032 * -: bit is not set 1033 * ?: don't care 1034 * 1035 * 1r: one owner/group ACE 1036 * 1c: one creator owner/group ACE 1037 */ 1038 static int 1039 smb_fsacl_inheritable(acl_t *zacl, int is_dir) 1040 { 1041 int numaces; 1042 int num_inheritable = 0; 1043 ace_t *zace; 1044 1045 if (zacl == NULL) 1046 return (0); 1047 1048 for (numaces = 0, zace = zacl->acl_aclp; 1049 numaces < zacl->acl_cnt; 1050 zace++, numaces++) { 1051 switch (zace->a_flags & ACE_FD_INHERIT_ACE) { 1052 case (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE): 1053 /* 1054 * Files inherit an effective ACE. 1055 * 1056 * Dirs inherit an effective ACE. 1057 * The inherited ACE is inheritable unless the 1058 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set 1059 */ 1060 num_inheritable++; 1061 1062 if (is_dir && ZACE_IS_CREATOR(zace) && 1063 (ZACE_IS_PROPAGATE(zace))) { 1064 num_inheritable++; 1065 } 1066 break; 1067 1068 case ACE_FILE_INHERIT_ACE: 1069 /* 1070 * Files inherit as an effective ACE. 1071 * 1072 * Dirs inherit an inherit-only ACE 1073 * unless the ACE_NO_PROPAGATE_INHERIT_ACE bit 1074 * flag is also set. 1075 */ 1076 if (is_dir == 0) 1077 num_inheritable++; 1078 else if (ZACE_IS_PROPAGATE(zace)) 1079 num_inheritable++; 1080 break; 1081 1082 case ACE_DIRECTORY_INHERIT_ACE: 1083 /* 1084 * No effect on files 1085 * 1086 * Dirs inherit an effective ACE. 1087 * The inherited ACE is inheritable unless the 1088 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set. 1089 */ 1090 if (is_dir == 0) 1091 break; 1092 1093 num_inheritable++; 1094 1095 if (ZACE_IS_CREATOR(zace) && 1096 (ZACE_IS_PROPAGATE(zace))) 1097 num_inheritable++; 1098 break; 1099 1100 default: 1101 break; 1102 } 1103 } 1104 1105 return (num_inheritable); 1106 } 1107 1108 1109 /* 1110 * ACE Functions 1111 */ 1112 1113 /* 1114 * This is generic (ACL version 2) vs. object-specific 1115 * (ACL version 4) ACE types. 1116 */ 1117 boolean_t 1118 smb_ace_is_generic(int type) 1119 { 1120 switch (type) { 1121 case ACE_ACCESS_ALLOWED_ACE_TYPE: 1122 case ACE_ACCESS_DENIED_ACE_TYPE: 1123 case ACE_SYSTEM_AUDIT_ACE_TYPE: 1124 case ACE_SYSTEM_ALARM_ACE_TYPE: 1125 case ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 1126 case ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE: 1127 case ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 1128 case ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE: 1129 return (B_TRUE); 1130 1131 default: 1132 break; 1133 } 1134 1135 return (B_FALSE); 1136 } 1137 1138 boolean_t 1139 smb_ace_is_access(int type) 1140 { 1141 switch (type) { 1142 case ACE_ACCESS_ALLOWED_ACE_TYPE: 1143 case ACE_ACCESS_DENIED_ACE_TYPE: 1144 case ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE: 1145 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 1146 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 1147 case ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 1148 case ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE: 1149 case ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 1150 case ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 1151 return (B_TRUE); 1152 1153 default: 1154 break; 1155 } 1156 1157 return (B_FALSE); 1158 } 1159 1160 boolean_t 1161 smb_ace_is_audit(int type) 1162 { 1163 switch (type) { 1164 case ACE_SYSTEM_AUDIT_ACE_TYPE: 1165 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 1166 case ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 1167 case ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 1168 return (B_TRUE); 1169 1170 default: 1171 break; 1172 } 1173 1174 return (B_FALSE); 1175 } 1176 1177 /* 1178 * smb_ace_len 1179 * 1180 * Returns the length of the given ACE as it appears in an 1181 * ACL on the wire (i.e. a flat buffer which contains the SID) 1182 */ 1183 static uint16_t 1184 smb_ace_len(smb_ace_t *ace) 1185 { 1186 ASSERT(ace); 1187 ASSERT(ace->se_sid); 1188 1189 if (ace == NULL) 1190 return (0); 1191 1192 return (SMB_ACE_HDRSIZE + sizeof (ace->se_mask) + 1193 smb_sid_len(ace->se_sid)); 1194 } 1195 1196 static void 1197 smb_ace_inherit(ace_t *dir_zace, ace_t *zace, int is_dir) 1198 { 1199 *zace = *dir_zace; 1200 if (!(is_dir && ZACE_IS_PROPAGATE(dir_zace))) 1201 zace->a_flags &= ~ACE_INHERIT_FLAGS; 1202 zace->a_flags |= ACE_INHERITED_ACE; 1203 1204 /* 1205 * Replace creator owner/group ACEs with 1206 * actual owner/group ACEs. 1207 */ 1208 if (ZACE_IS_CREATOR_OWNER(dir_zace)) { 1209 zace->a_who = (uid_t)-1; 1210 zace->a_flags |= ACE_OWNER; 1211 } else if (ZACE_IS_CREATOR_GROUP(dir_zace)) { 1212 zace->a_who = (uid_t)-1; 1213 zace->a_flags |= ACE_GROUP; 1214 } 1215 } 1216 1217 /* 1218 * smb_ace_mask_g2s 1219 * 1220 * Converts generic access bits in the given mask (if any) 1221 * to file specific bits. Generic access masks shouldn't be 1222 * stored in filesystem ACEs. 1223 */ 1224 static uint32_t 1225 smb_ace_mask_g2s(uint32_t mask) 1226 { 1227 if (mask & GENERIC_ALL) { 1228 mask &= ~(GENERIC_ALL | GENERIC_READ | GENERIC_WRITE 1229 | GENERIC_EXECUTE); 1230 1231 mask |= FILE_ALL_ACCESS; 1232 return (mask); 1233 } 1234 1235 if (mask & GENERIC_READ) { 1236 mask &= ~GENERIC_READ; 1237 mask |= FILE_GENERIC_READ; 1238 } 1239 1240 if (mask & GENERIC_WRITE) { 1241 mask &= ~GENERIC_WRITE; 1242 mask |= FILE_GENERIC_WRITE; 1243 } 1244 1245 if (mask & GENERIC_EXECUTE) { 1246 mask &= ~GENERIC_EXECUTE; 1247 mask |= FILE_GENERIC_EXECUTE; 1248 } 1249 1250 return (mask); 1251 } 1252 1253 static uint16_t 1254 smb_ace_flags_tozfs(uint8_t c_flags, int isdir) 1255 { 1256 uint16_t z_flags = 0; 1257 1258 if (c_flags & SUCCESSFUL_ACCESS_ACE_FLAG) 1259 z_flags |= ACE_SUCCESSFUL_ACCESS_ACE_FLAG; 1260 1261 if (c_flags & FAILED_ACCESS_ACE_FLAG) 1262 z_flags |= ACE_FAILED_ACCESS_ACE_FLAG; 1263 1264 if (c_flags & INHERITED_ACE) 1265 z_flags |= ACE_INHERITED_ACE; 1266 1267 /* 1268 * ZFS doesn't like any inheritance flags to be set on a 1269 * file's ACE, only directories. Windows doesn't care. 1270 */ 1271 if (isdir) 1272 z_flags |= (c_flags & ACE_INHERIT_FLAGS); 1273 1274 return (z_flags); 1275 } 1276 1277 static uint8_t 1278 smb_ace_flags_fromzfs(uint16_t z_flags) 1279 { 1280 uint8_t c_flags; 1281 1282 c_flags = z_flags & ACE_INHERIT_FLAGS; 1283 1284 if (z_flags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG) 1285 c_flags |= SUCCESSFUL_ACCESS_ACE_FLAG; 1286 1287 if (z_flags & ACE_FAILED_ACCESS_ACE_FLAG) 1288 c_flags |= FAILED_ACCESS_ACE_FLAG; 1289 1290 if (z_flags & ACE_INHERITED_ACE) 1291 c_flags |= INHERITED_ACE; 1292 1293 return (c_flags); 1294 } 1295 1296 static boolean_t 1297 smb_ace_isvalid(smb_ace_t *ace, int which_acl) 1298 { 1299 uint16_t min_len; 1300 1301 min_len = sizeof (smb_acehdr_t); 1302 1303 if (ace->se_hdr.se_bsize < min_len) 1304 return (B_FALSE); 1305 1306 if (smb_ace_is_access(ace->se_hdr.se_type) && 1307 (which_acl != SMB_DACL_SECINFO)) 1308 return (B_FALSE); 1309 1310 if (smb_ace_is_audit(ace->se_hdr.se_type) && 1311 (which_acl != SMB_SACL_SECINFO)) 1312 return (B_FALSE); 1313 1314 if (smb_ace_is_generic(ace->se_hdr.se_type)) { 1315 if (!smb_sid_isvalid(ace->se_sid)) 1316 return (B_FALSE); 1317 1318 min_len += sizeof (ace->se_mask); 1319 min_len += smb_sid_len(ace->se_sid); 1320 1321 if (ace->se_hdr.se_bsize < min_len) 1322 return (B_FALSE); 1323 } 1324 1325 /* 1326 * object-specific ACE validation will be added later. 1327 */ 1328 return (B_TRUE); 1329 } 1330