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