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