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