1 /** 2 * acls.c - General function to process NTFS ACLs 3 * 4 * This module is part of ntfs-3g library, but may also be 5 * integrated in tools running over Linux or Windows 6 * 7 * Copyright (c) 2007-2016 Jean-Pierre Andre 8 * 9 * This program/include file is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as published 11 * by the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program/include file is distributed in the hope that it will be 15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program (in the main directory of the NTFS-3G 21 * distribution in the file COPYING); if not, write to the Free Software 22 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25 #include "config.h" 26 27 #ifdef HAVE_STDIO_H 28 #include <stdio.h> 29 #endif 30 #ifdef HAVE_STDLIB_H 31 #include <stdlib.h> 32 #endif 33 #ifdef HAVE_STRING_H 34 #include <string.h> 35 #endif 36 #ifdef HAVE_ERRNO_H 37 #include <errno.h> 38 #endif 39 #ifdef HAVE_SYS_STAT_H 40 #include <sys/stat.h> 41 #endif 42 #ifdef HAVE_FCNTL_H 43 #include <fcntl.h> 44 #endif 45 #ifdef HAVE_SYSLOG_H 46 #include <syslog.h> 47 #endif 48 #include <unistd.h> 49 #include <pwd.h> 50 #include <grp.h> 51 52 #ifdef __HAIKU__ 53 #define getgrgid(a) NULL 54 #define getpwuid(a) NULL 55 #define getgrnam(x) NULL 56 #define getpwnam(x) NULL 57 #endif 58 59 #include "types.h" 60 #include "layout.h" 61 #include "security.h" 62 #include "acls.h" 63 #include "misc.h" 64 65 /* 66 * A few useful constants 67 */ 68 69 /* 70 * null SID (S-1-0-0) 71 */ 72 73 static const char nullsidbytes[] = { 74 1, /* revision */ 75 1, /* auth count */ 76 0, 0, 0, 0, 0, 0, /* base */ 77 0, 0, 0, 0 /* 1st level */ 78 }; 79 80 static const SID *nullsid = (const SID*)nullsidbytes; 81 82 /* 83 * SID for world (S-1-1-0) 84 */ 85 86 static const char worldsidbytes[] = { 87 1, /* revision */ 88 1, /* auth count */ 89 0, 0, 0, 0, 0, 1, /* base */ 90 0, 0, 0, 0 /* 1st level */ 91 } ; 92 93 const SID *worldsid = (const SID*)worldsidbytes; 94 95 /* 96 * SID for authenticated user (S-1-5-11) 97 */ 98 99 static const char authsidbytes[] = { 100 1, /* revision */ 101 1, /* auth count */ 102 0, 0, 0, 0, 0, 5, /* base */ 103 11, 0, 0, 0 /* 1st level */ 104 }; 105 106 static const SID *authsid = (const SID*)authsidbytes; 107 108 /* 109 * SID for administrator 110 */ 111 112 static const char adminsidbytes[] = { 113 1, /* revision */ 114 2, /* auth count */ 115 0, 0, 0, 0, 0, 5, /* base */ 116 32, 0, 0, 0, /* 1st level */ 117 32, 2, 0, 0 /* 2nd level */ 118 }; 119 120 const SID *adminsid = (const SID*)adminsidbytes; 121 122 /* 123 * SID for system 124 */ 125 126 static const char systemsidbytes[] = { 127 1, /* revision */ 128 1, /* auth count */ 129 0, 0, 0, 0, 0, 5, /* base */ 130 18, 0, 0, 0 /* 1st level */ 131 }; 132 133 static const SID *systemsid = (const SID*)systemsidbytes; 134 135 /* 136 * SID for generic creator-owner 137 * S-1-3-0 138 */ 139 140 static const char ownersidbytes[] = { 141 1, /* revision */ 142 1, /* auth count */ 143 0, 0, 0, 0, 0, 3, /* base */ 144 0, 0, 0, 0 /* 1st level */ 145 } ; 146 147 static const SID *ownersid = (const SID*)ownersidbytes; 148 149 /* 150 * SID for generic creator-group 151 * S-1-3-1 152 */ 153 154 static const char groupsidbytes[] = { 155 1, /* revision */ 156 1, /* auth count */ 157 0, 0, 0, 0, 0, 3, /* base */ 158 1, 0, 0, 0 /* 1st level */ 159 } ; 160 161 static const SID *groupsid = (const SID*)groupsidbytes; 162 163 /* 164 * Determine the size of a SID 165 */ 166 167 int ntfs_sid_size(const SID * sid) 168 { 169 return (sid->sub_authority_count * 4 + 8); 170 } 171 172 /* 173 * Test whether two SID are equal 174 */ 175 176 BOOL ntfs_same_sid(const SID *first, const SID *second) 177 { 178 int size; 179 180 size = ntfs_sid_size(first); 181 return ((ntfs_sid_size(second) == size) 182 && !memcmp(first, second, size)); 183 } 184 185 /* 186 * Test whether a SID means "world user" 187 * Local users group recognized as world 188 * Also interactive users so that /Users/Public is world accessible, 189 * but only if Posix ACLs are not enabled (if Posix ACLs are enabled, 190 * access to /Users/Public should be done by defining interactive users 191 * as a mapped group.) 192 */ 193 194 static int is_world_sid(const SID * usid) 195 { 196 return ( 197 /* check whether S-1-1-0 : world */ 198 ((usid->sub_authority_count == 1) 199 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 200 && (usid->identifier_authority.low_part == const_cpu_to_be32(1)) 201 && (usid->sub_authority[0] == const_cpu_to_le32(0))) 202 203 /* check whether S-1-5-32-545 : local user */ 204 || ((usid->sub_authority_count == 2) 205 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 206 && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) 207 && (usid->sub_authority[0] == const_cpu_to_le32(32)) 208 && (usid->sub_authority[1] == const_cpu_to_le32(545))) 209 210 /* check whether S-1-5-11 : authenticated user */ 211 || ((usid->sub_authority_count == 1) 212 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 213 && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) 214 && (usid->sub_authority[0] == const_cpu_to_le32(11))) 215 216 #if !POSIXACLS 217 /* check whether S-1-5-4 : interactive user */ 218 || ((usid->sub_authority_count == 1) 219 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 220 && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) 221 && (usid->sub_authority[0] == const_cpu_to_le32(4))) 222 #endif /* !POSIXACLS */ 223 ); 224 } 225 226 /* 227 * Test whether a SID means "some user (or group)" 228 * Currently we only check for S-1-5-21... but we should 229 * probably test for other configurations 230 */ 231 232 BOOL ntfs_is_user_sid(const SID *usid) 233 { 234 return ((usid->sub_authority_count == 5) 235 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 236 && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) 237 && (usid->sub_authority[0] == const_cpu_to_le32(21))); 238 } 239 240 /* 241 * Test whether a SID means "some special group" 242 * Currently we only check for a few S-1-5-n but we should 243 * probably test for other configurations. 244 * 245 * This is useful for granting access to /Users/Public for 246 * specific users when the Posix ACLs are enabled. 247 */ 248 249 static BOOL ntfs_known_group_sid(const SID *usid) 250 { 251 /* count == 1 excludes S-1-5-5-X-Y (logon) */ 252 return ((usid->sub_authority_count == 1) 253 && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) 254 && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) 255 && (le32_to_cpu(usid->sub_authority[0]) >= 1) 256 && (le32_to_cpu(usid->sub_authority[0]) <= 6)); 257 } 258 259 /* 260 * Determine the size of a security attribute 261 * whatever the order of fields 262 */ 263 264 unsigned int ntfs_attr_size(const char *attr) 265 { 266 const SECURITY_DESCRIPTOR_RELATIVE *phead; 267 const ACL *pdacl; 268 const ACL *psacl; 269 const SID *psid; 270 unsigned int offdacl; 271 unsigned int offsacl; 272 unsigned int offowner; 273 unsigned int offgroup; 274 unsigned int endsid; 275 unsigned int endacl; 276 unsigned int attrsz; 277 278 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)attr; 279 /* 280 * First check group, which is the last field in all descriptors 281 * we build, and in most descriptors built by Windows 282 */ 283 attrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 284 offgroup = le32_to_cpu(phead->group); 285 if (offgroup >= attrsz) { 286 /* find end of GSID */ 287 psid = (const SID*)&attr[offgroup]; 288 endsid = offgroup + ntfs_sid_size(psid); 289 if (endsid > attrsz) attrsz = endsid; 290 } 291 offowner = le32_to_cpu(phead->owner); 292 if (offowner >= attrsz) { 293 /* find end of USID */ 294 psid = (const SID*)&attr[offowner]; 295 endsid = offowner + ntfs_sid_size(psid); 296 attrsz = endsid; 297 } 298 offsacl = le32_to_cpu(phead->sacl); 299 if (offsacl >= attrsz) { 300 /* find end of SACL */ 301 psacl = (const ACL*)&attr[offsacl]; 302 endacl = offsacl + le16_to_cpu(psacl->size); 303 if (endacl > attrsz) 304 attrsz = endacl; 305 } 306 307 308 /* find end of DACL */ 309 offdacl = le32_to_cpu(phead->dacl); 310 if (offdacl >= attrsz) { 311 pdacl = (const ACL*)&attr[offdacl]; 312 endacl = offdacl + le16_to_cpu(pdacl->size); 313 if (endacl > attrsz) 314 attrsz = endacl; 315 } 316 return (attrsz); 317 } 318 319 /** 320 * ntfs_valid_sid - determine if a SID is valid 321 * @sid: SID for which to determine if it is valid 322 * 323 * Determine if the SID pointed to by @sid is valid. 324 * 325 * Return TRUE if it is valid and FALSE otherwise. 326 */ 327 BOOL ntfs_valid_sid(const SID *sid) 328 { 329 return sid && sid->revision == SID_REVISION && 330 sid->sub_authority_count <= SID_MAX_SUB_AUTHORITIES; 331 } 332 333 /* 334 * Check whether a SID is acceptable for an implicit 335 * mapping pattern. 336 * It should have been already checked it is a valid user SID. 337 * 338 * The last authority reference has to be >= 1000 (Windows usage) 339 * and <= 0x7fffffff, so that 30 bits from a uid and 30 more bits 340 * from a gid an be inserted with no overflow. 341 */ 342 343 BOOL ntfs_valid_pattern(const SID *sid) 344 { 345 int cnt; 346 u32 auth; 347 le32 leauth; 348 349 cnt = sid->sub_authority_count; 350 leauth = sid->sub_authority[cnt-1]; 351 auth = le32_to_cpu(leauth); 352 return ((auth >= 1000) && (auth <= 0x7fffffff)); 353 } 354 355 /* 356 * Compute the uid or gid associated to a SID 357 * through an implicit mapping 358 * 359 * Returns 0 (root) if it does not match pattern 360 */ 361 362 static u32 findimplicit(const SID *xsid, const SID *pattern, int parity) 363 { 364 BIGSID defsid; 365 SID *psid; 366 u32 xid; /* uid or gid */ 367 int cnt; 368 u32 carry; 369 le32 leauth; 370 u32 uauth; 371 u32 xlast; 372 u32 rlast; 373 374 memcpy(&defsid,pattern,ntfs_sid_size(pattern)); 375 psid = (SID*)&defsid; 376 cnt = psid->sub_authority_count; 377 xid = 0; 378 if (xsid->sub_authority_count == cnt) { 379 psid->sub_authority[cnt-1] = xsid->sub_authority[cnt-1]; 380 leauth = xsid->sub_authority[cnt-1]; 381 xlast = le32_to_cpu(leauth); 382 leauth = pattern->sub_authority[cnt-1]; 383 rlast = le32_to_cpu(leauth); 384 385 if ((xlast > rlast) && !((xlast ^ rlast ^ parity) & 1)) { 386 /* direct check for basic situation */ 387 if (ntfs_same_sid(psid,xsid)) 388 xid = ((xlast - rlast) >> 1) & 0x3fffffff; 389 else { 390 /* 391 * check whether part of mapping had to be 392 * recorded in a higher level authority 393 */ 394 carry = 1; 395 do { 396 leauth = psid->sub_authority[cnt-2]; 397 uauth = le32_to_cpu(leauth) + 1; 398 psid->sub_authority[cnt-2] 399 = cpu_to_le32(uauth); 400 } while (!ntfs_same_sid(psid,xsid) 401 && (++carry < 4)); 402 if (carry < 4) 403 xid = (((xlast - rlast) >> 1) 404 & 0x3fffffff) | (carry << 30); 405 } 406 } 407 } 408 return (xid); 409 } 410 411 /* 412 * Find usid mapped to a Linux user 413 * Returns NULL if not found 414 */ 415 416 const SID *ntfs_find_usid(const struct MAPPING* usermapping, 417 uid_t uid, SID *defusid) 418 { 419 const struct MAPPING *p; 420 const SID *sid; 421 le32 leauth; 422 u32 uauth; 423 int cnt; 424 425 if (!uid) 426 sid = adminsid; 427 else { 428 p = usermapping; 429 while (p && p->xid && ((uid_t)p->xid != uid)) 430 p = p->next; 431 if (p && !p->xid) { 432 /* 433 * default pattern has been reached : 434 * build an implicit SID according to pattern 435 * (the pattern format was checked while reading 436 * the mapping file) 437 */ 438 memcpy(defusid, p->sid, ntfs_sid_size(p->sid)); 439 cnt = defusid->sub_authority_count; 440 leauth = defusid->sub_authority[cnt-1]; 441 uauth = le32_to_cpu(leauth) + 2*(uid & 0x3fffffff); 442 defusid->sub_authority[cnt-1] = cpu_to_le32(uauth); 443 if (uid & 0xc0000000) { 444 leauth = defusid->sub_authority[cnt-2]; 445 uauth = le32_to_cpu(leauth) + ((uid >> 30) & 3); 446 defusid->sub_authority[cnt-2] = cpu_to_le32(uauth); 447 } 448 sid = defusid; 449 } else 450 sid = (p ? p->sid : (const SID*)NULL); 451 } 452 return (sid); 453 } 454 455 /* 456 * Find Linux group mapped to a gsid 457 * Returns 0 (root) if not found 458 */ 459 460 const SID *ntfs_find_gsid(const struct MAPPING* groupmapping, 461 gid_t gid, SID *defgsid) 462 { 463 const struct MAPPING *p; 464 const SID *sid; 465 le32 leauth; 466 u32 uauth; 467 int cnt; 468 469 if (!gid) 470 sid = adminsid; 471 else { 472 p = groupmapping; 473 while (p && p->xid && ((gid_t)p->xid != gid)) 474 p = p->next; 475 if (p && !p->xid) { 476 /* 477 * default pattern has been reached : 478 * build an implicit SID according to pattern 479 * (the pattern format was checked while reading 480 * the mapping file) 481 */ 482 memcpy(defgsid, p->sid, ntfs_sid_size(p->sid)); 483 cnt = defgsid->sub_authority_count; 484 leauth = defgsid->sub_authority[cnt-1]; 485 uauth = le32_to_cpu(leauth) + 2*(gid & 0x3fffffff) + 1; 486 defgsid->sub_authority[cnt-1] = cpu_to_le32(uauth); 487 if (gid & 0xc0000000) { 488 leauth = defgsid->sub_authority[cnt-2]; 489 uauth = le32_to_cpu(leauth) + ((gid >> 30) & 3); 490 defgsid->sub_authority[cnt-2] = cpu_to_le32(uauth); 491 } 492 sid = defgsid; 493 } else 494 sid = (p ? p->sid : (const SID*)NULL); 495 } 496 return (sid); 497 } 498 499 /* 500 * Find Linux owner mapped to a usid 501 * Returns 0 (root) if not found 502 */ 503 504 uid_t ntfs_find_user(const struct MAPPING* usermapping, const SID *usid) 505 { 506 uid_t uid; 507 const struct MAPPING *p; 508 509 p = usermapping; 510 while (p && p->xid && !ntfs_same_sid(usid, p->sid)) 511 p = p->next; 512 if (p && !p->xid) 513 /* 514 * No explicit mapping found, try implicit mapping 515 */ 516 uid = findimplicit(usid,p->sid,0); 517 else 518 uid = (p ? p->xid : 0); 519 return (uid); 520 } 521 522 /* 523 * Find Linux group mapped to a gsid 524 * Returns 0 (root) if not found 525 */ 526 527 gid_t ntfs_find_group(const struct MAPPING* groupmapping, const SID * gsid) 528 { 529 gid_t gid; 530 const struct MAPPING *p; 531 532 p = groupmapping; 533 while (p && p->xid && !ntfs_same_sid(gsid, p->sid)) 534 p = p->next; 535 if (p && !p->xid) 536 /* 537 * No explicit mapping found, try implicit mapping 538 */ 539 gid = findimplicit(gsid,p->sid,1); 540 else 541 gid = (p ? p->xid : 0); 542 return (gid); 543 } 544 545 /* 546 * Check the validity of the ACEs in a DACL or SACL 547 */ 548 549 static BOOL valid_acl(const ACL *pacl, unsigned int end) 550 { 551 const ACCESS_ALLOWED_ACE *pace; 552 unsigned int offace; 553 unsigned int acecnt; 554 unsigned int acesz; 555 unsigned int nace; 556 unsigned int wantsz; 557 BOOL ok; 558 559 ok = TRUE; 560 acecnt = le16_to_cpu(pacl->ace_count); 561 offace = sizeof(ACL); 562 for (nace = 0; (nace < acecnt) && ok; nace++) { 563 /* be sure the beginning is within range */ 564 if ((offace + sizeof(ACCESS_ALLOWED_ACE)) > end) 565 ok = FALSE; 566 else { 567 pace = (const ACCESS_ALLOWED_ACE*) 568 &((const char*)pacl)[offace]; 569 acesz = le16_to_cpu(pace->size); 570 if (((offace + acesz) > end) 571 || !ntfs_valid_sid(&pace->sid)) 572 ok = FALSE; 573 else { 574 /* Win10 may insert garbage in the last ACE */ 575 wantsz = ntfs_sid_size(&pace->sid) + 8; 576 if (((nace < (acecnt - 1)) 577 && (wantsz != acesz)) 578 || (wantsz > acesz)) 579 ok = FALSE; 580 } 581 offace += acesz; 582 } 583 } 584 return (ok); 585 } 586 587 /* 588 * Do sanity checks on security descriptors read from storage 589 * basically, we make sure that every field holds within 590 * allocated storage 591 * Should not be called with a NULL argument 592 * returns TRUE if considered safe 593 * if not, error should be logged by caller 594 */ 595 596 BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz) 597 { 598 const SECURITY_DESCRIPTOR_RELATIVE *phead; 599 const ACL *pdacl; 600 const ACL *psacl; 601 unsigned int offdacl; 602 unsigned int offsacl; 603 unsigned int offowner; 604 unsigned int offgroup; 605 BOOL ok; 606 607 ok = TRUE; 608 609 /* 610 * first check overall size if within allocation range 611 * and a DACL is present 612 * and owner and group SID are valid 613 */ 614 615 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 616 offdacl = le32_to_cpu(phead->dacl); 617 offsacl = le32_to_cpu(phead->sacl); 618 offowner = le32_to_cpu(phead->owner); 619 offgroup = le32_to_cpu(phead->group); 620 pdacl = (const ACL*)&securattr[offdacl]; 621 psacl = (const ACL*)&securattr[offsacl]; 622 623 /* 624 * size check occurs before the above pointers are used 625 * 626 * "DR Watson" standard directory on WinXP has an 627 * old revision and no DACL though SE_DACL_PRESENT is set 628 */ 629 if ((attrsz >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 630 && (phead->revision == SECURITY_DESCRIPTOR_REVISION) 631 && (offowner >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 632 && ((offowner + 2) < attrsz) 633 && (offgroup >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 634 && ((offgroup + 2) < attrsz) 635 && (!offdacl 636 || ((offdacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 637 && (offdacl+sizeof(ACL) <= attrsz))) 638 && (!offsacl 639 || ((offsacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 640 && (offsacl+sizeof(ACL) <= attrsz))) 641 && !(phead->owner & const_cpu_to_le32(3)) 642 && !(phead->group & const_cpu_to_le32(3)) 643 && !(phead->dacl & const_cpu_to_le32(3)) 644 && !(phead->sacl & const_cpu_to_le32(3)) 645 && (ntfs_attr_size(securattr) <= attrsz) 646 && ntfs_valid_sid((const SID*)&securattr[offowner]) 647 && ntfs_valid_sid((const SID*)&securattr[offgroup]) 648 /* 649 * if there is an ACL, as indicated by offdacl, 650 * require SE_DACL_PRESENT 651 * but "Dr Watson" has SE_DACL_PRESENT though no DACL 652 */ 653 && (!offdacl 654 || ((phead->control & SE_DACL_PRESENT) 655 && ((pdacl->revision == ACL_REVISION) 656 || (pdacl->revision == ACL_REVISION_DS)))) 657 /* same for SACL */ 658 && (!offsacl 659 || ((phead->control & SE_SACL_PRESENT) 660 && ((psacl->revision == ACL_REVISION) 661 || (psacl->revision == ACL_REVISION_DS))))) { 662 /* 663 * Check the DACL and SACL if present 664 */ 665 if ((offdacl && !valid_acl(pdacl,attrsz - offdacl)) 666 || (offsacl && !valid_acl(psacl,attrsz - offsacl))) 667 ok = FALSE; 668 } else 669 ok = FALSE; 670 return (ok); 671 } 672 673 /* 674 * Copy the inheritable parts of an ACL 675 * 676 * Returns the size of the new ACL 677 * or zero if nothing is inheritable 678 */ 679 680 int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, 681 const SID *usid, const SID *gsid, BOOL fordir, 682 le16 inherited) 683 { 684 unsigned int src; 685 unsigned int dst; 686 int oldcnt; 687 int newcnt; 688 unsigned int selection; 689 int nace; 690 int acesz; 691 int usidsz; 692 int gsidsz; 693 const ACCESS_ALLOWED_ACE *poldace; 694 ACCESS_ALLOWED_ACE *pnewace; 695 ACCESS_ALLOWED_ACE *pauthace; 696 ACCESS_ALLOWED_ACE *pownerace; 697 698 pauthace = (ACCESS_ALLOWED_ACE*)NULL; 699 pownerace = (ACCESS_ALLOWED_ACE*)NULL; 700 usidsz = ntfs_sid_size(usid); 701 gsidsz = ntfs_sid_size(gsid); 702 703 /* ACL header */ 704 705 newacl->revision = ACL_REVISION; 706 newacl->alignment1 = 0; 707 newacl->alignment2 = const_cpu_to_le16(0); 708 src = dst = sizeof(ACL); 709 710 selection = (fordir ? CONTAINER_INHERIT_ACE : OBJECT_INHERIT_ACE); 711 newcnt = 0; 712 oldcnt = le16_to_cpu(oldacl->ace_count); 713 for (nace = 0; nace < oldcnt; nace++) { 714 poldace = (const ACCESS_ALLOWED_ACE*)((const char*)oldacl + src); 715 acesz = le16_to_cpu(poldace->size); 716 src += acesz; 717 /* 718 * Extract inheritance for access, including inheritance for 719 * access from an ACE with is both applied and inheritable. 720 * 721 * must not output OBJECT_INHERIT_ACE or CONTAINER_INHERIT_ACE 722 * 723 * According to MSDN : 724 * "For a case in which a container object inherits an ACE 725 * "that is both effective on the container and inheritable 726 * "by its descendants, the container may inherit two ACEs. 727 * "This occurs if the inheritable ACE contains generic 728 * "information." 729 */ 730 if ((poldace->flags & selection) 731 && (!fordir 732 || (poldace->flags & NO_PROPAGATE_INHERIT_ACE) 733 || (poldace->mask & (GENERIC_ALL | GENERIC_READ 734 | GENERIC_WRITE | GENERIC_EXECUTE))) 735 && !ntfs_same_sid(&poldace->sid, ownersid) 736 && !ntfs_same_sid(&poldace->sid, groupsid)) { 737 pnewace = (ACCESS_ALLOWED_ACE*) 738 ((char*)newacl + dst); 739 memcpy(pnewace,poldace,acesz); 740 /* reencode GENERIC_ALL */ 741 if (pnewace->mask & GENERIC_ALL) { 742 pnewace->mask &= ~GENERIC_ALL; 743 if (fordir) 744 pnewace->mask |= OWNER_RIGHTS 745 | DIR_READ 746 | DIR_WRITE 747 | DIR_EXEC; 748 else 749 /* 750 * The last flag is not defined for a file, 751 * however Windows sets it, so do the same 752 */ 753 pnewace->mask |= OWNER_RIGHTS 754 | FILE_READ 755 | FILE_WRITE 756 | FILE_EXEC 757 | const_cpu_to_le32(0x40); 758 } 759 /* reencode GENERIC_READ (+ EXECUTE) */ 760 if (pnewace->mask & GENERIC_READ) { 761 if (fordir) 762 pnewace->mask |= OWNER_RIGHTS 763 | DIR_READ 764 | DIR_EXEC; 765 else 766 pnewace->mask |= OWNER_RIGHTS 767 | FILE_READ 768 | FILE_EXEC; 769 pnewace->mask &= ~(GENERIC_READ 770 | GENERIC_EXECUTE 771 | WRITE_DAC 772 | WRITE_OWNER 773 | DELETE | FILE_WRITE_EA 774 | FILE_WRITE_ATTRIBUTES); 775 } 776 /* reencode GENERIC_WRITE */ 777 if (pnewace->mask & GENERIC_WRITE) { 778 if (fordir) 779 pnewace->mask |= OWNER_RIGHTS 780 | DIR_WRITE; 781 else 782 pnewace->mask |= OWNER_RIGHTS 783 | FILE_WRITE; 784 pnewace->mask &= ~(GENERIC_WRITE 785 | WRITE_DAC 786 | WRITE_OWNER 787 | FILE_DELETE_CHILD); 788 } 789 /* remove inheritance flags */ 790 pnewace->flags &= ~(OBJECT_INHERIT_ACE 791 | CONTAINER_INHERIT_ACE 792 | INHERIT_ONLY_ACE); 793 /* 794 * Group similar ACE for authenticated users 795 * (should probably be done for other SIDs) 796 */ 797 if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE) 798 && ntfs_same_sid(&poldace->sid, authsid)) { 799 if (pauthace) { 800 pauthace->flags |= pnewace->flags; 801 pauthace->mask |= pnewace->mask; 802 } else { 803 pauthace = pnewace; 804 if (inherited) 805 pnewace->flags |= INHERITED_ACE; 806 dst += acesz; 807 newcnt++; 808 } 809 } else { 810 if (inherited) 811 pnewace->flags |= INHERITED_ACE; 812 dst += acesz; 813 newcnt++; 814 } 815 } 816 /* 817 * Inheritance for access, specific to 818 * creator-owner (and creator-group) 819 */ 820 if (fordir || !inherited 821 || (poldace->flags 822 & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))) { 823 pnewace = (ACCESS_ALLOWED_ACE*) 824 ((char*)newacl + dst); 825 memcpy(pnewace,poldace,acesz); 826 /* 827 * Replace generic creator-owner and 828 * creator-group by owner and group 829 * (but keep for further inheritance) 830 */ 831 if (ntfs_same_sid(&pnewace->sid, ownersid)) { 832 memcpy(&pnewace->sid, usid, usidsz); 833 pnewace->size = cpu_to_le16(usidsz + 8); 834 /* remove inheritance flags */ 835 pnewace->flags &= ~(OBJECT_INHERIT_ACE 836 | CONTAINER_INHERIT_ACE 837 | INHERIT_ONLY_ACE); 838 if (inherited) 839 pnewace->flags |= INHERITED_ACE; 840 if ((pnewace->type == ACCESS_ALLOWED_ACE_TYPE) 841 && pownerace 842 && !(pnewace->flags & ~pownerace->flags)) { 843 pownerace->mask |= pnewace->mask; 844 } else { 845 dst += usidsz + 8; 846 newcnt++; 847 } 848 } 849 if (ntfs_same_sid(&pnewace->sid, groupsid)) { 850 memcpy(&pnewace->sid, gsid, gsidsz); 851 pnewace->size = cpu_to_le16(gsidsz + 8); 852 /* remove inheritance flags */ 853 pnewace->flags &= ~(OBJECT_INHERIT_ACE 854 | CONTAINER_INHERIT_ACE 855 | INHERIT_ONLY_ACE); 856 if (inherited) 857 pnewace->flags |= INHERITED_ACE; 858 dst += gsidsz + 8; 859 newcnt++; 860 } 861 } 862 863 /* 864 * inheritance for further inheritance 865 * 866 * Situations leading to output CONTAINER_INHERIT_ACE 867 * or OBJECT_INHERIT_ACE 868 */ 869 if (fordir 870 && (poldace->flags 871 & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))) { 872 pnewace = (ACCESS_ALLOWED_ACE*) 873 ((char*)newacl + dst); 874 memcpy(pnewace,poldace,acesz); 875 if ((poldace->flags & OBJECT_INHERIT_ACE) 876 && !(poldace->flags & (CONTAINER_INHERIT_ACE 877 | NO_PROPAGATE_INHERIT_ACE))) 878 pnewace->flags |= INHERIT_ONLY_ACE; 879 if ((poldace->flags & CONTAINER_INHERIT_ACE) 880 && !(poldace->flags & NO_PROPAGATE_INHERIT_ACE) 881 && !ntfs_same_sid(&poldace->sid, ownersid) 882 && !ntfs_same_sid(&poldace->sid, groupsid)) { 883 if ((poldace->mask & (GENERIC_ALL | GENERIC_READ 884 | GENERIC_WRITE | GENERIC_EXECUTE))) 885 pnewace->flags |= INHERIT_ONLY_ACE; 886 else 887 pnewace->flags &= ~INHERIT_ONLY_ACE; 888 } 889 if (inherited) 890 pnewace->flags |= INHERITED_ACE; 891 /* 892 * Prepare grouping similar ACE for authenticated users 893 */ 894 if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE) 895 && !pauthace 896 && !(pnewace->flags & INHERIT_ONLY_ACE) 897 && ntfs_same_sid(&poldace->sid, authsid)) { 898 pauthace = pnewace; 899 } 900 /* 901 * Prepare grouping similar ACE for owner 902 */ 903 if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE) 904 && !pownerace 905 && !(pnewace->flags & INHERIT_ONLY_ACE) 906 && ntfs_same_sid(&poldace->sid, usid)) { 907 pownerace = pnewace; 908 } 909 dst += acesz; 910 newcnt++; 911 } 912 } 913 /* 914 * Adjust header if something was inherited 915 */ 916 if (dst > sizeof(ACL)) { 917 newacl->ace_count = cpu_to_le16(newcnt); 918 newacl->size = cpu_to_le16(dst); 919 } else 920 dst = 0; 921 return (dst); 922 } 923 924 #if POSIXACLS 925 926 /* 927 * Do sanity checks on a Posix descriptor 928 * Should not be called with a NULL argument 929 * returns TRUE if considered safe 930 * if not, error should be logged by caller 931 */ 932 933 BOOL ntfs_valid_posix(const struct POSIX_SECURITY *pxdesc) 934 { 935 const struct POSIX_ACL *pacl; 936 int i; 937 BOOL ok; 938 u16 tag; 939 u32 id; 940 int perms; 941 struct { 942 u16 previous; 943 u32 previousid; 944 u16 tagsset; 945 mode_t mode; 946 int owners; 947 int groups; 948 int others; 949 } checks[2], *pchk; 950 951 for (i=0; i<2; i++) { 952 checks[i].mode = 0; 953 checks[i].tagsset = 0; 954 checks[i].owners = 0; 955 checks[i].groups = 0; 956 checks[i].others = 0; 957 checks[i].previous = 0; 958 checks[i].previousid = 0; 959 } 960 ok = TRUE; 961 pacl = &pxdesc->acl; 962 /* 963 * header (strict for now) 964 */ 965 if ((pacl->version != POSIX_VERSION) 966 || (pacl->flags != 0) 967 || (pacl->filler != 0)) 968 ok = FALSE; 969 /* 970 * Reject multiple owner, group or other 971 * but do not require them to be present 972 * Also check the ACEs are in correct order 973 * which implies there is no duplicates 974 */ 975 for (i=0; i<pxdesc->acccnt + pxdesc->defcnt; i++) { 976 if (i >= pxdesc->firstdef) 977 pchk = &checks[1]; 978 else 979 pchk = &checks[0]; 980 perms = pacl->ace[i].perms; 981 tag = pacl->ace[i].tag; 982 pchk->tagsset |= tag; 983 id = pacl->ace[i].id; 984 if (perms & ~7) ok = FALSE; 985 if ((tag < pchk->previous) 986 || ((tag == pchk->previous) 987 && (id <= pchk->previousid))) 988 ok = FALSE; 989 pchk->previous = tag; 990 pchk->previousid = id; 991 switch (tag) { 992 case POSIX_ACL_USER_OBJ : 993 if (pchk->owners++) 994 ok = FALSE; 995 if (id != (u32)-1) 996 ok = FALSE; 997 pchk->mode |= perms << 6; 998 break; 999 case POSIX_ACL_GROUP_OBJ : 1000 if (pchk->groups++) 1001 ok = FALSE; 1002 if (id != (u32)-1) 1003 ok = FALSE; 1004 pchk->mode = (pchk->mode & 07707) | (perms << 3); 1005 break; 1006 case POSIX_ACL_OTHER : 1007 if (pchk->others++) 1008 ok = FALSE; 1009 if (id != (u32)-1) 1010 ok = FALSE; 1011 pchk->mode |= perms; 1012 break; 1013 case POSIX_ACL_USER : 1014 case POSIX_ACL_GROUP : 1015 if (id == (u32)-1) 1016 ok = FALSE; 1017 break; 1018 case POSIX_ACL_MASK : 1019 if (id != (u32)-1) 1020 ok = FALSE; 1021 pchk->mode = (pchk->mode & 07707) | (perms << 3); 1022 break; 1023 default : 1024 ok = FALSE; 1025 break; 1026 } 1027 } 1028 if ((pxdesc->acccnt > 0) 1029 && ((checks[0].owners != 1) || (checks[0].groups != 1) 1030 || (checks[0].others != 1))) 1031 ok = FALSE; 1032 /* do not check owner, group or other are present in */ 1033 /* the default ACL, Windows does not necessarily set them */ 1034 /* descriptor */ 1035 if (pxdesc->defcnt && (pxdesc->acccnt > pxdesc->firstdef)) 1036 ok = FALSE; 1037 if ((pxdesc->acccnt < 0) || (pxdesc->defcnt < 0)) 1038 ok = FALSE; 1039 /* check mode, unless null or no tag set */ 1040 if (pxdesc->mode 1041 && checks[0].tagsset 1042 && (checks[0].mode != (pxdesc->mode & 0777))) 1043 ok = FALSE; 1044 /* check tagsset */ 1045 if (pxdesc->tagsset != checks[0].tagsset) 1046 ok = FALSE; 1047 return (ok); 1048 } 1049 1050 /* 1051 * Set standard header data into a Posix ACL 1052 * The mode argument should provide the 3 upper bits of target mode 1053 */ 1054 1055 static mode_t posix_header(struct POSIX_SECURITY *pxdesc, mode_t basemode) 1056 { 1057 mode_t mode; 1058 u16 tagsset; 1059 struct POSIX_ACE *pace; 1060 int i; 1061 1062 mode = basemode & 07000; 1063 tagsset = 0; 1064 for (i=0; i<pxdesc->acccnt; i++) { 1065 pace = &pxdesc->acl.ace[i]; 1066 tagsset |= pace->tag; 1067 switch(pace->tag) { 1068 case POSIX_ACL_USER_OBJ : 1069 mode |= (pace->perms & 7) << 6; 1070 break; 1071 case POSIX_ACL_GROUP_OBJ : 1072 case POSIX_ACL_MASK : 1073 mode = (mode & 07707) | ((pace->perms & 7) << 3); 1074 break; 1075 case POSIX_ACL_OTHER : 1076 mode |= pace->perms & 7; 1077 break; 1078 default : 1079 break; 1080 } 1081 } 1082 pxdesc->tagsset = tagsset; 1083 pxdesc->mode = mode; 1084 pxdesc->acl.version = POSIX_VERSION; 1085 pxdesc->acl.flags = 0; 1086 pxdesc->acl.filler = 0; 1087 return (mode); 1088 } 1089 1090 /* 1091 * Sort ACEs in a Posix ACL 1092 * This is useful for always getting reusable converted ACLs, 1093 * it also helps in merging ACEs. 1094 * Repeated tag+id are allowed and not merged here. 1095 * 1096 * Tags should be in ascending sequence and for a repeatable tag 1097 * ids should be in ascending sequence. 1098 */ 1099 1100 void ntfs_sort_posix(struct POSIX_SECURITY *pxdesc) 1101 { 1102 struct POSIX_ACL *pacl; 1103 struct POSIX_ACE ace; 1104 int i; 1105 int offs; 1106 BOOL done; 1107 u16 tag; 1108 u16 previous; 1109 u32 id; 1110 u32 previousid; 1111 1112 1113 /* 1114 * Check sequencing of tag+id in access ACE's 1115 */ 1116 pacl = &pxdesc->acl; 1117 do { 1118 done = TRUE; 1119 previous = pacl->ace[0].tag; 1120 previousid = pacl->ace[0].id; 1121 for (i=1; i<pxdesc->acccnt; i++) { 1122 tag = pacl->ace[i].tag; 1123 id = pacl->ace[i].id; 1124 1125 if ((tag < previous) 1126 || ((tag == previous) && (id < previousid))) { 1127 done = FALSE; 1128 memcpy(&ace,&pacl->ace[i-1],sizeof(struct POSIX_ACE)); 1129 memcpy(&pacl->ace[i-1],&pacl->ace[i],sizeof(struct POSIX_ACE)); 1130 memcpy(&pacl->ace[i],&ace,sizeof(struct POSIX_ACE)); 1131 } else { 1132 previous = tag; 1133 previousid = id; 1134 } 1135 } 1136 } while (!done); 1137 /* 1138 * Same for default ACEs 1139 */ 1140 do { 1141 done = TRUE; 1142 if ((pxdesc->defcnt) > 1) { 1143 offs = pxdesc->firstdef; 1144 previous = pacl->ace[offs].tag; 1145 previousid = pacl->ace[offs].id; 1146 for (i=offs+1; i<offs+pxdesc->defcnt; i++) { 1147 tag = pacl->ace[i].tag; 1148 id = pacl->ace[i].id; 1149 1150 if ((tag < previous) 1151 || ((tag == previous) && (id < previousid))) { 1152 done = FALSE; 1153 memcpy(&ace,&pacl->ace[i-1],sizeof(struct POSIX_ACE)); 1154 memcpy(&pacl->ace[i-1],&pacl->ace[i],sizeof(struct POSIX_ACE)); 1155 memcpy(&pacl->ace[i],&ace,sizeof(struct POSIX_ACE)); 1156 } else { 1157 previous = tag; 1158 previousid = id; 1159 } 1160 } 1161 } 1162 } while (!done); 1163 } 1164 1165 /* 1166 * Merge a new mode into a Posix descriptor 1167 * The Posix descriptor is not reallocated, its size is unchanged 1168 * 1169 * returns 0 if ok 1170 */ 1171 1172 int ntfs_merge_mode_posix(struct POSIX_SECURITY *pxdesc, mode_t mode) 1173 { 1174 int i; 1175 BOOL maskfound; 1176 struct POSIX_ACE *pace; 1177 int todo; 1178 1179 maskfound = FALSE; 1180 todo = POSIX_ACL_USER_OBJ | POSIX_ACL_GROUP_OBJ | POSIX_ACL_OTHER; 1181 for (i=pxdesc->acccnt-1; i>=0; i--) { 1182 pace = &pxdesc->acl.ace[i]; 1183 switch(pace->tag) { 1184 case POSIX_ACL_USER_OBJ : 1185 pace->perms = (mode >> 6) & 7; 1186 todo &= ~POSIX_ACL_USER_OBJ; 1187 break; 1188 case POSIX_ACL_GROUP_OBJ : 1189 if (!maskfound) 1190 pace->perms = (mode >> 3) & 7; 1191 todo &= ~POSIX_ACL_GROUP_OBJ; 1192 break; 1193 case POSIX_ACL_MASK : 1194 pace->perms = (mode >> 3) & 7; 1195 maskfound = TRUE; 1196 break; 1197 case POSIX_ACL_OTHER : 1198 pace->perms = mode & 7; 1199 todo &= ~POSIX_ACL_OTHER; 1200 break; 1201 default : 1202 break; 1203 } 1204 } 1205 pxdesc->mode = mode; 1206 return (todo ? -1 : 0); 1207 } 1208 1209 /* 1210 * Replace an access or default Posix ACL 1211 * The resulting ACL is checked for validity 1212 * 1213 * Returns a new ACL or NULL if there is a problem 1214 */ 1215 1216 struct POSIX_SECURITY *ntfs_replace_acl(const struct POSIX_SECURITY *oldpxdesc, 1217 const struct POSIX_ACL *newacl, int count, BOOL deflt) 1218 { 1219 struct POSIX_SECURITY *newpxdesc; 1220 size_t newsize; 1221 int offset; 1222 int oldoffset; 1223 int i; 1224 1225 if (deflt) 1226 newsize = sizeof(struct POSIX_SECURITY) 1227 + (oldpxdesc->acccnt + count)*sizeof(struct POSIX_ACE); 1228 else 1229 newsize = sizeof(struct POSIX_SECURITY) 1230 + (oldpxdesc->defcnt + count)*sizeof(struct POSIX_ACE); 1231 newpxdesc = (struct POSIX_SECURITY*)malloc(newsize); 1232 if (newpxdesc) { 1233 if (deflt) { 1234 offset = oldpxdesc->acccnt; 1235 newpxdesc->acccnt = oldpxdesc->acccnt; 1236 newpxdesc->defcnt = count; 1237 newpxdesc->firstdef = offset; 1238 /* copy access ACEs */ 1239 for (i=0; i<newpxdesc->acccnt; i++) 1240 newpxdesc->acl.ace[i] = oldpxdesc->acl.ace[i]; 1241 /* copy default ACEs */ 1242 for (i=0; i<count; i++) 1243 newpxdesc->acl.ace[i + offset] = newacl->ace[i]; 1244 } else { 1245 offset = count; 1246 newpxdesc->acccnt = count; 1247 newpxdesc->defcnt = oldpxdesc->defcnt; 1248 newpxdesc->firstdef = count; 1249 /* copy access ACEs */ 1250 for (i=0; i<count; i++) 1251 newpxdesc->acl.ace[i] = newacl->ace[i]; 1252 /* copy default ACEs */ 1253 oldoffset = oldpxdesc->firstdef; 1254 for (i=0; i<newpxdesc->defcnt; i++) 1255 newpxdesc->acl.ace[i + offset] = oldpxdesc->acl.ace[i + oldoffset]; 1256 } 1257 /* assume special flags unchanged */ 1258 posix_header(newpxdesc, oldpxdesc->mode); 1259 if (!ntfs_valid_posix(newpxdesc)) { 1260 /* do not log, this is an application error */ 1261 free(newpxdesc); 1262 newpxdesc = (struct POSIX_SECURITY*)NULL; 1263 errno = EINVAL; 1264 } 1265 } else 1266 errno = ENOMEM; 1267 return (newpxdesc); 1268 } 1269 1270 /* 1271 * Build a basic Posix ACL from a mode and umask, 1272 * ignoring inheritance from the parent directory 1273 */ 1274 1275 struct POSIX_SECURITY *ntfs_build_basic_posix( 1276 const struct POSIX_SECURITY *pxdesc __attribute__((unused)), 1277 mode_t mode, mode_t mask, BOOL isdir __attribute__((unused))) 1278 { 1279 struct POSIX_SECURITY *pydesc; 1280 struct POSIX_ACE *pyace; 1281 1282 pydesc = (struct POSIX_SECURITY*)malloc( 1283 sizeof(struct POSIX_SECURITY) + 3*sizeof(struct POSIX_ACE)); 1284 if (pydesc) { 1285 pyace = &pydesc->acl.ace[0]; 1286 pyace->tag = POSIX_ACL_USER_OBJ; 1287 pyace->perms = ((mode & ~mask) >> 6) & 7; 1288 pyace->id = -1; 1289 pyace = &pydesc->acl.ace[1]; 1290 pyace->tag = POSIX_ACL_GROUP_OBJ; 1291 pyace->perms = ((mode & ~mask) >> 3) & 7; 1292 pyace->id = -1; 1293 pyace = &pydesc->acl.ace[2]; 1294 pyace->tag = POSIX_ACL_OTHER; 1295 pyace->perms = (mode & ~mask) & 7; 1296 pyace->id = -1; 1297 pydesc->mode = mode; 1298 pydesc->tagsset = POSIX_ACL_USER_OBJ 1299 | POSIX_ACL_GROUP_OBJ 1300 | POSIX_ACL_OTHER; 1301 pydesc->acccnt = 3; 1302 pydesc->defcnt = 0; 1303 pydesc->firstdef = 6; 1304 } else 1305 errno = ENOMEM; 1306 return (pydesc); 1307 } 1308 1309 /* 1310 * Build an inherited Posix descriptor from parent 1311 * descriptor (if any) restricted to creation mode 1312 * 1313 * Returns the inherited descriptor or NULL if there is a problem 1314 */ 1315 1316 struct POSIX_SECURITY *ntfs_build_inherited_posix( 1317 const struct POSIX_SECURITY *pxdesc, mode_t mode, 1318 mode_t mask, BOOL isdir) 1319 { 1320 struct POSIX_SECURITY *pydesc; 1321 struct POSIX_ACE *pyace; 1322 int count; 1323 int defcnt; 1324 int size; 1325 int i; 1326 s16 tagsset; 1327 1328 if (pxdesc && pxdesc->defcnt) { 1329 if (isdir) 1330 count = 2*pxdesc->defcnt + 3; 1331 else 1332 count = pxdesc->defcnt + 3; 1333 } else 1334 count = 3; 1335 pydesc = (struct POSIX_SECURITY*)malloc( 1336 sizeof(struct POSIX_SECURITY) + count*sizeof(struct POSIX_ACE)); 1337 if (pydesc) { 1338 /* 1339 * Copy inherited tags and adapt perms 1340 * Use requested mode, ignoring umask 1341 * (not possible with older versions of fuse) 1342 */ 1343 tagsset = 0; 1344 defcnt = (pxdesc ? pxdesc->defcnt : 0); 1345 for (i=defcnt-1; i>=0; i--) { 1346 pyace = &pydesc->acl.ace[i]; 1347 *pyace = pxdesc->acl.ace[pxdesc->firstdef + i]; 1348 switch (pyace->tag) { 1349 case POSIX_ACL_USER_OBJ : 1350 pyace->perms &= (mode >> 6) & 7; 1351 break; 1352 case POSIX_ACL_GROUP_OBJ : 1353 if (!(tagsset & POSIX_ACL_MASK)) 1354 pyace->perms &= (mode >> 3) & 7; 1355 break; 1356 case POSIX_ACL_OTHER : 1357 pyace->perms &= mode & 7; 1358 break; 1359 case POSIX_ACL_MASK : 1360 pyace->perms &= (mode >> 3) & 7; 1361 break; 1362 default : 1363 break; 1364 } 1365 tagsset |= pyace->tag; 1366 } 1367 pydesc->acccnt = defcnt; 1368 /* 1369 * If some standard tags were missing, append them from mode 1370 * and sort the list 1371 * Here we have to use the umask'ed mode 1372 */ 1373 if (~tagsset & (POSIX_ACL_USER_OBJ 1374 | POSIX_ACL_GROUP_OBJ | POSIX_ACL_OTHER)) { 1375 i = defcnt; 1376 /* owner was missing */ 1377 if (!(tagsset & POSIX_ACL_USER_OBJ)) { 1378 pyace = &pydesc->acl.ace[i]; 1379 pyace->tag = POSIX_ACL_USER_OBJ; 1380 pyace->id = -1; 1381 pyace->perms = ((mode & ~mask) >> 6) & 7; 1382 tagsset |= POSIX_ACL_USER_OBJ; 1383 i++; 1384 } 1385 /* owning group was missing */ 1386 if (!(tagsset & POSIX_ACL_GROUP_OBJ)) { 1387 pyace = &pydesc->acl.ace[i]; 1388 pyace->tag = POSIX_ACL_GROUP_OBJ; 1389 pyace->id = -1; 1390 pyace->perms = ((mode & ~mask) >> 3) & 7; 1391 tagsset |= POSIX_ACL_GROUP_OBJ; 1392 i++; 1393 } 1394 /* other was missing */ 1395 if (!(tagsset & POSIX_ACL_OTHER)) { 1396 pyace = &pydesc->acl.ace[i]; 1397 pyace->tag = POSIX_ACL_OTHER; 1398 pyace->id = -1; 1399 pyace->perms = mode & ~mask & 7; 1400 tagsset |= POSIX_ACL_OTHER; 1401 i++; 1402 } 1403 pydesc->acccnt = i; 1404 pydesc->firstdef = i; 1405 pydesc->defcnt = 0; 1406 ntfs_sort_posix(pydesc); 1407 } 1408 1409 /* 1410 * append as a default ACL if a directory 1411 */ 1412 pydesc->firstdef = pydesc->acccnt; 1413 if (defcnt && isdir) { 1414 size = sizeof(struct POSIX_ACE)*defcnt; 1415 memcpy(&pydesc->acl.ace[pydesc->firstdef], 1416 &pxdesc->acl.ace[pxdesc->firstdef],size); 1417 pydesc->defcnt = defcnt; 1418 } else { 1419 pydesc->defcnt = 0; 1420 } 1421 /* assume special bits are not inherited */ 1422 posix_header(pydesc, mode & 07000); 1423 if (!ntfs_valid_posix(pydesc)) { 1424 ntfs_log_error("Error building an inherited Posix desc\n"); 1425 errno = EIO; 1426 free(pydesc); 1427 pydesc = (struct POSIX_SECURITY*)NULL; 1428 } 1429 } else 1430 errno = ENOMEM; 1431 return (pydesc); 1432 } 1433 1434 static int merge_lists_posix(struct POSIX_ACE *targetace, 1435 const struct POSIX_ACE *firstace, 1436 const struct POSIX_ACE *secondace, 1437 int firstcnt, int secondcnt) 1438 { 1439 int k; 1440 1441 k = 0; 1442 /* 1443 * No list is exhausted : 1444 * if same tag+id in both list : 1445 * ignore ACE from second list 1446 * else take the one with smaller tag+id 1447 */ 1448 while ((firstcnt > 0) && (secondcnt > 0)) 1449 if ((firstace->tag == secondace->tag) 1450 && (firstace->id == secondace->id)) { 1451 secondace++; 1452 secondcnt--; 1453 } else 1454 if ((firstace->tag < secondace->tag) 1455 || ((firstace->tag == secondace->tag) 1456 && (firstace->id < secondace->id))) { 1457 targetace->tag = firstace->tag; 1458 targetace->id = firstace->id; 1459 targetace->perms = firstace->perms; 1460 firstace++; 1461 targetace++; 1462 firstcnt--; 1463 k++; 1464 } else { 1465 targetace->tag = secondace->tag; 1466 targetace->id = secondace->id; 1467 targetace->perms = secondace->perms; 1468 secondace++; 1469 targetace++; 1470 secondcnt--; 1471 k++; 1472 } 1473 /* 1474 * One list is exhausted, copy the other one 1475 */ 1476 while (firstcnt > 0) { 1477 targetace->tag = firstace->tag; 1478 targetace->id = firstace->id; 1479 targetace->perms = firstace->perms; 1480 firstace++; 1481 targetace++; 1482 firstcnt--; 1483 k++; 1484 } 1485 while (secondcnt > 0) { 1486 targetace->tag = secondace->tag; 1487 targetace->id = secondace->id; 1488 targetace->perms = secondace->perms; 1489 secondace++; 1490 targetace++; 1491 secondcnt--; 1492 k++; 1493 } 1494 return (k); 1495 } 1496 1497 /* 1498 * Merge two Posix ACLs 1499 * The input ACLs have to be adequately sorted 1500 * 1501 * Returns the merged ACL, which is allocated and has to be freed by caller, 1502 * or NULL if failed 1503 */ 1504 1505 struct POSIX_SECURITY *ntfs_merge_descr_posix(const struct POSIX_SECURITY *first, 1506 const struct POSIX_SECURITY *second) 1507 { 1508 struct POSIX_SECURITY *pxdesc; 1509 struct POSIX_ACE *targetace; 1510 const struct POSIX_ACE *firstace; 1511 const struct POSIX_ACE *secondace; 1512 size_t size; 1513 int k; 1514 1515 size = sizeof(struct POSIX_SECURITY) 1516 + (first->acccnt + first->defcnt 1517 + second->acccnt + second->defcnt)*sizeof(struct POSIX_ACE); 1518 pxdesc = (struct POSIX_SECURITY*)malloc(size); 1519 if (pxdesc) { 1520 /* 1521 * merge access ACEs 1522 */ 1523 firstace = first->acl.ace; 1524 secondace = second->acl.ace; 1525 targetace = pxdesc->acl.ace; 1526 k = merge_lists_posix(targetace,firstace,secondace, 1527 first->acccnt,second->acccnt); 1528 pxdesc->acccnt = k; 1529 /* 1530 * merge default ACEs 1531 */ 1532 pxdesc->firstdef = k; 1533 firstace = &first->acl.ace[first->firstdef]; 1534 secondace = &second->acl.ace[second->firstdef]; 1535 targetace = &pxdesc->acl.ace[k]; 1536 k = merge_lists_posix(targetace,firstace,secondace, 1537 first->defcnt,second->defcnt); 1538 pxdesc->defcnt = k; 1539 /* 1540 * build header 1541 */ 1542 pxdesc->acl.version = POSIX_VERSION; 1543 pxdesc->acl.flags = 0; 1544 pxdesc->acl.filler = 0; 1545 pxdesc->mode = 0; 1546 pxdesc->tagsset = 0; 1547 } else 1548 errno = ENOMEM; 1549 return (pxdesc); 1550 } 1551 1552 struct BUILD_CONTEXT { 1553 BOOL isdir; 1554 BOOL adminowns; 1555 BOOL groupowns; 1556 u16 selfuserperms; 1557 u16 selfgrpperms; 1558 u16 grpperms; 1559 u16 othperms; 1560 u16 mask; 1561 u16 designates; 1562 u16 withmask; 1563 u16 rootspecial; 1564 } ; 1565 1566 1567 1568 static BOOL build_user_denials(ACL *pacl, 1569 const SID *usid, struct MAPPING* const mapping[], 1570 ACE_FLAGS flags, const struct POSIX_ACE *pxace, 1571 struct BUILD_CONTEXT *pset) 1572 { 1573 BIGSID defsid; 1574 ACCESS_ALLOWED_ACE *pdace; 1575 const SID *sid; 1576 int sidsz; 1577 int pos; 1578 int acecnt; 1579 le32 grants; 1580 le32 denials; 1581 u16 perms; 1582 u16 mixperms; 1583 u16 tag; 1584 BOOL rejected; 1585 BOOL rootuser; 1586 BOOL avoidmask; 1587 1588 rejected = FALSE; 1589 tag = pxace->tag; 1590 perms = pxace->perms; 1591 rootuser = FALSE; 1592 pos = le16_to_cpu(pacl->size); 1593 acecnt = le16_to_cpu(pacl->ace_count); 1594 avoidmask = (pset->mask == (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X)) 1595 && ((pset->designates && pset->withmask) 1596 || (!pset->designates && !pset->withmask)); 1597 if (tag == POSIX_ACL_USER_OBJ) { 1598 sid = usid; 1599 sidsz = ntfs_sid_size(sid); 1600 grants = OWNER_RIGHTS; 1601 } else { 1602 if (pxace->id) { 1603 sid = ntfs_find_usid(mapping[MAPUSERS], 1604 pxace->id, (SID*)&defsid); 1605 grants = WORLD_RIGHTS; 1606 } else { 1607 sid = adminsid; 1608 rootuser = TRUE; 1609 grants = WORLD_RIGHTS & ~ROOT_OWNER_UNMARK; 1610 } 1611 if (sid) { 1612 sidsz = ntfs_sid_size(sid); 1613 /* 1614 * Insert denial of complement of mask for 1615 * each designated user (except root) 1616 * WRITE_OWNER is inserted so that 1617 * the mask can be identified 1618 */ 1619 if (!avoidmask && !rootuser) { 1620 denials = WRITE_OWNER; 1621 pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1622 if (pset->isdir) { 1623 if (!(pset->mask & POSIX_PERM_X)) 1624 denials |= DIR_EXEC; 1625 if (!(pset->mask & POSIX_PERM_W)) 1626 denials |= DIR_WRITE; 1627 if (!(pset->mask & POSIX_PERM_R)) 1628 denials |= DIR_READ; 1629 } else { 1630 if (!(pset->mask & POSIX_PERM_X)) 1631 denials |= FILE_EXEC; 1632 if (!(pset->mask & POSIX_PERM_W)) 1633 denials |= FILE_WRITE; 1634 if (!(pset->mask & POSIX_PERM_R)) 1635 denials |= FILE_READ; 1636 } 1637 if (rootuser) 1638 grants &= ~ROOT_OWNER_UNMARK; 1639 pdace->type = ACCESS_DENIED_ACE_TYPE; 1640 pdace->flags = flags; 1641 pdace->size = cpu_to_le16(sidsz + 8); 1642 pdace->mask = denials; 1643 memcpy((char*)&pdace->sid, sid, sidsz); 1644 pos += sidsz + 8; 1645 acecnt++; 1646 } 1647 } else 1648 rejected = TRUE; 1649 } 1650 if (!rejected) { 1651 if (pset->isdir) { 1652 if (perms & POSIX_PERM_X) 1653 grants |= DIR_EXEC; 1654 if (perms & POSIX_PERM_W) 1655 grants |= DIR_WRITE; 1656 if (perms & POSIX_PERM_R) 1657 grants |= DIR_READ; 1658 } else { 1659 if (perms & POSIX_PERM_X) 1660 grants |= FILE_EXEC; 1661 if (perms & POSIX_PERM_W) 1662 grants |= FILE_WRITE; 1663 if (perms & POSIX_PERM_R) 1664 grants |= FILE_READ; 1665 } 1666 1667 /* a possible ACE to deny owner what he/she would */ 1668 /* induely get from administrator, group or world */ 1669 /* unless owner is administrator or group */ 1670 1671 denials = const_cpu_to_le32(0); 1672 pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1673 if (!pset->adminowns && !rootuser) { 1674 if (!pset->groupowns) { 1675 mixperms = pset->grpperms | pset->othperms; 1676 if (tag == POSIX_ACL_USER_OBJ) 1677 mixperms |= pset->selfuserperms; 1678 if (pset->isdir) { 1679 if (mixperms & POSIX_PERM_X) 1680 denials |= DIR_EXEC; 1681 if (mixperms & POSIX_PERM_W) 1682 denials |= DIR_WRITE; 1683 if (mixperms & POSIX_PERM_R) 1684 denials |= DIR_READ; 1685 } else { 1686 if (mixperms & POSIX_PERM_X) 1687 denials |= FILE_EXEC; 1688 if (mixperms & POSIX_PERM_W) 1689 denials |= FILE_WRITE; 1690 if (mixperms & POSIX_PERM_R) 1691 denials |= FILE_READ; 1692 } 1693 } else { 1694 mixperms = ~pset->grpperms & pset->othperms; 1695 if (tag == POSIX_ACL_USER_OBJ) 1696 mixperms |= pset->selfuserperms; 1697 if (pset->isdir) { 1698 if (mixperms & POSIX_PERM_X) 1699 denials |= DIR_EXEC; 1700 if (mixperms & POSIX_PERM_W) 1701 denials |= DIR_WRITE; 1702 if (mixperms & POSIX_PERM_R) 1703 denials |= DIR_READ; 1704 } else { 1705 if (mixperms & POSIX_PERM_X) 1706 denials |= FILE_EXEC; 1707 if (mixperms & POSIX_PERM_W) 1708 denials |= FILE_WRITE; 1709 if (mixperms & POSIX_PERM_R) 1710 denials |= FILE_READ; 1711 } 1712 } 1713 denials &= ~grants; 1714 if (denials) { 1715 pdace->type = ACCESS_DENIED_ACE_TYPE; 1716 pdace->flags = flags; 1717 pdace->size = cpu_to_le16(sidsz + 8); 1718 pdace->mask = denials; 1719 memcpy((char*)&pdace->sid, sid, sidsz); 1720 pos += sidsz + 8; 1721 acecnt++; 1722 } 1723 } 1724 } 1725 pacl->size = cpu_to_le16(pos); 1726 pacl->ace_count = cpu_to_le16(acecnt); 1727 return (!rejected); 1728 } 1729 1730 static BOOL build_user_grants(ACL *pacl, 1731 const SID *usid, struct MAPPING* const mapping[], 1732 ACE_FLAGS flags, const struct POSIX_ACE *pxace, 1733 struct BUILD_CONTEXT *pset) 1734 { 1735 BIGSID defsid; 1736 ACCESS_ALLOWED_ACE *pgace; 1737 const SID *sid; 1738 int sidsz; 1739 int pos; 1740 int acecnt; 1741 le32 grants; 1742 u16 perms; 1743 u16 tag; 1744 BOOL rejected; 1745 BOOL rootuser; 1746 1747 rejected = FALSE; 1748 tag = pxace->tag; 1749 perms = pxace->perms; 1750 rootuser = FALSE; 1751 pos = le16_to_cpu(pacl->size); 1752 acecnt = le16_to_cpu(pacl->ace_count); 1753 if (tag == POSIX_ACL_USER_OBJ) { 1754 sid = usid; 1755 sidsz = ntfs_sid_size(sid); 1756 grants = OWNER_RIGHTS; 1757 } else { 1758 if (pxace->id) { 1759 sid = ntfs_find_usid(mapping[MAPUSERS], 1760 pxace->id, (SID*)&defsid); 1761 if (sid) 1762 sidsz = ntfs_sid_size(sid); 1763 else 1764 rejected = TRUE; 1765 grants = WORLD_RIGHTS; 1766 } else { 1767 sid = adminsid; 1768 sidsz = ntfs_sid_size(sid); 1769 rootuser = TRUE; 1770 grants = WORLD_RIGHTS & ~ROOT_OWNER_UNMARK; 1771 } 1772 } 1773 if (!rejected) { 1774 if (pset->isdir) { 1775 if (perms & POSIX_PERM_X) 1776 grants |= DIR_EXEC; 1777 if (perms & POSIX_PERM_W) 1778 grants |= DIR_WRITE; 1779 if (perms & POSIX_PERM_R) 1780 grants |= DIR_READ; 1781 } else { 1782 if (perms & POSIX_PERM_X) 1783 grants |= FILE_EXEC; 1784 if (perms & POSIX_PERM_W) 1785 grants |= FILE_WRITE; 1786 if (perms & POSIX_PERM_R) 1787 grants |= FILE_READ; 1788 } 1789 if (rootuser) 1790 grants &= ~ROOT_OWNER_UNMARK; 1791 pgace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1792 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 1793 pgace->size = cpu_to_le16(sidsz + 8); 1794 pgace->flags = flags; 1795 pgace->mask = grants; 1796 memcpy((char*)&pgace->sid, sid, sidsz); 1797 pos += sidsz + 8; 1798 acecnt = le16_to_cpu(pacl->ace_count) + 1; 1799 pacl->ace_count = cpu_to_le16(acecnt); 1800 pacl->size = cpu_to_le16(pos); 1801 } 1802 return (!rejected); 1803 } 1804 1805 1806 /* a grant ACE for group */ 1807 /* unless group-obj has the same rights as world */ 1808 /* but present if group is owner or owner is administrator */ 1809 /* this ACE will be inserted after denials for group */ 1810 1811 static BOOL build_group_denials_grant(ACL *pacl, 1812 const SID *gsid, struct MAPPING* const mapping[], 1813 ACE_FLAGS flags, const struct POSIX_ACE *pxace, 1814 struct BUILD_CONTEXT *pset) 1815 { 1816 BIGSID defsid; 1817 ACCESS_ALLOWED_ACE *pdace; 1818 ACCESS_ALLOWED_ACE *pgace; 1819 const SID *sid; 1820 int sidsz; 1821 int pos; 1822 int acecnt; 1823 le32 grants; 1824 le32 denials; 1825 u16 perms; 1826 u16 mixperms; 1827 u16 tag; 1828 BOOL avoidmask; 1829 BOOL rootgroup; 1830 BOOL rejected; 1831 1832 rejected = FALSE; 1833 tag = pxace->tag; 1834 perms = pxace->perms; 1835 pos = le16_to_cpu(pacl->size); 1836 acecnt = le16_to_cpu(pacl->ace_count); 1837 rootgroup = FALSE; 1838 avoidmask = (pset->mask == (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X)) 1839 && ((pset->designates && pset->withmask) 1840 || (!pset->designates && !pset->withmask)); 1841 if (tag == POSIX_ACL_GROUP_OBJ) 1842 sid = gsid; 1843 else 1844 if (pxace->id) 1845 sid = ntfs_find_gsid(mapping[MAPGROUPS], 1846 pxace->id, (SID*)&defsid); 1847 else { 1848 sid = adminsid; 1849 rootgroup = TRUE; 1850 } 1851 if (sid) { 1852 sidsz = ntfs_sid_size(sid); 1853 /* 1854 * Insert denial of complement of mask for 1855 * each group 1856 * WRITE_OWNER is inserted so that 1857 * the mask can be identified 1858 * Note : this mask may lead on Windows to 1859 * deny rights to administrators belonging 1860 * to some user group 1861 */ 1862 if ((!avoidmask && !rootgroup) 1863 || (pset->rootspecial 1864 && (tag == POSIX_ACL_GROUP_OBJ))) { 1865 denials = WRITE_OWNER; 1866 pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1867 if (pset->isdir) { 1868 if (!(pset->mask & POSIX_PERM_X)) 1869 denials |= DIR_EXEC; 1870 if (!(pset->mask & POSIX_PERM_W)) 1871 denials |= DIR_WRITE; 1872 if (!(pset->mask & POSIX_PERM_R)) 1873 denials |= DIR_READ; 1874 } else { 1875 if (!(pset->mask & POSIX_PERM_X)) 1876 denials |= FILE_EXEC; 1877 if (!(pset->mask & POSIX_PERM_W)) 1878 denials |= FILE_WRITE; 1879 if (!(pset->mask & POSIX_PERM_R)) 1880 denials |= FILE_READ; 1881 } 1882 pdace->type = ACCESS_DENIED_ACE_TYPE; 1883 pdace->flags = flags; 1884 pdace->size = cpu_to_le16(sidsz + 8); 1885 pdace->mask = denials; 1886 memcpy((char*)&pdace->sid, sid, sidsz); 1887 pos += sidsz + 8; 1888 acecnt++; 1889 } 1890 } else 1891 rejected = TRUE; 1892 if (!rejected 1893 && (pset->adminowns 1894 || pset->groupowns 1895 || avoidmask 1896 || rootgroup 1897 || (perms != pset->othperms))) { 1898 grants = WORLD_RIGHTS; 1899 if (rootgroup) 1900 grants &= ~ROOT_GROUP_UNMARK; 1901 if (pset->isdir) { 1902 if (perms & POSIX_PERM_X) 1903 grants |= DIR_EXEC; 1904 if (perms & POSIX_PERM_W) 1905 grants |= DIR_WRITE; 1906 if (perms & POSIX_PERM_R) 1907 grants |= DIR_READ; 1908 } else { 1909 if (perms & POSIX_PERM_X) 1910 grants |= FILE_EXEC; 1911 if (perms & POSIX_PERM_W) 1912 grants |= FILE_WRITE; 1913 if (perms & POSIX_PERM_R) 1914 grants |= FILE_READ; 1915 } 1916 1917 /* a possible ACE to deny group what it would get from world */ 1918 /* or administrator, unless owner is administrator or group */ 1919 1920 denials = const_cpu_to_le32(0); 1921 pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1922 if (!pset->adminowns 1923 && !pset->groupowns 1924 && !rootgroup) { 1925 mixperms = pset->othperms; 1926 if (tag == POSIX_ACL_GROUP_OBJ) 1927 mixperms |= pset->selfgrpperms; 1928 if (pset->isdir) { 1929 if (mixperms & POSIX_PERM_X) 1930 denials |= DIR_EXEC; 1931 if (mixperms & POSIX_PERM_W) 1932 denials |= DIR_WRITE; 1933 if (mixperms & POSIX_PERM_R) 1934 denials |= DIR_READ; 1935 } else { 1936 if (mixperms & POSIX_PERM_X) 1937 denials |= FILE_EXEC; 1938 if (mixperms & POSIX_PERM_W) 1939 denials |= FILE_WRITE; 1940 if (mixperms & POSIX_PERM_R) 1941 denials |= FILE_READ; 1942 } 1943 denials &= ~(grants | OWNER_RIGHTS); 1944 if (denials) { 1945 pdace->type = ACCESS_DENIED_ACE_TYPE; 1946 pdace->flags = flags; 1947 pdace->size = cpu_to_le16(sidsz + 8); 1948 pdace->mask = denials; 1949 memcpy((char*)&pdace->sid, sid, sidsz); 1950 pos += sidsz + 8; 1951 acecnt++; 1952 } 1953 } 1954 1955 /* now insert grants to group if more than world */ 1956 if (pset->adminowns 1957 || pset->groupowns 1958 || (avoidmask && (pset->designates || pset->withmask)) 1959 || (perms & ~pset->othperms) 1960 || (pset->rootspecial 1961 && (tag == POSIX_ACL_GROUP_OBJ)) 1962 || (tag == POSIX_ACL_GROUP)) { 1963 if (rootgroup) 1964 grants &= ~ROOT_GROUP_UNMARK; 1965 pgace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos]; 1966 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 1967 pgace->flags = flags; 1968 pgace->size = cpu_to_le16(sidsz + 8); 1969 pgace->mask = grants; 1970 memcpy((char*)&pgace->sid, sid, sidsz); 1971 pos += sidsz + 8; 1972 acecnt++; 1973 } 1974 } 1975 pacl->size = cpu_to_le16(pos); 1976 pacl->ace_count = cpu_to_le16(acecnt); 1977 return (!rejected); 1978 } 1979 1980 1981 /* 1982 * Build an ACL composed of several ACE's 1983 * returns size of ACL or zero if failed 1984 * 1985 * Three schemes are defined : 1986 * 1987 * 1) if root is neither owner nor group up to 7 ACE's are set up : 1988 * - denials to owner (preventing grants to world or group to apply) 1989 * + mask denials to designated user (unless mask allows all) 1990 * + denials to designated user 1991 * - grants to owner (always present - first grant) 1992 * + grants to designated user 1993 * + mask denial to group (unless mask allows all) 1994 * - denials to group (preventing grants to world to apply) 1995 * - grants to group (unless group has no more than world rights) 1996 * + mask denials to designated group (unless mask allows all) 1997 * + grants to designated group 1998 * + denials to designated group 1999 * - grants to world (unless none) 2000 * - full privileges to administrator, always present 2001 * - full privileges to system, always present 2002 * 2003 * The same scheme is applied for Posix ACLs, with the mask represented 2004 * as denials prepended to grants for designated users and groups 2005 * 2006 * This is inspired by an Internet Draft from Marius Aamodt Eriksen 2007 * for mapping NFSv4 ACLs to Posix ACLs (draft-ietf-nfsv4-acl-mapping-00.txt) 2008 * More recent versions of the draft (draft-ietf-nfsv4-acl-mapping-05.txt) 2009 * are not followed, as they ignore the Posix mask and lead to 2010 * loss of compatibility with Linux implementations on other fs. 2011 * 2012 * Note that denials to group are located after grants to owner. 2013 * This only occurs in the unfrequent situation where world 2014 * has more rights than group and cannot be avoided if owner and other 2015 * have some common right which is denied to group (eg for mode 745 2016 * executing has to be denied to group, but not to owner or world). 2017 * This rare situation is processed by Windows correctly, but 2018 * Windows utilities may want to change the order, with a 2019 * consequence of applying the group denials to the Windows owner. 2020 * The interpretation on Linux is not affected by the order change. 2021 * 2022 * 2) if root is either owner or group, two problems arise : 2023 * - granting full rights to administrator (as needed to transpose 2024 * to Windows rights bypassing granting to root) would imply 2025 * Linux permissions to always be seen as rwx, no matter the chmod 2026 * - there is no different SID to separate an administrator owner 2027 * from an administrator group. Hence Linux permissions for owner 2028 * would always be similar to permissions to group. 2029 * 2030 * as a work-around, up to 5 ACE's are set up if owner or group : 2031 * - grants to owner, always present at first position 2032 * - grants to group, always present 2033 * - grants to world, unless none 2034 * - full privileges to administrator, always present 2035 * - full privileges to system, always present 2036 * 2037 * On Windows, these ACE's are processed normally, though they 2038 * are redundant (owner, group and administrator are the same, 2039 * as a consequence any denials would damage administrator rights) 2040 * but on Linux, privileges to administrator are ignored (they 2041 * are not needed as root has always full privileges), and 2042 * neither grants to group are applied to owner, nor grants to 2043 * world are applied to owner or group. 2044 * 2045 * 3) finally a similar situation arises when group is owner (they 2046 * have the same SID), but is not root. 2047 * In this situation up to 6 ACE's are set up : 2048 * 2049 * - denials to owner (preventing grants to world to apply) 2050 * - grants to owner (always present) 2051 * - grants to group (unless groups has same rights as world) 2052 * - grants to world (unless none) 2053 * - full privileges to administrator, always present 2054 * - full privileges to system, always present 2055 * 2056 * On Windows, these ACE's are processed normally, though they 2057 * are redundant (as owner and group are the same), but this has 2058 * no impact on administrator rights 2059 * 2060 * Special flags (S_ISVTX, S_ISGID, S_ISUID) : 2061 * an extra null ACE is inserted to hold these flags, using 2062 * the same conventions as cygwin. 2063 * 2064 */ 2065 2066 static int buildacls_posix(struct MAPPING* const mapping[], 2067 char *secattr, int offs, const struct POSIX_SECURITY *pxdesc, 2068 int isdir, const SID *usid, const SID *gsid) 2069 { 2070 struct BUILD_CONTEXT aceset[2], *pset; 2071 BOOL adminowns; 2072 BOOL groupowns; 2073 ACL *pacl; 2074 ACCESS_ALLOWED_ACE *pgace; 2075 ACCESS_ALLOWED_ACE *pdace; 2076 const struct POSIX_ACE *pxace; 2077 BOOL ok; 2078 mode_t mode; 2079 u16 tag; 2080 u16 perms; 2081 ACE_FLAGS flags; 2082 int pos; 2083 int i; 2084 int k; 2085 BIGSID defsid; 2086 const SID *sid; 2087 int acecnt; 2088 int usidsz; 2089 int wsidsz; 2090 int asidsz; 2091 int ssidsz; 2092 int nsidsz; 2093 le32 grants; 2094 2095 usidsz = ntfs_sid_size(usid); 2096 wsidsz = ntfs_sid_size(worldsid); 2097 asidsz = ntfs_sid_size(adminsid); 2098 ssidsz = ntfs_sid_size(systemsid); 2099 mode = pxdesc->mode; 2100 /* adminowns and groupowns are used for both lists */ 2101 adminowns = ntfs_same_sid(usid, adminsid) 2102 || ntfs_same_sid(gsid, adminsid); 2103 groupowns = !adminowns && ntfs_same_sid(usid, gsid); 2104 2105 ok = TRUE; 2106 2107 /* ACL header */ 2108 pacl = (ACL*)&secattr[offs]; 2109 pacl->revision = ACL_REVISION; 2110 pacl->alignment1 = 0; 2111 pacl->size = cpu_to_le16(sizeof(ACL) + usidsz + 8); 2112 pacl->ace_count = const_cpu_to_le16(0); 2113 pacl->alignment2 = const_cpu_to_le16(0); 2114 2115 /* 2116 * Determine what is allowed to some group or world 2117 * to prevent designated users or other groups to get 2118 * rights from groups or world 2119 * Do the same if owner and group appear as designated 2120 * user or group 2121 * Also get global mask 2122 */ 2123 for (k=0; k<2; k++) { 2124 pset = &aceset[k]; 2125 pset->selfuserperms = 0; 2126 pset->selfgrpperms = 0; 2127 pset->grpperms = 0; 2128 pset->othperms = 0; 2129 pset->mask = (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X); 2130 pset->designates = 0; 2131 pset->withmask = 0; 2132 pset->rootspecial = 0; 2133 pset->adminowns = adminowns; 2134 pset->groupowns = groupowns; 2135 pset->isdir = isdir; 2136 } 2137 2138 for (i=pxdesc->acccnt+pxdesc->defcnt-1; i>=0; i--) { 2139 if (i >= pxdesc->acccnt) { 2140 pset = &aceset[1]; 2141 pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt]; 2142 } else { 2143 pset = &aceset[0]; 2144 pxace = &pxdesc->acl.ace[i]; 2145 } 2146 switch (pxace->tag) { 2147 case POSIX_ACL_USER : 2148 pset->designates++; 2149 if (pxace->id) { 2150 sid = ntfs_find_usid(mapping[MAPUSERS], 2151 pxace->id, (SID*)&defsid); 2152 if (sid && ntfs_same_sid(sid,usid)) 2153 pset->selfuserperms |= pxace->perms; 2154 } else 2155 /* root as designated user is processed apart */ 2156 pset->rootspecial = TRUE; 2157 break; 2158 case POSIX_ACL_GROUP : 2159 pset->designates++; 2160 if (pxace->id) { 2161 sid = ntfs_find_gsid(mapping[MAPUSERS], 2162 pxace->id, (SID*)&defsid); 2163 if (sid && ntfs_same_sid(sid,gsid)) 2164 pset->selfgrpperms |= pxace->perms; 2165 } else 2166 /* root as designated group is processed apart */ 2167 pset->rootspecial = TRUE; 2168 /* fall through */ 2169 case POSIX_ACL_GROUP_OBJ : 2170 pset->grpperms |= pxace->perms; 2171 break; 2172 case POSIX_ACL_OTHER : 2173 pset->othperms = pxace->perms; 2174 break; 2175 case POSIX_ACL_MASK : 2176 pset->withmask++; 2177 pset->mask = pxace->perms; 2178 default : 2179 break; 2180 } 2181 } 2182 2183 if (pxdesc->defcnt && (pxdesc->firstdef != pxdesc->acccnt)) { 2184 ntfs_log_error("** error : access and default not consecutive\n"); 2185 return (0); 2186 } 2187 /* 2188 * First insert all denials for owner and each 2189 * designated user (with mask if needed) 2190 */ 2191 2192 pacl->ace_count = const_cpu_to_le16(0); 2193 pacl->size = const_cpu_to_le16(sizeof(ACL)); 2194 for (i=0; (i<(pxdesc->acccnt + pxdesc->defcnt)) && ok; i++) { 2195 if (i >= pxdesc->acccnt) { 2196 flags = INHERIT_ONLY_ACE 2197 | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 2198 pset = &aceset[1]; 2199 pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt]; 2200 } else { 2201 if (pxdesc->defcnt) 2202 flags = NO_PROPAGATE_INHERIT_ACE; 2203 else 2204 flags = (isdir ? DIR_INHERITANCE 2205 : FILE_INHERITANCE); 2206 pset = &aceset[0]; 2207 pxace = &pxdesc->acl.ace[i]; 2208 } 2209 tag = pxace->tag; 2210 perms = pxace->perms; 2211 switch (tag) { 2212 2213 /* insert denial ACEs for each owner or allowed user */ 2214 2215 case POSIX_ACL_USER : 2216 case POSIX_ACL_USER_OBJ : 2217 2218 ok = build_user_denials(pacl, 2219 usid, mapping, flags, pxace, pset); 2220 break; 2221 default : 2222 break; 2223 } 2224 } 2225 2226 /* 2227 * for directories, insert a world execution denial 2228 * inherited to plain files. 2229 * This is to prevent Windows from granting execution 2230 * of files through inheritance from parent directory 2231 */ 2232 2233 if (isdir && ok) { 2234 pos = le16_to_cpu(pacl->size); 2235 pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos]; 2236 pdace->type = ACCESS_DENIED_ACE_TYPE; 2237 pdace->flags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; 2238 pdace->size = cpu_to_le16(wsidsz + 8); 2239 pdace->mask = FILE_EXEC; 2240 memcpy((char*)&pdace->sid, worldsid, wsidsz); 2241 pos += wsidsz + 8; 2242 acecnt = le16_to_cpu(pacl->ace_count) + 1; 2243 pacl->ace_count = cpu_to_le16(acecnt); 2244 pacl->size = cpu_to_le16(pos); 2245 } 2246 2247 /* 2248 * now insert (if needed) 2249 * - grants to owner and designated users 2250 * - mask and denials for all groups 2251 * - grants to other 2252 */ 2253 2254 for (i=0; (i<(pxdesc->acccnt + pxdesc->defcnt)) && ok; i++) { 2255 if (i >= pxdesc->acccnt) { 2256 flags = INHERIT_ONLY_ACE 2257 | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 2258 pset = &aceset[1]; 2259 pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt]; 2260 } else { 2261 if (pxdesc->defcnt) 2262 flags = NO_PROPAGATE_INHERIT_ACE; 2263 else 2264 flags = (isdir ? DIR_INHERITANCE 2265 : FILE_INHERITANCE); 2266 pset = &aceset[0]; 2267 pxace = &pxdesc->acl.ace[i]; 2268 } 2269 tag = pxace->tag; 2270 perms = pxace->perms; 2271 switch (tag) { 2272 2273 /* ACE for each owner or allowed user */ 2274 2275 case POSIX_ACL_USER : 2276 case POSIX_ACL_USER_OBJ : 2277 ok = build_user_grants(pacl,usid, 2278 mapping,flags,pxace,pset); 2279 break; 2280 2281 case POSIX_ACL_GROUP_OBJ : 2282 /* denials and grants for group when needed */ 2283 if (pset->groupowns && !pset->adminowns 2284 && (pset->grpperms == pset->othperms) 2285 && !pset->designates && !pset->withmask) { 2286 ok = TRUE; 2287 } else { 2288 ok = build_group_denials_grant(pacl,gsid, 2289 mapping,flags,pxace,pset); 2290 } 2291 break; 2292 2293 case POSIX_ACL_GROUP : 2294 2295 /* denials and grants for designated groups */ 2296 2297 ok = build_group_denials_grant(pacl,gsid, 2298 mapping,flags,pxace,pset); 2299 break; 2300 2301 case POSIX_ACL_OTHER : 2302 2303 /* grants for other users */ 2304 2305 pos = le16_to_cpu(pacl->size); 2306 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2307 grants = WORLD_RIGHTS; 2308 if (isdir) { 2309 if (perms & POSIX_PERM_X) 2310 grants |= DIR_EXEC; 2311 if (perms & POSIX_PERM_W) 2312 grants |= DIR_WRITE; 2313 if (perms & POSIX_PERM_R) 2314 grants |= DIR_READ; 2315 } else { 2316 if (perms & POSIX_PERM_X) 2317 grants |= FILE_EXEC; 2318 if (perms & POSIX_PERM_W) 2319 grants |= FILE_WRITE; 2320 if (perms & POSIX_PERM_R) 2321 grants |= FILE_READ; 2322 } 2323 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2324 pgace->flags = flags; 2325 pgace->size = cpu_to_le16(wsidsz + 8); 2326 pgace->mask = grants; 2327 memcpy((char*)&pgace->sid, worldsid, wsidsz); 2328 pos += wsidsz + 8; 2329 acecnt = le16_to_cpu(pacl->ace_count) + 1; 2330 pacl->ace_count = cpu_to_le16(acecnt); 2331 pacl->size = cpu_to_le16(pos); 2332 break; 2333 } 2334 } 2335 2336 if (!ok) { 2337 errno = EINVAL; 2338 pos = 0; 2339 } else { 2340 /* an ACE for administrators */ 2341 /* always full access */ 2342 2343 pos = le16_to_cpu(pacl->size); 2344 acecnt = le16_to_cpu(pacl->ace_count); 2345 if (isdir) 2346 flags = OBJECT_INHERIT_ACE 2347 | CONTAINER_INHERIT_ACE; 2348 else 2349 flags = NO_PROPAGATE_INHERIT_ACE; 2350 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2351 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2352 pgace->flags = flags; 2353 pgace->size = cpu_to_le16(asidsz + 8); 2354 grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC; 2355 pgace->mask = grants; 2356 memcpy((char*)&pgace->sid, adminsid, asidsz); 2357 pos += asidsz + 8; 2358 acecnt++; 2359 2360 /* an ACE for system (needed ?) */ 2361 /* always full access */ 2362 2363 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2364 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2365 pgace->flags = flags; 2366 pgace->size = cpu_to_le16(ssidsz + 8); 2367 grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC; 2368 pgace->mask = grants; 2369 memcpy((char*)&pgace->sid, systemsid, ssidsz); 2370 pos += ssidsz + 8; 2371 acecnt++; 2372 2373 /* a null ACE to hold special flags */ 2374 /* using the same representation as cygwin */ 2375 2376 if (mode & (S_ISVTX | S_ISGID | S_ISUID)) { 2377 nsidsz = ntfs_sid_size(nullsid); 2378 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2379 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2380 pgace->flags = NO_PROPAGATE_INHERIT_ACE; 2381 pgace->size = cpu_to_le16(nsidsz + 8); 2382 grants = const_cpu_to_le32(0); 2383 if (mode & S_ISUID) 2384 grants |= FILE_APPEND_DATA; 2385 if (mode & S_ISGID) 2386 grants |= FILE_WRITE_DATA; 2387 if (mode & S_ISVTX) 2388 grants |= FILE_READ_DATA; 2389 pgace->mask = grants; 2390 memcpy((char*)&pgace->sid, nullsid, nsidsz); 2391 pos += nsidsz + 8; 2392 acecnt++; 2393 } 2394 2395 /* fix ACL header */ 2396 pacl->size = cpu_to_le16(pos); 2397 pacl->ace_count = cpu_to_le16(acecnt); 2398 } 2399 return (ok ? pos : 0); 2400 } 2401 2402 #endif /* POSIXACLS */ 2403 2404 static int buildacls(char *secattr, int offs, mode_t mode, int isdir, 2405 const SID * usid, const SID * gsid) 2406 { 2407 ACL *pacl; 2408 ACCESS_ALLOWED_ACE *pgace; 2409 ACCESS_ALLOWED_ACE *pdace; 2410 BOOL adminowns; 2411 BOOL groupowns; 2412 ACE_FLAGS gflags; 2413 int pos; 2414 int acecnt; 2415 int usidsz; 2416 int gsidsz; 2417 int wsidsz; 2418 int asidsz; 2419 int ssidsz; 2420 int nsidsz; 2421 le32 grants; 2422 le32 denials; 2423 2424 usidsz = ntfs_sid_size(usid); 2425 gsidsz = ntfs_sid_size(gsid); 2426 wsidsz = ntfs_sid_size(worldsid); 2427 asidsz = ntfs_sid_size(adminsid); 2428 ssidsz = ntfs_sid_size(systemsid); 2429 adminowns = ntfs_same_sid(usid, adminsid) 2430 || ntfs_same_sid(gsid, adminsid); 2431 groupowns = !adminowns && ntfs_same_sid(usid, gsid); 2432 2433 /* ACL header */ 2434 pacl = (ACL*)&secattr[offs]; 2435 pacl->revision = ACL_REVISION; 2436 pacl->alignment1 = 0; 2437 pacl->size = cpu_to_le16(sizeof(ACL) + usidsz + 8); 2438 pacl->ace_count = const_cpu_to_le16(1); 2439 pacl->alignment2 = const_cpu_to_le16(0); 2440 pos = sizeof(ACL); 2441 acecnt = 0; 2442 2443 /* compute a grant ACE for owner */ 2444 /* this ACE will be inserted after denial for owner */ 2445 2446 grants = OWNER_RIGHTS; 2447 if (isdir) { 2448 gflags = DIR_INHERITANCE; 2449 if (mode & S_IXUSR) 2450 grants |= DIR_EXEC; 2451 if (mode & S_IWUSR) 2452 grants |= DIR_WRITE; 2453 if (mode & S_IRUSR) 2454 grants |= DIR_READ; 2455 } else { 2456 gflags = FILE_INHERITANCE; 2457 if (mode & S_IXUSR) 2458 grants |= FILE_EXEC; 2459 if (mode & S_IWUSR) 2460 grants |= FILE_WRITE; 2461 if (mode & S_IRUSR) 2462 grants |= FILE_READ; 2463 } 2464 2465 /* a possible ACE to deny owner what he/she would */ 2466 /* induely get from administrator, group or world */ 2467 /* unless owner is administrator or group */ 2468 2469 denials = const_cpu_to_le32(0); 2470 pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos]; 2471 if (!adminowns) { 2472 if (!groupowns) { 2473 if (isdir) { 2474 pdace->flags = DIR_INHERITANCE; 2475 if (mode & (S_IXGRP | S_IXOTH)) 2476 denials |= DIR_EXEC; 2477 if (mode & (S_IWGRP | S_IWOTH)) 2478 denials |= DIR_WRITE; 2479 if (mode & (S_IRGRP | S_IROTH)) 2480 denials |= DIR_READ; 2481 } else { 2482 pdace->flags = FILE_INHERITANCE; 2483 if (mode & (S_IXGRP | S_IXOTH)) 2484 denials |= FILE_EXEC; 2485 if (mode & (S_IWGRP | S_IWOTH)) 2486 denials |= FILE_WRITE; 2487 if (mode & (S_IRGRP | S_IROTH)) 2488 denials |= FILE_READ; 2489 } 2490 } else { 2491 if (isdir) { 2492 pdace->flags = DIR_INHERITANCE; 2493 if ((mode & S_IXOTH) && !(mode & S_IXGRP)) 2494 denials |= DIR_EXEC; 2495 if ((mode & S_IWOTH) && !(mode & S_IWGRP)) 2496 denials |= DIR_WRITE; 2497 if ((mode & S_IROTH) && !(mode & S_IRGRP)) 2498 denials |= DIR_READ; 2499 } else { 2500 pdace->flags = FILE_INHERITANCE; 2501 if ((mode & S_IXOTH) && !(mode & S_IXGRP)) 2502 denials |= FILE_EXEC; 2503 if ((mode & S_IWOTH) && !(mode & S_IWGRP)) 2504 denials |= FILE_WRITE; 2505 if ((mode & S_IROTH) && !(mode & S_IRGRP)) 2506 denials |= FILE_READ; 2507 } 2508 } 2509 denials &= ~grants; 2510 if (denials) { 2511 pdace->type = ACCESS_DENIED_ACE_TYPE; 2512 pdace->size = cpu_to_le16(usidsz + 8); 2513 pdace->mask = denials; 2514 memcpy((char*)&pdace->sid, usid, usidsz); 2515 pos += usidsz + 8; 2516 acecnt++; 2517 } 2518 } 2519 /* 2520 * for directories, a world execution denial 2521 * inherited to plain files 2522 */ 2523 2524 if (isdir) { 2525 pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos]; 2526 pdace->type = ACCESS_DENIED_ACE_TYPE; 2527 pdace->flags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; 2528 pdace->size = cpu_to_le16(wsidsz + 8); 2529 pdace->mask = FILE_EXEC; 2530 memcpy((char*)&pdace->sid, worldsid, wsidsz); 2531 pos += wsidsz + 8; 2532 acecnt++; 2533 } 2534 2535 2536 /* now insert grants to owner */ 2537 pgace = (ACCESS_ALLOWED_ACE*) &secattr[offs + pos]; 2538 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2539 pgace->size = cpu_to_le16(usidsz + 8); 2540 pgace->flags = gflags; 2541 pgace->mask = grants; 2542 memcpy((char*)&pgace->sid, usid, usidsz); 2543 pos += usidsz + 8; 2544 acecnt++; 2545 2546 /* a grant ACE for group */ 2547 /* unless group has the same rights as world */ 2548 /* but present if group is owner or owner is administrator */ 2549 /* this ACE will be inserted after denials for group */ 2550 2551 if (adminowns 2552 || (((mode >> 3) ^ mode) & 7)) { 2553 grants = WORLD_RIGHTS; 2554 if (isdir) { 2555 gflags = DIR_INHERITANCE; 2556 if (mode & S_IXGRP) 2557 grants |= DIR_EXEC; 2558 if (mode & S_IWGRP) 2559 grants |= DIR_WRITE; 2560 if (mode & S_IRGRP) 2561 grants |= DIR_READ; 2562 } else { 2563 gflags = FILE_INHERITANCE; 2564 if (mode & S_IXGRP) 2565 grants |= FILE_EXEC; 2566 if (mode & S_IWGRP) 2567 grants |= FILE_WRITE; 2568 if (mode & S_IRGRP) 2569 grants |= FILE_READ; 2570 } 2571 2572 /* a possible ACE to deny group what it would get from world */ 2573 /* or administrator, unless owner is administrator or group */ 2574 2575 denials = const_cpu_to_le32(0); 2576 pdace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2577 if (!adminowns && !groupowns) { 2578 if (isdir) { 2579 pdace->flags = DIR_INHERITANCE; 2580 if (mode & S_IXOTH) 2581 denials |= DIR_EXEC; 2582 if (mode & S_IWOTH) 2583 denials |= DIR_WRITE; 2584 if (mode & S_IROTH) 2585 denials |= DIR_READ; 2586 } else { 2587 pdace->flags = FILE_INHERITANCE; 2588 if (mode & S_IXOTH) 2589 denials |= FILE_EXEC; 2590 if (mode & S_IWOTH) 2591 denials |= FILE_WRITE; 2592 if (mode & S_IROTH) 2593 denials |= FILE_READ; 2594 } 2595 denials &= ~(grants | OWNER_RIGHTS); 2596 if (denials) { 2597 pdace->type = ACCESS_DENIED_ACE_TYPE; 2598 pdace->size = cpu_to_le16(gsidsz + 8); 2599 pdace->mask = denials; 2600 memcpy((char*)&pdace->sid, gsid, gsidsz); 2601 pos += gsidsz + 8; 2602 acecnt++; 2603 } 2604 } 2605 2606 if (adminowns 2607 || groupowns 2608 || ((mode >> 3) & ~mode & 7)) { 2609 /* now insert grants to group */ 2610 /* if more rights than other */ 2611 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2612 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2613 pgace->flags = gflags; 2614 pgace->size = cpu_to_le16(gsidsz + 8); 2615 pgace->mask = grants; 2616 memcpy((char*)&pgace->sid, gsid, gsidsz); 2617 pos += gsidsz + 8; 2618 acecnt++; 2619 } 2620 } 2621 2622 /* an ACE for world users */ 2623 2624 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2625 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2626 grants = WORLD_RIGHTS; 2627 if (isdir) { 2628 pgace->flags = DIR_INHERITANCE; 2629 if (mode & S_IXOTH) 2630 grants |= DIR_EXEC; 2631 if (mode & S_IWOTH) 2632 grants |= DIR_WRITE; 2633 if (mode & S_IROTH) 2634 grants |= DIR_READ; 2635 } else { 2636 pgace->flags = FILE_INHERITANCE; 2637 if (mode & S_IXOTH) 2638 grants |= FILE_EXEC; 2639 if (mode & S_IWOTH) 2640 grants |= FILE_WRITE; 2641 if (mode & S_IROTH) 2642 grants |= FILE_READ; 2643 } 2644 pgace->size = cpu_to_le16(wsidsz + 8); 2645 pgace->mask = grants; 2646 memcpy((char*)&pgace->sid, worldsid, wsidsz); 2647 pos += wsidsz + 8; 2648 acecnt++; 2649 2650 /* an ACE for administrators */ 2651 /* always full access */ 2652 2653 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2654 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2655 if (isdir) 2656 pgace->flags = DIR_INHERITANCE; 2657 else 2658 pgace->flags = FILE_INHERITANCE; 2659 pgace->size = cpu_to_le16(asidsz + 8); 2660 grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC; 2661 pgace->mask = grants; 2662 memcpy((char*)&pgace->sid, adminsid, asidsz); 2663 pos += asidsz + 8; 2664 acecnt++; 2665 2666 /* an ACE for system (needed ?) */ 2667 /* always full access */ 2668 2669 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2670 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2671 if (isdir) 2672 pgace->flags = DIR_INHERITANCE; 2673 else 2674 pgace->flags = FILE_INHERITANCE; 2675 pgace->size = cpu_to_le16(ssidsz + 8); 2676 grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC; 2677 pgace->mask = grants; 2678 memcpy((char*)&pgace->sid, systemsid, ssidsz); 2679 pos += ssidsz + 8; 2680 acecnt++; 2681 2682 /* a null ACE to hold special flags */ 2683 /* using the same representation as cygwin */ 2684 2685 if (mode & (S_ISVTX | S_ISGID | S_ISUID)) { 2686 nsidsz = ntfs_sid_size(nullsid); 2687 pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos]; 2688 pgace->type = ACCESS_ALLOWED_ACE_TYPE; 2689 pgace->flags = NO_PROPAGATE_INHERIT_ACE; 2690 pgace->size = cpu_to_le16(nsidsz + 8); 2691 grants = const_cpu_to_le32(0); 2692 if (mode & S_ISUID) 2693 grants |= FILE_APPEND_DATA; 2694 if (mode & S_ISGID) 2695 grants |= FILE_WRITE_DATA; 2696 if (mode & S_ISVTX) 2697 grants |= FILE_READ_DATA; 2698 pgace->mask = grants; 2699 memcpy((char*)&pgace->sid, nullsid, nsidsz); 2700 pos += nsidsz + 8; 2701 acecnt++; 2702 } 2703 2704 /* fix ACL header */ 2705 pacl->size = cpu_to_le16(pos); 2706 pacl->ace_count = cpu_to_le16(acecnt); 2707 return (pos); 2708 } 2709 2710 #if POSIXACLS 2711 2712 /* 2713 * Build a full security descriptor from a Posix ACL 2714 * returns descriptor in allocated memory, must free() after use 2715 */ 2716 2717 char *ntfs_build_descr_posix(struct MAPPING* const mapping[], 2718 struct POSIX_SECURITY *pxdesc, 2719 int isdir, const SID *usid, const SID *gsid) 2720 { 2721 int newattrsz; 2722 SECURITY_DESCRIPTOR_RELATIVE *pnhead; 2723 char *newattr; 2724 int aclsz; 2725 int usidsz; 2726 int gsidsz; 2727 int wsidsz; 2728 int asidsz; 2729 int ssidsz; 2730 int k; 2731 2732 usidsz = ntfs_sid_size(usid); 2733 gsidsz = ntfs_sid_size(gsid); 2734 wsidsz = ntfs_sid_size(worldsid); 2735 asidsz = ntfs_sid_size(adminsid); 2736 ssidsz = ntfs_sid_size(systemsid); 2737 2738 /* allocate enough space for the new security attribute */ 2739 newattrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE) /* header */ 2740 + usidsz + gsidsz /* usid and gsid */ 2741 + sizeof(ACL) /* acl header */ 2742 + 2*(8 + usidsz) /* two possible ACE for user */ 2743 + 3*(8 + gsidsz) /* three possible ACE for group and mask */ 2744 + 8 + wsidsz /* one ACE for world */ 2745 + 8 + asidsz /* one ACE for admin */ 2746 + 8 + ssidsz; /* one ACE for system */ 2747 if (isdir) /* a world denial for directories */ 2748 newattrsz += 8 + wsidsz; 2749 if (pxdesc->mode & 07000) /* a NULL ACE for special modes */ 2750 newattrsz += 8 + ntfs_sid_size(nullsid); 2751 /* account for non-owning users and groups */ 2752 for (k=0; k<pxdesc->acccnt; k++) { 2753 if ((pxdesc->acl.ace[k].tag == POSIX_ACL_USER) 2754 || (pxdesc->acl.ace[k].tag == POSIX_ACL_GROUP)) 2755 newattrsz += 3*MAX_SID_SIZE; 2756 } 2757 /* account for default ACE's */ 2758 newattrsz += 2*MAX_SID_SIZE*pxdesc->defcnt; 2759 newattr = (char*)ntfs_malloc(newattrsz); 2760 if (newattr) { 2761 /* build the main header part */ 2762 pnhead = (SECURITY_DESCRIPTOR_RELATIVE*)newattr; 2763 pnhead->revision = SECURITY_DESCRIPTOR_REVISION; 2764 pnhead->alignment = 0; 2765 /* 2766 * The flag SE_DACL_PROTECTED prevents the ACL 2767 * to be changed in an inheritance after creation 2768 */ 2769 pnhead->control = SE_DACL_PRESENT | SE_DACL_PROTECTED 2770 | SE_SELF_RELATIVE; 2771 /* 2772 * Windows prefers ACL first, do the same to 2773 * get the same hash value and avoid duplication 2774 */ 2775 /* build permissions */ 2776 aclsz = buildacls_posix(mapping,newattr, 2777 sizeof(SECURITY_DESCRIPTOR_RELATIVE), 2778 pxdesc, isdir, usid, gsid); 2779 if (aclsz && ((int)(sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2780 + aclsz + usidsz + gsidsz) <= newattrsz)) { 2781 /* append usid and gsid */ 2782 memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2783 + aclsz], usid, usidsz); 2784 memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2785 + aclsz + usidsz], gsid, gsidsz); 2786 /* positions of ACL, USID and GSID into header */ 2787 pnhead->owner = 2788 cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2789 + aclsz); 2790 pnhead->group = 2791 cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2792 + aclsz + usidsz); 2793 pnhead->sacl = const_cpu_to_le32(0); 2794 pnhead->dacl = 2795 const_cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)); 2796 } else { 2797 /* ACL failure (errno set) or overflow */ 2798 free(newattr); 2799 newattr = (char*)NULL; 2800 if (aclsz) { 2801 /* hope error was detected before overflowing */ 2802 ntfs_log_error("Security descriptor is longer than expected\n"); 2803 errno = EIO; 2804 } 2805 } 2806 } else 2807 errno = ENOMEM; 2808 return (newattr); 2809 } 2810 2811 #endif /* POSIXACLS */ 2812 2813 /* 2814 * Build a full security descriptor 2815 * returns descriptor in allocated memory, must free() after use 2816 */ 2817 2818 char *ntfs_build_descr(mode_t mode, 2819 int isdir, const SID * usid, const SID * gsid) 2820 { 2821 int newattrsz; 2822 SECURITY_DESCRIPTOR_RELATIVE *pnhead; 2823 char *newattr; 2824 int aclsz; 2825 int usidsz; 2826 int gsidsz; 2827 int wsidsz; 2828 int asidsz; 2829 int ssidsz; 2830 2831 usidsz = ntfs_sid_size(usid); 2832 gsidsz = ntfs_sid_size(gsid); 2833 wsidsz = ntfs_sid_size(worldsid); 2834 asidsz = ntfs_sid_size(adminsid); 2835 ssidsz = ntfs_sid_size(systemsid); 2836 2837 /* allocate enough space for the new security attribute */ 2838 newattrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE) /* header */ 2839 + usidsz + gsidsz /* usid and gsid */ 2840 + sizeof(ACL) /* acl header */ 2841 + 2*(8 + usidsz) /* two possible ACE for user */ 2842 + 2*(8 + gsidsz) /* two possible ACE for group */ 2843 + 8 + wsidsz /* one ACE for world */ 2844 + 8 + asidsz /* one ACE for admin */ 2845 + 8 + ssidsz; /* one ACE for system */ 2846 if (isdir) /* a world denial for directories */ 2847 newattrsz += 8 + wsidsz; 2848 if (mode & 07000) /* a NULL ACE for special modes */ 2849 newattrsz += 8 + ntfs_sid_size(nullsid); 2850 newattr = (char*)ntfs_malloc(newattrsz); 2851 if (newattr) { 2852 /* build the main header part */ 2853 pnhead = (SECURITY_DESCRIPTOR_RELATIVE*) newattr; 2854 pnhead->revision = SECURITY_DESCRIPTOR_REVISION; 2855 pnhead->alignment = 0; 2856 /* 2857 * The flag SE_DACL_PROTECTED prevents the ACL 2858 * to be changed in an inheritance after creation 2859 */ 2860 pnhead->control = SE_DACL_PRESENT | SE_DACL_PROTECTED 2861 | SE_SELF_RELATIVE; 2862 /* 2863 * Windows prefers ACL first, do the same to 2864 * get the same hash value and avoid duplication 2865 */ 2866 /* build permissions */ 2867 aclsz = buildacls(newattr, 2868 sizeof(SECURITY_DESCRIPTOR_RELATIVE), 2869 mode, isdir, usid, gsid); 2870 if (((int)sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2871 + aclsz + usidsz + gsidsz) <= newattrsz) { 2872 /* append usid and gsid */ 2873 memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2874 + aclsz], usid, usidsz); 2875 memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2876 + aclsz + usidsz], gsid, gsidsz); 2877 /* positions of ACL, USID and GSID into header */ 2878 pnhead->owner = 2879 cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2880 + aclsz); 2881 pnhead->group = 2882 cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE) 2883 + aclsz + usidsz); 2884 pnhead->sacl = const_cpu_to_le32(0); 2885 pnhead->dacl = 2886 const_cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)); 2887 } else { 2888 /* hope error was detected before overflowing */ 2889 free(newattr); 2890 newattr = (char*)NULL; 2891 ntfs_log_error("Security descriptor is longer than expected\n"); 2892 errno = EIO; 2893 } 2894 } else 2895 errno = ENOMEM; 2896 return (newattr); 2897 } 2898 2899 /* 2900 * Create a mode_t permission set 2901 * from owner, group and world grants as represented in ACEs 2902 */ 2903 2904 static int merge_permissions(BOOL isdir, 2905 le32 owner, le32 group, le32 world, le32 special) 2906 2907 { 2908 int perm; 2909 2910 perm = 0; 2911 /* build owner permission */ 2912 if (owner) { 2913 if (isdir) { 2914 /* exec if any of list, traverse */ 2915 if (owner & DIR_GEXEC) 2916 perm |= S_IXUSR; 2917 /* write if any of addfile, adddir, delchild */ 2918 if (owner & DIR_GWRITE) 2919 perm |= S_IWUSR; 2920 /* read if any of list */ 2921 if (owner & DIR_GREAD) 2922 perm |= S_IRUSR; 2923 } else { 2924 /* exec if execute or generic execute */ 2925 if (owner & FILE_GEXEC) 2926 perm |= S_IXUSR; 2927 /* write if any of writedata or generic write */ 2928 if (owner & FILE_GWRITE) 2929 perm |= S_IWUSR; 2930 /* read if any of readdata or generic read */ 2931 if (owner & FILE_GREAD) 2932 perm |= S_IRUSR; 2933 } 2934 } 2935 /* build group permission */ 2936 if (group) { 2937 if (isdir) { 2938 /* exec if any of list, traverse */ 2939 if (group & DIR_GEXEC) 2940 perm |= S_IXGRP; 2941 /* write if any of addfile, adddir, delchild */ 2942 if (group & DIR_GWRITE) 2943 perm |= S_IWGRP; 2944 /* read if any of list */ 2945 if (group & DIR_GREAD) 2946 perm |= S_IRGRP; 2947 } else { 2948 /* exec if execute */ 2949 if (group & FILE_GEXEC) 2950 perm |= S_IXGRP; 2951 /* write if any of writedata, appenddata */ 2952 if (group & FILE_GWRITE) 2953 perm |= S_IWGRP; 2954 /* read if any of readdata */ 2955 if (group & FILE_GREAD) 2956 perm |= S_IRGRP; 2957 } 2958 } 2959 /* build world permission */ 2960 if (world) { 2961 if (isdir) { 2962 /* exec if any of list, traverse */ 2963 if (world & DIR_GEXEC) 2964 perm |= S_IXOTH; 2965 /* write if any of addfile, adddir, delchild */ 2966 if (world & DIR_GWRITE) 2967 perm |= S_IWOTH; 2968 /* read if any of list */ 2969 if (world & DIR_GREAD) 2970 perm |= S_IROTH; 2971 } else { 2972 /* exec if execute */ 2973 if (world & FILE_GEXEC) 2974 perm |= S_IXOTH; 2975 /* write if any of writedata, appenddata */ 2976 if (world & FILE_GWRITE) 2977 perm |= S_IWOTH; 2978 /* read if any of readdata */ 2979 if (world & FILE_GREAD) 2980 perm |= S_IROTH; 2981 } 2982 } 2983 /* build special permission flags */ 2984 if (special) { 2985 if (special & FILE_APPEND_DATA) 2986 perm |= S_ISUID; 2987 if (special & FILE_WRITE_DATA) 2988 perm |= S_ISGID; 2989 if (special & FILE_READ_DATA) 2990 perm |= S_ISVTX; 2991 } 2992 return (perm); 2993 } 2994 2995 #if POSIXACLS 2996 2997 /* 2998 * Normalize a Posix ACL either from a sorted raw set of 2999 * access ACEs or default ACEs 3000 * (standard case : different owner, group and administrator) 3001 */ 3002 3003 static int norm_std_permissions_posix(struct POSIX_SECURITY *posix_desc, 3004 BOOL groupowns, int start, int count, int target) 3005 { 3006 int j,k; 3007 s32 id; 3008 u16 tag; 3009 u16 tagsset; 3010 struct POSIX_ACE *pxace; 3011 mode_t grantgrps; 3012 mode_t grantwrld; 3013 mode_t denywrld; 3014 mode_t allow; 3015 mode_t deny; 3016 mode_t perms; 3017 mode_t mode; 3018 3019 mode = 0; 3020 tagsset = 0; 3021 /* 3022 * Determine what is granted to some group or world 3023 * Also get denials to world which are meant to prevent 3024 * execution flags to be inherited by plain files 3025 */ 3026 pxace = posix_desc->acl.ace; 3027 grantgrps = 0; 3028 grantwrld = 0; 3029 denywrld = 0; 3030 for (j=start; j<(start + count); j++) { 3031 if (pxace[j].perms & POSIX_PERM_DENIAL) { 3032 /* deny world exec unless for default */ 3033 if ((pxace[j].tag == POSIX_ACL_OTHER) 3034 && !start) 3035 denywrld = pxace[j].perms; 3036 } else { 3037 switch (pxace[j].tag) { 3038 case POSIX_ACL_GROUP_OBJ : 3039 grantgrps |= pxace[j].perms; 3040 break; 3041 case POSIX_ACL_GROUP : 3042 if (pxace[j].id) 3043 grantgrps |= pxace[j].perms; 3044 break; 3045 case POSIX_ACL_OTHER : 3046 grantwrld = pxace[j].perms; 3047 break; 3048 default : 3049 break; 3050 } 3051 } 3052 } 3053 /* 3054 * Collect groups of ACEs related to the same id 3055 * and determine what is granted and what is denied. 3056 * It is important the ACEs have been sorted 3057 */ 3058 j = start; 3059 k = target; 3060 while (j < (start + count)) { 3061 tag = pxace[j].tag; 3062 id = pxace[j].id; 3063 if (pxace[j].perms & POSIX_PERM_DENIAL) { 3064 deny = pxace[j].perms | denywrld; 3065 allow = 0; 3066 } else { 3067 deny = denywrld; 3068 allow = pxace[j].perms; 3069 } 3070 j++; 3071 while ((j < (start + count)) 3072 && (pxace[j].tag == tag) 3073 && (pxace[j].id == id)) { 3074 if (pxace[j].perms & POSIX_PERM_DENIAL) 3075 deny |= pxace[j].perms; 3076 else 3077 allow |= pxace[j].perms; 3078 j++; 3079 } 3080 /* 3081 * Build the permissions equivalent to grants and denials 3082 */ 3083 if (groupowns) { 3084 if (tag == POSIX_ACL_MASK) 3085 perms = ~deny; 3086 else 3087 perms = allow & ~deny; 3088 } else 3089 switch (tag) { 3090 case POSIX_ACL_USER_OBJ : 3091 perms = (allow | grantgrps | grantwrld) & ~deny; 3092 break; 3093 case POSIX_ACL_USER : 3094 if (id) 3095 perms = (allow | grantgrps | grantwrld) 3096 & ~deny; 3097 else 3098 perms = allow; 3099 break; 3100 case POSIX_ACL_GROUP_OBJ : 3101 perms = (allow | grantwrld) & ~deny; 3102 break; 3103 case POSIX_ACL_GROUP : 3104 if (id) 3105 perms = (allow | grantwrld) & ~deny; 3106 else 3107 perms = allow; 3108 break; 3109 case POSIX_ACL_MASK : 3110 perms = ~deny; 3111 break; 3112 default : 3113 perms = allow & ~deny; 3114 break; 3115 } 3116 /* 3117 * Store into a Posix ACE 3118 */ 3119 if (tag != POSIX_ACL_SPECIAL) { 3120 pxace[k].tag = tag; 3121 pxace[k].id = id; 3122 pxace[k].perms = perms 3123 & (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X); 3124 tagsset |= tag; 3125 k++; 3126 } 3127 switch (tag) { 3128 case POSIX_ACL_USER_OBJ : 3129 mode |= ((perms & 7) << 6); 3130 break; 3131 case POSIX_ACL_GROUP_OBJ : 3132 case POSIX_ACL_MASK : 3133 mode = (mode & 07707) | ((perms & 7) << 3); 3134 break; 3135 case POSIX_ACL_OTHER : 3136 mode |= perms & 7; 3137 break; 3138 case POSIX_ACL_SPECIAL : 3139 mode |= (perms & (S_ISVTX | S_ISUID | S_ISGID)); 3140 break; 3141 default : 3142 break; 3143 } 3144 } 3145 if (!start) { /* not satisfactory */ 3146 posix_desc->mode = mode; 3147 posix_desc->tagsset = tagsset; 3148 } 3149 return (k - target); 3150 } 3151 3152 #endif /* POSIXACLS */ 3153 3154 /* 3155 * Interpret an ACL and extract meaningful grants 3156 * (standard case : different owner, group and administrator) 3157 */ 3158 3159 static int build_std_permissions(const char *securattr, 3160 const SID *usid, const SID *gsid, BOOL isdir) 3161 { 3162 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3163 const ACL *pacl; 3164 const ACCESS_ALLOWED_ACE *pace; 3165 int offdacl; 3166 int offace; 3167 int acecnt; 3168 int nace; 3169 BOOL noown; 3170 le32 special; 3171 le32 allowown, allowgrp, allowall; 3172 le32 denyown, denygrp, denyall; 3173 3174 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3175 offdacl = le32_to_cpu(phead->dacl); 3176 pacl = (const ACL*)&securattr[offdacl]; 3177 special = const_cpu_to_le32(0); 3178 allowown = allowgrp = allowall = const_cpu_to_le32(0); 3179 denyown = denygrp = denyall = const_cpu_to_le32(0); 3180 noown = TRUE; 3181 if (offdacl) { 3182 acecnt = le16_to_cpu(pacl->ace_count); 3183 offace = offdacl + sizeof(ACL); 3184 } else { 3185 acecnt = 0; 3186 offace = 0; 3187 } 3188 for (nace = 0; nace < acecnt; nace++) { 3189 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3190 if (!(pace->flags & INHERIT_ONLY_ACE)) { 3191 if (ntfs_same_sid(usid, &pace->sid) 3192 || ntfs_same_sid(ownersid, &pace->sid)) { 3193 noown = FALSE; 3194 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3195 allowown |= pace->mask; 3196 else if (pace->type == ACCESS_DENIED_ACE_TYPE) 3197 denyown |= pace->mask; 3198 } else 3199 if (ntfs_same_sid(gsid, &pace->sid) 3200 && !(pace->mask & WRITE_OWNER)) { 3201 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3202 allowgrp |= pace->mask; 3203 else if (pace->type == ACCESS_DENIED_ACE_TYPE) 3204 denygrp |= pace->mask; 3205 } else 3206 if (is_world_sid((const SID*)&pace->sid)) { 3207 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3208 allowall |= pace->mask; 3209 else 3210 if (pace->type == ACCESS_DENIED_ACE_TYPE) 3211 denyall |= pace->mask; 3212 } else 3213 if ((ntfs_same_sid((const SID*)&pace->sid,nullsid)) 3214 && (pace->type == ACCESS_ALLOWED_ACE_TYPE)) 3215 special |= pace->mask; 3216 } 3217 offace += le16_to_cpu(pace->size); 3218 } 3219 /* 3220 * No indication about owner's rights : grant basic rights 3221 * This happens for files created by Windows in directories 3222 * created by Linux and owned by root, because Windows 3223 * merges the admin ACEs 3224 */ 3225 if (noown) 3226 allowown = (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE); 3227 /* 3228 * Add to owner rights granted to group or world 3229 * unless denied personaly, and add to group rights 3230 * granted to world unless denied specifically 3231 */ 3232 allowown |= (allowgrp | allowall); 3233 allowgrp |= allowall; 3234 return (merge_permissions(isdir, 3235 allowown & ~(denyown | denyall), 3236 allowgrp & ~(denygrp | denyall), 3237 allowall & ~denyall, 3238 special)); 3239 } 3240 3241 /* 3242 * Interpret an ACL and extract meaningful grants 3243 * (special case : owner and group are the same, 3244 * and not administrator) 3245 */ 3246 3247 static int build_owngrp_permissions(const char *securattr, 3248 const SID *usid, BOOL isdir) 3249 { 3250 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3251 const ACL *pacl; 3252 const ACCESS_ALLOWED_ACE *pace; 3253 int offdacl; 3254 int offace; 3255 int acecnt; 3256 int nace; 3257 le32 special; 3258 BOOL grppresent; 3259 BOOL ownpresent; 3260 le32 allowown, allowgrp, allowall; 3261 le32 denyown, denygrp, denyall; 3262 3263 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3264 offdacl = le32_to_cpu(phead->dacl); 3265 pacl = (const ACL*)&securattr[offdacl]; 3266 special = const_cpu_to_le32(0); 3267 allowown = allowgrp = allowall = const_cpu_to_le32(0); 3268 denyown = denygrp = denyall = const_cpu_to_le32(0); 3269 ownpresent = FALSE; 3270 grppresent = FALSE; 3271 if (offdacl) { 3272 acecnt = le16_to_cpu(pacl->ace_count); 3273 offace = offdacl + sizeof(ACL); 3274 } else { 3275 acecnt = 0; 3276 offace = 0; 3277 } 3278 for (nace = 0; nace < acecnt; nace++) { 3279 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3280 if (!(pace->flags & INHERIT_ONLY_ACE)) { 3281 if ((ntfs_same_sid(usid, &pace->sid) 3282 || ntfs_same_sid(ownersid, &pace->sid)) 3283 && (pace->mask & WRITE_OWNER)) { 3284 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { 3285 allowown |= pace->mask; 3286 ownpresent = TRUE; 3287 } 3288 } else 3289 if (ntfs_same_sid(usid, &pace->sid) 3290 && (!(pace->mask & WRITE_OWNER))) { 3291 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { 3292 allowgrp |= pace->mask; 3293 grppresent = TRUE; 3294 } 3295 } else 3296 if (is_world_sid((const SID*)&pace->sid)) { 3297 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3298 allowall |= pace->mask; 3299 else 3300 if (pace->type == ACCESS_DENIED_ACE_TYPE) 3301 denyall |= pace->mask; 3302 } else 3303 if ((ntfs_same_sid((const SID*)&pace->sid,nullsid)) 3304 && (pace->type == ACCESS_ALLOWED_ACE_TYPE)) 3305 special |= pace->mask; 3306 } 3307 offace += le16_to_cpu(pace->size); 3308 } 3309 if (!ownpresent) 3310 allowown = allowall; 3311 if (!grppresent) 3312 allowgrp = allowall; 3313 return (merge_permissions(isdir, 3314 allowown & ~(denyown | denyall), 3315 allowgrp & ~(denygrp | denyall), 3316 allowall & ~denyall, 3317 special)); 3318 } 3319 3320 #if POSIXACLS 3321 3322 /* 3323 * Normalize a Posix ACL either from a sorted raw set of 3324 * access ACEs or default ACEs 3325 * (special case : owner or/and group is administrator) 3326 */ 3327 3328 static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc, 3329 int start, int count, int target) 3330 { 3331 int j,k; 3332 s32 id; 3333 u16 tag; 3334 u16 tagsset; 3335 struct POSIX_ACE *pxace; 3336 mode_t denywrld; 3337 mode_t allow; 3338 mode_t deny; 3339 mode_t perms; 3340 mode_t mode; 3341 3342 mode = 0; 3343 pxace = posix_desc->acl.ace; 3344 tagsset = 0; 3345 denywrld = 0; 3346 /* 3347 * Get denials to world which are meant to prevent 3348 * execution flags to be inherited by plain files 3349 */ 3350 for (j=start; j<(start + count); j++) { 3351 if (pxace[j].perms & POSIX_PERM_DENIAL) { 3352 /* deny world exec not for default */ 3353 if ((pxace[j].tag == POSIX_ACL_OTHER) 3354 && !start) 3355 denywrld = pxace[j].perms; 3356 } 3357 } 3358 /* 3359 * Collect groups of ACEs related to the same id 3360 * and determine what is granted (denials are ignored) 3361 * It is important the ACEs have been sorted 3362 */ 3363 j = start; 3364 k = target; 3365 deny = 0; 3366 while (j < (start + count)) { 3367 allow = 0; 3368 tag = pxace[j].tag; 3369 id = pxace[j].id; 3370 if (tag == POSIX_ACL_MASK) { 3371 deny = pxace[j].perms; 3372 j++; 3373 while ((j < (start + count)) 3374 && (pxace[j].tag == POSIX_ACL_MASK)) 3375 j++; 3376 } else { 3377 if (!(pxace[j].perms & POSIX_PERM_DENIAL)) 3378 allow = pxace[j].perms; 3379 j++; 3380 while ((j < (start + count)) 3381 && (pxace[j].tag == tag) 3382 && (pxace[j].id == id)) { 3383 if (!(pxace[j].perms & POSIX_PERM_DENIAL)) 3384 allow |= pxace[j].perms; 3385 j++; 3386 } 3387 } 3388 3389 /* 3390 * Store the grants into a Posix ACE 3391 */ 3392 if (tag == POSIX_ACL_MASK) 3393 perms = ~deny; 3394 else 3395 perms = allow & ~denywrld; 3396 if (tag != POSIX_ACL_SPECIAL) { 3397 pxace[k].tag = tag; 3398 pxace[k].id = id; 3399 pxace[k].perms = perms 3400 & (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X); 3401 tagsset |= tag; 3402 k++; 3403 } 3404 switch (tag) { 3405 case POSIX_ACL_USER_OBJ : 3406 mode |= ((perms & 7) << 6); 3407 break; 3408 case POSIX_ACL_GROUP_OBJ : 3409 case POSIX_ACL_MASK : 3410 mode = (mode & 07707) | ((perms & 7) << 3); 3411 break; 3412 case POSIX_ACL_OTHER : 3413 mode |= perms & 7; 3414 break; 3415 case POSIX_ACL_SPECIAL : 3416 mode |= perms & (S_ISVTX | S_ISUID | S_ISGID); 3417 break; 3418 default : 3419 break; 3420 } 3421 } 3422 if (!start) { /* not satisfactory */ 3423 posix_desc->mode = mode; 3424 posix_desc->tagsset = tagsset; 3425 } 3426 return (k - target); 3427 } 3428 3429 #endif /* POSIXACLS */ 3430 3431 /* 3432 * Interpret an ACL and extract meaningful grants 3433 * (special case : owner or/and group is administrator) 3434 */ 3435 3436 3437 static int build_ownadmin_permissions(const char *securattr, 3438 const SID *usid, const SID *gsid, BOOL isdir) 3439 { 3440 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3441 const ACL *pacl; 3442 const ACCESS_ALLOWED_ACE *pace; 3443 int offdacl; 3444 int offace; 3445 int acecnt; 3446 int nace; 3447 BOOL firstapply; 3448 int isforeign; 3449 le32 special; 3450 le32 allowown, allowgrp, allowall; 3451 le32 denyown, denygrp, denyall; 3452 3453 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3454 offdacl = le32_to_cpu(phead->dacl); 3455 pacl = (const ACL*)&securattr[offdacl]; 3456 special = const_cpu_to_le32(0); 3457 allowown = allowgrp = allowall = const_cpu_to_le32(0); 3458 denyown = denygrp = denyall = const_cpu_to_le32(0); 3459 if (offdacl) { 3460 acecnt = le16_to_cpu(pacl->ace_count); 3461 offace = offdacl + sizeof(ACL); 3462 } else { 3463 acecnt = 0; 3464 offace = 0; 3465 } 3466 firstapply = TRUE; 3467 isforeign = 3; 3468 for (nace = 0; nace < acecnt; nace++) { 3469 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3470 if (!(pace->flags & INHERIT_ONLY_ACE) 3471 && !(~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK))) { 3472 if ((ntfs_same_sid(usid, &pace->sid) 3473 || ntfs_same_sid(ownersid, &pace->sid)) 3474 && (((pace->mask & WRITE_OWNER) && firstapply))) { 3475 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { 3476 allowown |= pace->mask; 3477 isforeign &= ~1; 3478 } else 3479 if (pace->type == ACCESS_DENIED_ACE_TYPE) 3480 denyown |= pace->mask; 3481 } else 3482 if (ntfs_same_sid(gsid, &pace->sid) 3483 && (!(pace->mask & WRITE_OWNER))) { 3484 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { 3485 allowgrp |= pace->mask; 3486 isforeign &= ~2; 3487 } else 3488 if (pace->type == ACCESS_DENIED_ACE_TYPE) 3489 denygrp |= pace->mask; 3490 } else if (is_world_sid((const SID*)&pace->sid)) { 3491 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3492 allowall |= pace->mask; 3493 else 3494 if (pace->type == ACCESS_DENIED_ACE_TYPE) 3495 denyall |= pace->mask; 3496 } 3497 firstapply = FALSE; 3498 } else 3499 if (!(pace->flags & INHERIT_ONLY_ACE)) 3500 if ((ntfs_same_sid((const SID*)&pace->sid,nullsid)) 3501 && (pace->type == ACCESS_ALLOWED_ACE_TYPE)) 3502 special |= pace->mask; 3503 offace += le16_to_cpu(pace->size); 3504 } 3505 if (isforeign) { 3506 allowown |= (allowgrp | allowall); 3507 allowgrp |= allowall; 3508 } 3509 return (merge_permissions(isdir, 3510 allowown & ~(denyown | denyall), 3511 allowgrp & ~(denygrp | denyall), 3512 allowall & ~denyall, 3513 special)); 3514 } 3515 3516 #if OWNERFROMACL 3517 3518 /* 3519 * Define the owner of a file as the first user allowed 3520 * to change the owner, instead of the user defined as owner. 3521 * 3522 * This produces better approximations for files written by a 3523 * Windows user in an inheritable directory owned by another user, 3524 * as the access rights are inheritable but the ownership is not. 3525 * 3526 * An important case is the directories "Documents and Settings/user" 3527 * which the users must have access to, though Windows considers them 3528 * as owned by administrator. 3529 */ 3530 3531 const SID *ntfs_acl_owner(const char *securattr) 3532 { 3533 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3534 const SID *usid; 3535 const ACL *pacl; 3536 const ACCESS_ALLOWED_ACE *pace; 3537 int offdacl; 3538 int offace; 3539 int acecnt; 3540 int nace; 3541 BOOL found; 3542 3543 found = FALSE; 3544 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3545 offdacl = le32_to_cpu(phead->dacl); 3546 if (offdacl) { 3547 pacl = (const ACL*)&securattr[offdacl]; 3548 acecnt = le16_to_cpu(pacl->ace_count); 3549 offace = offdacl + sizeof(ACL); 3550 nace = 0; 3551 do { 3552 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3553 if ((pace->mask & WRITE_OWNER) 3554 && (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3555 && ntfs_is_user_sid(&pace->sid)) 3556 found = TRUE; 3557 offace += le16_to_cpu(pace->size); 3558 } while (!found && (++nace < acecnt)); 3559 } 3560 if (found) 3561 usid = &pace->sid; 3562 else 3563 usid = (const SID*)&securattr[le32_to_cpu(phead->owner)]; 3564 return (usid); 3565 } 3566 3567 #else 3568 3569 /* 3570 * Special case for files owned by administrator with full 3571 * access granted to a mapped user : consider this user as the tenant 3572 * of the file. 3573 * 3574 * This situation cannot be represented with Linux concepts and can 3575 * only be found for files or directories created by Windows. 3576 * Typical situation : directory "Documents and Settings/user" which 3577 * is on the path to user's files and must be given access to user 3578 * only. 3579 * 3580 * Check file is owned by administrator and no user has rights before 3581 * calling. 3582 * Returns the uid of tenant or zero if none 3583 */ 3584 3585 3586 static uid_t find_tenant(struct MAPPING *const mapping[], 3587 const char *securattr) 3588 { 3589 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3590 const ACL *pacl; 3591 const ACCESS_ALLOWED_ACE *pace; 3592 int offdacl; 3593 int offace; 3594 int acecnt; 3595 int nace; 3596 uid_t tid; 3597 uid_t xid; 3598 3599 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3600 offdacl = le32_to_cpu(phead->dacl); 3601 pacl = (const ACL*)&securattr[offdacl]; 3602 tid = 0; 3603 if (offdacl) { 3604 acecnt = le16_to_cpu(pacl->ace_count); 3605 offace = offdacl + sizeof(ACL); 3606 } else 3607 acecnt = 0; 3608 for (nace = 0; nace < acecnt; nace++) { 3609 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3610 if ((pace->type == ACCESS_ALLOWED_ACE_TYPE) 3611 && (pace->mask & DIR_WRITE)) { 3612 xid = ntfs_find_user(mapping[MAPUSERS], &pace->sid); 3613 if (xid) tid = xid; 3614 } 3615 offace += le16_to_cpu(pace->size); 3616 } 3617 return (tid); 3618 } 3619 3620 #endif /* OWNERFROMACL */ 3621 3622 #if POSIXACLS 3623 3624 /* 3625 * Build Posix permissions from an ACL 3626 * returns a pointer to the requested permissions 3627 * or a null pointer (with errno set) if there is a problem 3628 * 3629 * If the NTFS ACL was created according to our rules, the retrieved 3630 * Posix ACL should be the exact ACL which was set. However if 3631 * the NTFS ACL was built by a different tool, the result could 3632 * be a a poor approximation of what was expected 3633 */ 3634 3635 struct POSIX_SECURITY *ntfs_build_permissions_posix( 3636 struct MAPPING *const mapping[], 3637 const char *securattr, 3638 const SID *usid, const SID *gsid, BOOL isdir) 3639 { 3640 const SECURITY_DESCRIPTOR_RELATIVE *phead; 3641 struct POSIX_SECURITY *pxdesc; 3642 const ACL *pacl; 3643 const ACCESS_ALLOWED_ACE *pace; 3644 struct POSIX_ACE *pxace; 3645 struct { 3646 uid_t prevuid; 3647 gid_t prevgid; 3648 int groupmasks; 3649 s16 tagsset; 3650 BOOL gotowner; 3651 BOOL gotownermask; 3652 BOOL gotgroup; 3653 mode_t permswrld; 3654 } ctx[2], *pctx; 3655 int offdacl; 3656 int offace; 3657 int alloccnt; 3658 int acecnt; 3659 uid_t uid; 3660 gid_t gid; 3661 int i,j; 3662 int k,l; 3663 BOOL ignore; 3664 BOOL adminowns; 3665 BOOL groupowns; 3666 BOOL firstinh; 3667 BOOL genericinh; 3668 3669 phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; 3670 offdacl = le32_to_cpu(phead->dacl); 3671 if (offdacl) { 3672 pacl = (const ACL*)&securattr[offdacl]; 3673 acecnt = le16_to_cpu(pacl->ace_count); 3674 offace = offdacl + sizeof(ACL); 3675 } else { 3676 acecnt = 0; 3677 offace = 0; 3678 } 3679 adminowns = FALSE; 3680 groupowns = ntfs_same_sid(gsid,usid); 3681 firstinh = FALSE; 3682 genericinh = FALSE; 3683 /* 3684 * Build a raw posix security descriptor 3685 * by just translating permissions and ids 3686 * Add 2 to the count of ACE to be able to insert 3687 * a group ACE later in access and default ACLs 3688 * and add 2 more to be able to insert ACEs for owner 3689 * and 2 more for other 3690 */ 3691 alloccnt = acecnt + 6; 3692 pxdesc = (struct POSIX_SECURITY*)malloc( 3693 sizeof(struct POSIX_SECURITY) 3694 + alloccnt*sizeof(struct POSIX_ACE)); 3695 k = 0; 3696 l = alloccnt; 3697 for (i=0; i<2; i++) { 3698 pctx = &ctx[i]; 3699 pctx->permswrld = 0; 3700 pctx->prevuid = -1; 3701 pctx->prevgid = -1; 3702 pctx->groupmasks = 0; 3703 pctx->tagsset = 0; 3704 pctx->gotowner = FALSE; 3705 pctx->gotgroup = FALSE; 3706 pctx->gotownermask = FALSE; 3707 } 3708 for (j=0; j<acecnt; j++) { 3709 pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; 3710 if (pace->flags & INHERIT_ONLY_ACE) { 3711 pxace = &pxdesc->acl.ace[l - 1]; 3712 pctx = &ctx[1]; 3713 } else { 3714 pxace = &pxdesc->acl.ace[k]; 3715 pctx = &ctx[0]; 3716 } 3717 ignore = FALSE; 3718 /* 3719 * grants for root as a designated user or group 3720 */ 3721 if ((~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK)) 3722 && (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3723 && ntfs_same_sid(&pace->sid, adminsid)) { 3724 pxace->tag = (pace->mask & ROOT_OWNER_UNMARK ? POSIX_ACL_GROUP : POSIX_ACL_USER); 3725 pxace->id = 0; 3726 if ((pace->mask & (GENERIC_ALL | WRITE_OWNER)) 3727 && (pace->flags & INHERIT_ONLY_ACE)) 3728 ignore = genericinh = TRUE; 3729 } else 3730 if (ntfs_same_sid(usid, &pace->sid)) { 3731 pxace->id = -1; 3732 /* 3733 * Owner has no write-owner right : 3734 * a group was defined same as owner 3735 * or admin was owner or group : 3736 * denials are meant to owner 3737 * and grants are meant to group 3738 */ 3739 if (!(pace->mask & (WRITE_OWNER | GENERIC_ALL)) 3740 && (pace->type == ACCESS_ALLOWED_ACE_TYPE)) { 3741 if (ntfs_same_sid(gsid,usid)) { 3742 pxace->tag = POSIX_ACL_GROUP_OBJ; 3743 pxace->id = -1; 3744 } else { 3745 if (ntfs_same_sid(&pace->sid,usid)) 3746 groupowns = TRUE; 3747 gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid); 3748 if (gid) { 3749 pxace->tag = POSIX_ACL_GROUP; 3750 pxace->id = gid; 3751 pctx->prevgid = gid; 3752 } else { 3753 uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid); 3754 if (uid) { 3755 pxace->tag = POSIX_ACL_USER; 3756 pxace->id = uid; 3757 } else 3758 ignore = TRUE; 3759 } 3760 } 3761 } else { 3762 /* 3763 * when group owns, late denials for owner 3764 * mean group mask 3765 */ 3766 if ((pace->type == ACCESS_DENIED_ACE_TYPE) 3767 && (pace->mask & WRITE_OWNER)) { 3768 pxace->tag = POSIX_ACL_MASK; 3769 pctx->gotownermask = TRUE; 3770 if (pctx->gotowner) 3771 pctx->groupmasks++; 3772 } else { 3773 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3774 pctx->gotowner = TRUE; 3775 if (pctx->gotownermask && !pctx->gotowner) { 3776 uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid); 3777 pxace->id = uid; 3778 pxace->tag = POSIX_ACL_USER; 3779 } else 3780 pxace->tag = POSIX_ACL_USER_OBJ; 3781 /* system ignored, and admin */ 3782 /* ignored at first position */ 3783 if (pace->flags & INHERIT_ONLY_ACE) { 3784 if ((firstinh && ntfs_same_sid(&pace->sid,adminsid)) 3785 || ntfs_same_sid(&pace->sid,systemsid)) 3786 ignore = TRUE; 3787 if (!firstinh) { 3788 firstinh = TRUE; 3789 } 3790 } else { 3791 if ((adminowns && ntfs_same_sid(&pace->sid,adminsid)) 3792 || ntfs_same_sid(&pace->sid,systemsid)) 3793 ignore = TRUE; 3794 if (ntfs_same_sid(usid,adminsid)) 3795 adminowns = TRUE; 3796 } 3797 } 3798 } 3799 } else if (ntfs_same_sid(gsid, &pace->sid)) { 3800 if ((pace->type == ACCESS_DENIED_ACE_TYPE) 3801 && (pace->mask & WRITE_OWNER)) { 3802 pxace->tag = POSIX_ACL_MASK; 3803 pxace->id = -1; 3804 if (pctx->gotowner) 3805 pctx->groupmasks++; 3806 } else { 3807 if (pctx->gotgroup || (pctx->groupmasks > 1)) { 3808 gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid); 3809 if (gid) { 3810 pxace->id = gid; 3811 pxace->tag = POSIX_ACL_GROUP; 3812 pctx->prevgid = gid; 3813 } else 3814 ignore = TRUE; 3815 } else { 3816 pxace->id = -1; 3817 pxace->tag = POSIX_ACL_GROUP_OBJ; 3818 if (pace->type == ACCESS_ALLOWED_ACE_TYPE) 3819 pctx->gotgroup = TRUE; 3820 } 3821 3822 if (ntfs_same_sid(gsid,adminsid) 3823 || ntfs_same_sid(gsid,systemsid)) { 3824 if (pace->mask & (WRITE_OWNER | GENERIC_ALL)) 3825 ignore = TRUE; 3826 if (ntfs_same_sid(gsid,adminsid)) 3827 adminowns = TRUE; 3828 else 3829 genericinh = ignore; 3830 } 3831 } 3832 } else if (is_world_sid((const SID*)&pace->sid)) { 3833 pxace->id = -1; 3834 pxace->tag = POSIX_ACL_OTHER; 3835 if ((pace->type == ACCESS_DENIED_ACE_TYPE) 3836 && (pace->flags & INHERIT_ONLY_ACE)) 3837 ignore = TRUE; 3838 } else if (ntfs_same_sid((const SID*)&pace->sid,nullsid)) { 3839 pxace->id = -1; 3840 pxace->tag = POSIX_ACL_SPECIAL; 3841 } else { 3842 uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid); 3843 if (uid) { 3844 if ((pace->type == ACCESS_DENIED_ACE_TYPE) 3845 && (pace->mask & WRITE_OWNER) 3846 && (pctx->prevuid != uid)) { 3847 pxace->id = -1; 3848 pxace->tag = POSIX_ACL_MASK; 3849 } else { 3850 pxace->id = uid; 3851 pxace->tag = POSIX_ACL_USER; 3852 } 3853 pctx->prevuid = uid; 3854 } else { 3855 gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid); 3856 if (gid) { 3857 if ((pace->type == ACCESS_DENIED_ACE_TYPE) 3858 && (pace->mask & WRITE_OWNER) 3859 && (pctx->prevgid != gid)) { 3860 pxace->tag = POSIX_ACL_MASK; 3861 pctx->groupmasks++; 3862 } else { 3863 pxace->tag = POSIX_ACL_GROUP; 3864 } 3865 pxace->id = gid; 3866 pctx->prevgid = gid; 3867 } else { 3868 /* 3869 * do not grant rights to unknown 3870 * people and do not define root as a 3871 * designated user or group 3872 */ 3873 ignore = TRUE; 3874 } 3875 } 3876 } 3877 if (!ignore) { 3878 pxace->perms = 0; 3879 /* specific decoding for vtx/uid/gid */ 3880 if (pxace->tag == POSIX_ACL_SPECIAL) { 3881 if (pace->mask & FILE_APPEND_DATA) 3882 pxace->perms |= S_ISUID; 3883 if (pace->mask & FILE_WRITE_DATA) 3884 pxace->perms |= S_ISGID; 3885 if (pace->mask & FILE_READ_DATA) 3886 pxace->perms |= S_ISVTX; 3887 } else 3888 if (isdir) { 3889 if (pace->mask & DIR_GEXEC) 3890 pxace->perms |= POSIX_PERM_X; 3891 if (pace->mask & DIR_GWRITE) 3892 pxace->perms |= POSIX_PERM_W; 3893 if (pace->mask & DIR_GREAD) 3894 pxace->perms |= POSIX_PERM_R; 3895 if ((pace->mask & GENERIC_ALL) 3896 && (pace->flags & INHERIT_ONLY_ACE)) 3897 pxace->perms |= POSIX_PERM_X 3898 | POSIX_PERM_W 3899 | POSIX_PERM_R; 3900 } else { 3901 if (pace->mask & FILE_GEXEC) 3902 pxace->perms |= POSIX_PERM_X; 3903 if (pace->mask & FILE_GWRITE) 3904 pxace->perms |= POSIX_PERM_W; 3905 if (pace->mask & FILE_GREAD) 3906 pxace->perms |= POSIX_PERM_R; 3907 } 3908 3909 if (pace->type != ACCESS_ALLOWED_ACE_TYPE) 3910 pxace->perms |= POSIX_PERM_DENIAL; 3911 else 3912 if (pxace->tag == POSIX_ACL_OTHER) 3913 pctx->permswrld |= pxace->perms; 3914 pctx->tagsset |= pxace->tag; 3915 if (pace->flags & INHERIT_ONLY_ACE) { 3916 l--; 3917 } else { 3918 k++; 3919 } 3920 } 3921 offace += le16_to_cpu(pace->size); 3922 } 3923 /* 3924 * Create world perms if none (both lists) 3925 */ 3926 for (i=0; i<2; i++) 3927 if ((genericinh || !i) 3928 && !(ctx[i].tagsset & POSIX_ACL_OTHER)) { 3929 if (i) 3930 pxace = &pxdesc->acl.ace[--l]; 3931 else 3932 pxace = &pxdesc->acl.ace[k++]; 3933 pxace->tag = POSIX_ACL_OTHER; 3934 pxace->id = -1; 3935 pxace->perms = 0; 3936 ctx[i].tagsset |= POSIX_ACL_OTHER; 3937 ctx[i].permswrld = 0; 3938 } 3939 /* 3940 * Set basic owner perms if none (both lists) 3941 * This happens for files created by Windows in directories 3942 * created by Linux and owned by root, because Windows 3943 * merges the admin ACEs 3944 */ 3945 for (i=0; i<2; i++) 3946 if (!(ctx[i].tagsset & POSIX_ACL_USER_OBJ) 3947 && (ctx[i].tagsset & POSIX_ACL_OTHER)) { 3948 if (i) 3949 pxace = &pxdesc->acl.ace[--l]; 3950 else 3951 pxace = &pxdesc->acl.ace[k++]; 3952 pxace->tag = POSIX_ACL_USER_OBJ; 3953 pxace->id = -1; 3954 pxace->perms = POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X; 3955 ctx[i].tagsset |= POSIX_ACL_USER_OBJ; 3956 } 3957 /* 3958 * Duplicate world perms as group_obj perms if none 3959 */ 3960 for (i=0; i<2; i++) 3961 if ((ctx[i].tagsset & POSIX_ACL_OTHER) 3962 && !(ctx[i].tagsset & POSIX_ACL_GROUP_OBJ)) { 3963 if (i) 3964 pxace = &pxdesc->acl.ace[--l]; 3965 else 3966 pxace = &pxdesc->acl.ace[k++]; 3967 pxace->tag = POSIX_ACL_GROUP_OBJ; 3968 pxace->id = -1; 3969 pxace->perms = ctx[i].permswrld; 3970 ctx[i].tagsset |= POSIX_ACL_GROUP_OBJ; 3971 } 3972 /* 3973 * Also duplicate world perms as group perms if they 3974 * were converted to mask and not followed by a group entry 3975 */ 3976 if (ctx[0].groupmasks) { 3977 for (j=k-2; j>=0; j--) { 3978 if ((pxdesc->acl.ace[j].tag == POSIX_ACL_MASK) 3979 && (pxdesc->acl.ace[j].id != -1) 3980 && ((pxdesc->acl.ace[j+1].tag != POSIX_ACL_GROUP) 3981 || (pxdesc->acl.ace[j+1].id 3982 != pxdesc->acl.ace[j].id))) { 3983 pxace = &pxdesc->acl.ace[k]; 3984 pxace->tag = POSIX_ACL_GROUP; 3985 pxace->id = pxdesc->acl.ace[j].id; 3986 pxace->perms = ctx[0].permswrld; 3987 ctx[0].tagsset |= POSIX_ACL_GROUP; 3988 k++; 3989 } 3990 if (pxdesc->acl.ace[j].tag == POSIX_ACL_MASK) 3991 pxdesc->acl.ace[j].id = -1; 3992 } 3993 } 3994 if (ctx[1].groupmasks) { 3995 for (j=l; j<(alloccnt-1); j++) { 3996 if ((pxdesc->acl.ace[j].tag == POSIX_ACL_MASK) 3997 && (pxdesc->acl.ace[j].id != -1) 3998 && ((pxdesc->acl.ace[j+1].tag != POSIX_ACL_GROUP) 3999 || (pxdesc->acl.ace[j+1].id 4000 != pxdesc->acl.ace[j].id))) { 4001 pxace = &pxdesc->acl.ace[l - 1]; 4002 pxace->tag = POSIX_ACL_GROUP; 4003 pxace->id = pxdesc->acl.ace[j].id; 4004 pxace->perms = ctx[1].permswrld; 4005 ctx[1].tagsset |= POSIX_ACL_GROUP; 4006 l--; 4007 } 4008 if (pxdesc->acl.ace[j].tag == POSIX_ACL_MASK) 4009 pxdesc->acl.ace[j].id = -1; 4010 } 4011 } 4012 4013 /* 4014 * Insert default mask if none present and 4015 * there are designated users or groups 4016 * (the space for it has not beed used) 4017 */ 4018 for (i=0; i<2; i++) 4019 if ((ctx[i].tagsset & (POSIX_ACL_USER | POSIX_ACL_GROUP)) 4020 && !(ctx[i].tagsset & POSIX_ACL_MASK)) { 4021 if (i) 4022 pxace = &pxdesc->acl.ace[--l]; 4023 else 4024 pxace = &pxdesc->acl.ace[k++]; 4025 pxace->tag = POSIX_ACL_MASK; 4026 pxace->id = -1; 4027 pxace->perms = POSIX_PERM_DENIAL; 4028 ctx[i].tagsset |= POSIX_ACL_MASK; 4029 } 4030 4031 if (k > l) { 4032 ntfs_log_error("Posix descriptor is longer than expected\n"); 4033 errno = EIO; 4034 free(pxdesc); 4035 pxdesc = (struct POSIX_SECURITY*)NULL; 4036 } else { 4037 pxdesc->acccnt = k; 4038 pxdesc->defcnt = alloccnt - l; 4039 pxdesc->firstdef = l; 4040 pxdesc->tagsset = ctx[0].tagsset; 4041 pxdesc->acl.version = POSIX_VERSION; 4042 pxdesc->acl.flags = 0; 4043 pxdesc->acl.filler = 0; 4044 ntfs_sort_posix(pxdesc); 4045 if (adminowns) { 4046 k = norm_ownadmin_permissions_posix(pxdesc, 4047 0, pxdesc->acccnt, 0); 4048 pxdesc->acccnt = k; 4049 l = norm_ownadmin_permissions_posix(pxdesc, 4050 pxdesc->firstdef, pxdesc->defcnt, k); 4051 pxdesc->firstdef = k; 4052 pxdesc->defcnt = l; 4053 } else { 4054 k = norm_std_permissions_posix(pxdesc,groupowns, 4055 0, pxdesc->acccnt, 0); 4056 pxdesc->acccnt = k; 4057 l = norm_std_permissions_posix(pxdesc,groupowns, 4058 pxdesc->firstdef, pxdesc->defcnt, k); 4059 pxdesc->firstdef = k; 4060 pxdesc->defcnt = l; 4061 } 4062 } 4063 if (pxdesc && !ntfs_valid_posix(pxdesc)) { 4064 ntfs_log_error("Invalid Posix descriptor built\n"); 4065 errno = EIO; 4066 free(pxdesc); 4067 pxdesc = (struct POSIX_SECURITY*)NULL; 4068 } 4069 return (pxdesc); 4070 } 4071 4072 #endif /* POSIXACLS */ 4073 4074 /* 4075 * Build unix-style (mode_t) permissions from an ACL 4076 * returns the requested permissions 4077 * or a negative result (with errno set) if there is a problem 4078 */ 4079 4080 int ntfs_build_permissions(const char *securattr, 4081 const SID *usid, const SID *gsid, BOOL isdir) 4082 { 4083 int perm; 4084 BOOL adminowns; 4085 BOOL groupowns; 4086 4087 adminowns = ntfs_same_sid(usid,adminsid) 4088 || ntfs_same_sid(gsid,adminsid); 4089 groupowns = !adminowns && ntfs_same_sid(gsid,usid); 4090 if (adminowns) 4091 perm = build_ownadmin_permissions(securattr, usid, gsid, isdir); 4092 else 4093 if (groupowns) 4094 perm = build_owngrp_permissions(securattr, usid, isdir); 4095 else 4096 perm = build_std_permissions(securattr, usid, gsid, isdir); 4097 return (perm); 4098 } 4099 4100 #ifndef __HAIKU__ 4101 /* 4102 * The following must be in some library... 4103 */ 4104 4105 static unsigned long atoul(const char *p) 4106 { /* must be somewhere ! */ 4107 unsigned long v; 4108 4109 v = 0; 4110 while ((*p >= '0') && (*p <= '9')) 4111 v = v * 10 + (*p++) - '0'; 4112 return (v); 4113 } 4114 #endif 4115 4116 /* 4117 * Build an internal representation of a SID 4118 * Returns a copy in allocated memory if it succeeds 4119 * The SID is checked to be a valid user one. 4120 */ 4121 4122 static SID *encodesid(const char *sidstr) 4123 { 4124 SID *sid; 4125 int cnt; 4126 BIGSID bigsid; 4127 SID *bsid; 4128 u32 auth; 4129 const char *p; 4130 4131 sid = (SID*) NULL; 4132 if (!strncmp(sidstr, "S-1-", 4)) { 4133 bsid = (SID*)&bigsid; 4134 bsid->revision = SID_REVISION; 4135 p = &sidstr[4]; 4136 auth = atoul(p); 4137 bsid->identifier_authority.high_part = const_cpu_to_be16(0); 4138 bsid->identifier_authority.low_part = cpu_to_be32(auth); 4139 cnt = 0; 4140 p = strchr(p, '-'); 4141 while (p && (cnt < 8)) { 4142 p++; 4143 auth = atoul(p); 4144 bsid->sub_authority[cnt] = cpu_to_le32(auth); 4145 p = strchr(p, '-'); 4146 cnt++; 4147 } 4148 bsid->sub_authority_count = cnt; 4149 if ((cnt > 0) && ntfs_valid_sid(bsid) 4150 && (ntfs_is_user_sid(bsid) || ntfs_known_group_sid(bsid))) { 4151 sid = (SID*) ntfs_malloc(4 * cnt + 8); 4152 if (sid) 4153 memcpy(sid, bsid, 4 * cnt + 8); 4154 } 4155 } 4156 return (sid); 4157 } 4158 4159 /* 4160 * Get a single mapping item from buffer 4161 * 4162 * Always reads a full line, truncating long lines 4163 * Refills buffer when exhausted 4164 * Returns pointer to item, or NULL when there is no more 4165 */ 4166 4167 static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, 4168 off_t *poffs, char *buf, int *psrc, s64 *psize) 4169 { 4170 int src; 4171 int dst; 4172 char *q; 4173 char *pu; 4174 char *pg; 4175 int gotend; 4176 struct MAPLIST *item; 4177 4178 src = *psrc; 4179 dst = 0; 4180 /* allocate and get a full line */ 4181 item = (struct MAPLIST*)ntfs_malloc(sizeof(struct MAPLIST)); 4182 if (item) { 4183 do { 4184 gotend = 0; 4185 while ((src < *psize) 4186 && (buf[src] != '\n')) { 4187 if (dst < LINESZ) 4188 item->maptext[dst++] = buf[src]; 4189 src++; 4190 } 4191 if (src >= *psize) { 4192 *poffs += *psize; 4193 *psize = reader(fileid, buf, (size_t)BUFSZ, *poffs); 4194 src = 0; 4195 } else { 4196 gotend = 1; 4197 src++; 4198 item->maptext[dst] = '\0'; 4199 dst = 0; 4200 } 4201 } while (*psize && ((item->maptext[0] == '#') || !gotend)); 4202 if (gotend) { 4203 pu = pg = (char*)NULL; 4204 /* decompose into uid, gid and sid */ 4205 item->uidstr = item->maptext; 4206 item->gidstr = strchr(item->uidstr, ':'); 4207 if (item->gidstr) { 4208 pu = item->gidstr++; 4209 item->sidstr = strchr(item->gidstr, ':'); 4210 if (item->sidstr) { 4211 pg = item->sidstr++; 4212 q = strchr(item->sidstr, ':'); 4213 if (q) *q = 0; 4214 } 4215 } 4216 if (pu && pg) 4217 *pu = *pg = '\0'; 4218 else { 4219 ntfs_log_early_error("Bad mapping item \"%s\"\n", 4220 item->maptext); 4221 free(item); 4222 item = (struct MAPLIST*)NULL; 4223 } 4224 } else { 4225 free(item); /* free unused item */ 4226 item = (struct MAPLIST*)NULL; 4227 } 4228 } 4229 *psrc = src; 4230 return (item); 4231 } 4232 4233 /* 4234 * Read user mapping file and split into their attribute. 4235 * Parameters are kept as text in a chained list until logins 4236 * are converted to uid. 4237 * Returns the head of list, if any 4238 * 4239 * If an absolute path is provided, the mapping file is assumed 4240 * to be located in another mounted file system, and plain read() 4241 * are used to get its contents. 4242 * If a relative path is provided, the mapping file is assumed 4243 * to be located on the current file system, and internal IO 4244 * have to be used since we are still mounting and we have not 4245 * entered the fuse loop yet. 4246 */ 4247 4248 struct MAPLIST *ntfs_read_mapping(FILEREADER reader, void *fileid) 4249 { 4250 char buf[BUFSZ]; 4251 struct MAPLIST *item; 4252 struct MAPLIST *firstitem; 4253 struct MAPLIST *lastitem; 4254 int src; 4255 off_t offs; 4256 s64 size; 4257 4258 firstitem = (struct MAPLIST*)NULL; 4259 lastitem = (struct MAPLIST*)NULL; 4260 offs = 0; 4261 size = reader(fileid, buf, (size_t)BUFSZ, (off_t)0); 4262 if (size > 0) { 4263 src = 0; 4264 do { 4265 item = getmappingitem(reader, fileid, &offs, 4266 buf, &src, &size); 4267 if (item) { 4268 item->next = (struct MAPLIST*)NULL; 4269 if (lastitem) 4270 lastitem->next = item; 4271 else 4272 firstitem = item; 4273 lastitem = item; 4274 } 4275 } while (item); 4276 } 4277 return (firstitem); 4278 } 4279 4280 /* 4281 * Free memory used to store the user mapping 4282 * The only purpose is to facilitate the detection of memory leaks 4283 */ 4284 4285 void ntfs_free_mapping(struct MAPPING *mapping[]) 4286 { 4287 struct MAPPING *user; 4288 struct MAPPING *group; 4289 4290 /* free user mappings */ 4291 while (mapping[MAPUSERS]) { 4292 user = mapping[MAPUSERS]; 4293 /* do not free SIDs used for group mappings */ 4294 group = mapping[MAPGROUPS]; 4295 while (group && (group->sid != user->sid)) 4296 group = group->next; 4297 if (!group) 4298 free(user->sid); 4299 /* free group list if any */ 4300 if (user->grcnt) 4301 free(user->groups); 4302 /* unchain item and free */ 4303 mapping[MAPUSERS] = user->next; 4304 free(user); 4305 } 4306 /* free group mappings */ 4307 while (mapping[MAPGROUPS]) { 4308 group = mapping[MAPGROUPS]; 4309 free(group->sid); 4310 /* unchain item and free */ 4311 mapping[MAPGROUPS] = group->next; 4312 free(group); 4313 } 4314 } 4315 4316 4317 /* 4318 * Build the user mapping list 4319 * user identification may be given in symbolic or numeric format 4320 * 4321 * ! Note ! : does getpwnam() read /etc/passwd or some other file ? 4322 * if so there is a possible recursion into fuse if this 4323 * file is on NTFS, and fuse is not recursion safe. 4324 */ 4325 4326 struct MAPPING *ntfs_do_user_mapping(struct MAPLIST *firstitem) 4327 { 4328 struct MAPLIST *item; 4329 struct MAPPING *firstmapping; 4330 struct MAPPING *lastmapping; 4331 struct MAPPING *mapping; 4332 struct passwd *pwd; 4333 SID *sid; 4334 int uid; 4335 4336 firstmapping = (struct MAPPING*)NULL; 4337 lastmapping = (struct MAPPING*)NULL; 4338 for (item = firstitem; item; item = item->next) { 4339 if ((item->uidstr[0] >= '0') && (item->uidstr[0] <= '9')) 4340 uid = atoi(item->uidstr); 4341 else { 4342 uid = 0; 4343 if (item->uidstr[0]) { 4344 pwd = getpwnam(item->uidstr); 4345 if (pwd) 4346 uid = pwd->pw_uid; 4347 else 4348 ntfs_log_early_error("Invalid user \"%s\"\n", 4349 item->uidstr); 4350 } 4351 } 4352 /* 4353 * Records with no uid and no gid are inserted 4354 * to define the implicit mapping pattern 4355 */ 4356 if (uid 4357 || (!item->uidstr[0] && !item->gidstr[0])) { 4358 sid = encodesid(item->sidstr); 4359 if (sid && ntfs_known_group_sid(sid)) { 4360 ntfs_log_error("Bad user SID %s\n", 4361 item->sidstr); 4362 free(sid); 4363 sid = (SID*)NULL; 4364 } 4365 if (sid && !item->uidstr[0] && !item->gidstr[0] 4366 && !ntfs_valid_pattern(sid)) { 4367 ntfs_log_error("Bad implicit SID pattern %s\n", 4368 item->sidstr); 4369 sid = (SID*)NULL; 4370 } 4371 if (sid) { 4372 mapping = 4373 (struct MAPPING*) 4374 ntfs_malloc(sizeof(struct MAPPING)); 4375 if (mapping) { 4376 mapping->sid = sid; 4377 mapping->xid = uid; 4378 mapping->grcnt = 0; 4379 mapping->next = (struct MAPPING*)NULL; 4380 if (lastmapping) 4381 lastmapping->next = mapping; 4382 else 4383 firstmapping = mapping; 4384 lastmapping = mapping; 4385 } 4386 } 4387 } 4388 } 4389 return (firstmapping); 4390 } 4391 4392 /* 4393 * Build the group mapping list 4394 * group identification may be given in symbolic or numeric format 4395 * 4396 * gid not associated to a uid are processed first in order 4397 * to favour real groups 4398 * 4399 * ! Note ! : does getgrnam() read /etc/group or some other file ? 4400 * if so there is a possible recursion into fuse if this 4401 * file is on NTFS, and fuse is not recursion safe. 4402 */ 4403 4404 struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem) 4405 { 4406 struct MAPLIST *item; 4407 struct MAPPING *firstmapping; 4408 struct MAPPING *lastmapping; 4409 struct MAPPING *mapping; 4410 struct group *grp; 4411 BOOL secondstep; 4412 BOOL ok; 4413 int step; 4414 SID *sid; 4415 int gid; 4416 4417 firstmapping = (struct MAPPING*)NULL; 4418 lastmapping = (struct MAPPING*)NULL; 4419 for (step=1; step<=2; step++) { 4420 for (item = firstitem; item; item = item->next) { 4421 secondstep = (item->uidstr[0] != '\0') 4422 || !item->gidstr[0]; 4423 ok = (step == 1 ? !secondstep : secondstep); 4424 if ((item->gidstr[0] >= '0') 4425 && (item->gidstr[0] <= '9')) 4426 gid = atoi(item->gidstr); 4427 else { 4428 gid = 0; 4429 if (item->gidstr[0]) { 4430 grp = getgrnam(item->gidstr); 4431 if (grp) 4432 gid = grp->gr_gid; 4433 else 4434 ntfs_log_early_error("Invalid group \"%s\"\n", 4435 item->gidstr); 4436 } 4437 } 4438 /* 4439 * Records with no uid and no gid are inserted in the 4440 * second step to define the implicit mapping pattern 4441 */ 4442 if (ok 4443 && (gid 4444 || (!item->uidstr[0] && !item->gidstr[0]))) { 4445 sid = encodesid(item->sidstr); 4446 if (sid && !item->uidstr[0] && !item->gidstr[0] 4447 && !ntfs_valid_pattern(sid)) { 4448 /* error already logged */ 4449 sid = (SID*)NULL; 4450 } 4451 if (sid) { 4452 mapping = (struct MAPPING*) 4453 ntfs_malloc(sizeof(struct MAPPING)); 4454 if (mapping) { 4455 mapping->sid = sid; 4456 mapping->xid = gid; 4457 /* special groups point to themselves */ 4458 if (ntfs_known_group_sid(sid)) { 4459 mapping->groups = 4460 (gid_t*)&mapping->xid; 4461 mapping->grcnt = 1; 4462 } else 4463 mapping->grcnt = 0; 4464 4465 4466 mapping->next = (struct MAPPING*)NULL; 4467 if (lastmapping) 4468 lastmapping->next = mapping; 4469 else 4470 firstmapping = mapping; 4471 lastmapping = mapping; 4472 } 4473 } 4474 } 4475 } 4476 } 4477 return (firstmapping); 4478 } 4479