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