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