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