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