| .. | .. |
|---|
| 39 | 39 | /* security id for Authenticated Users system group */ |
|---|
| 40 | 40 | static const struct cifs_sid sid_authusers = { |
|---|
| 41 | 41 | 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} }; |
|---|
| 42 | | -/* group users */ |
|---|
| 43 | | -static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; |
|---|
| 44 | 42 | |
|---|
| 45 | 43 | /* S-1-22-1 Unmapped Unix users */ |
|---|
| 46 | 44 | static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, |
|---|
| .. | .. |
|---|
| 51 | 49 | {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; |
|---|
| 52 | 50 | |
|---|
| 53 | 51 | /* |
|---|
| 54 | | - * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx |
|---|
| 52 | + * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx |
|---|
| 55 | 53 | */ |
|---|
| 56 | 54 | |
|---|
| 57 | 55 | /* S-1-5-88 MS NFS and Apple style UID/GID/mode */ |
|---|
| .. | .. |
|---|
| 340 | 338 | goto out_key_put; |
|---|
| 341 | 339 | } |
|---|
| 342 | 340 | |
|---|
| 343 | | -static int |
|---|
| 341 | +int |
|---|
| 344 | 342 | sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, |
|---|
| 345 | 343 | struct cifs_fattr *fattr, uint sidtype) |
|---|
| 346 | 344 | { |
|---|
| 347 | | - int rc; |
|---|
| 345 | + int rc = 0; |
|---|
| 348 | 346 | struct key *sidkey; |
|---|
| 349 | 347 | char *sidstr; |
|---|
| 350 | 348 | const struct cred *saved_cred; |
|---|
| .. | .. |
|---|
| 361 | 359 | return -EIO; |
|---|
| 362 | 360 | } |
|---|
| 363 | 361 | |
|---|
| 364 | | - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) { |
|---|
| 362 | + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) || |
|---|
| 363 | + (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) { |
|---|
| 365 | 364 | uint32_t unix_id; |
|---|
| 366 | 365 | bool is_group; |
|---|
| 367 | 366 | |
|---|
| .. | .. |
|---|
| 452 | 451 | * fails then we just fall back to using the mnt_uid/mnt_gid. |
|---|
| 453 | 452 | */ |
|---|
| 454 | 453 | got_valid_id: |
|---|
| 454 | + rc = 0; |
|---|
| 455 | 455 | if (sidtype == SIDOWNER) |
|---|
| 456 | 456 | fattr->cf_uid = fuid; |
|---|
| 457 | 457 | else |
|---|
| 458 | 458 | fattr->cf_gid = fgid; |
|---|
| 459 | | - return 0; |
|---|
| 459 | + return rc; |
|---|
| 460 | 460 | } |
|---|
| 461 | 461 | |
|---|
| 462 | 462 | int |
|---|
| .. | .. |
|---|
| 701 | 701 | } |
|---|
| 702 | 702 | #endif |
|---|
| 703 | 703 | |
|---|
| 704 | | - |
|---|
| 705 | 704 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, |
|---|
| 706 | 705 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, |
|---|
| 707 | | - struct cifs_fattr *fattr) |
|---|
| 706 | + struct cifs_fattr *fattr, bool mode_from_special_sid) |
|---|
| 708 | 707 | { |
|---|
| 709 | 708 | int i; |
|---|
| 710 | 709 | int num_aces = 0; |
|---|
| .. | .. |
|---|
| 757 | 756 | #ifdef CONFIG_CIFS_DEBUG2 |
|---|
| 758 | 757 | dump_ace(ppace[i], end_of_acl); |
|---|
| 759 | 758 | #endif |
|---|
| 760 | | - if (compare_sids(&(ppace[i]->sid), pownersid) == 0) |
|---|
| 759 | + if (mode_from_special_sid && |
|---|
| 760 | + (compare_sids(&(ppace[i]->sid), |
|---|
| 761 | + &sid_unix_NFS_mode) == 0)) { |
|---|
| 762 | + /* |
|---|
| 763 | + * Full permissions are: |
|---|
| 764 | + * 07777 = S_ISUID | S_ISGID | S_ISVTX | |
|---|
| 765 | + * S_IRWXU | S_IRWXG | S_IRWXO |
|---|
| 766 | + */ |
|---|
| 767 | + fattr->cf_mode &= ~07777; |
|---|
| 768 | + fattr->cf_mode |= |
|---|
| 769 | + le32_to_cpu(ppace[i]->sid.sub_auth[2]); |
|---|
| 770 | + break; |
|---|
| 771 | + } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0) |
|---|
| 761 | 772 | access_flags_to_mode(ppace[i]->access_req, |
|---|
| 762 | 773 | ppace[i]->type, |
|---|
| 763 | 774 | &fattr->cf_mode, |
|---|
| 764 | 775 | &user_mask); |
|---|
| 765 | | - if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) |
|---|
| 776 | + else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) |
|---|
| 766 | 777 | access_flags_to_mode(ppace[i]->access_req, |
|---|
| 767 | 778 | ppace[i]->type, |
|---|
| 768 | 779 | &fattr->cf_mode, |
|---|
| 769 | 780 | &group_mask); |
|---|
| 770 | | - if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) |
|---|
| 781 | + else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) |
|---|
| 771 | 782 | access_flags_to_mode(ppace[i]->access_req, |
|---|
| 772 | 783 | ppace[i]->type, |
|---|
| 773 | 784 | &fattr->cf_mode, |
|---|
| 774 | 785 | &other_mask); |
|---|
| 775 | | - if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) |
|---|
| 786 | + else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) |
|---|
| 776 | 787 | access_flags_to_mode(ppace[i]->access_req, |
|---|
| 777 | 788 | ppace[i]->type, |
|---|
| 778 | 789 | &fattr->cf_mode, |
|---|
| .. | .. |
|---|
| 793 | 804 | return; |
|---|
| 794 | 805 | } |
|---|
| 795 | 806 | |
|---|
| 807 | +unsigned int setup_authusers_ACE(struct cifs_ace *pntace) |
|---|
| 808 | +{ |
|---|
| 809 | + int i; |
|---|
| 810 | + unsigned int ace_size = 20; |
|---|
| 811 | + |
|---|
| 812 | + pntace->type = ACCESS_ALLOWED_ACE_TYPE; |
|---|
| 813 | + pntace->flags = 0x0; |
|---|
| 814 | + pntace->access_req = cpu_to_le32(GENERIC_ALL); |
|---|
| 815 | + pntace->sid.num_subauth = 1; |
|---|
| 816 | + pntace->sid.revision = 1; |
|---|
| 817 | + for (i = 0; i < NUM_AUTHS; i++) |
|---|
| 818 | + pntace->sid.authority[i] = sid_authusers.authority[i]; |
|---|
| 819 | + |
|---|
| 820 | + pntace->sid.sub_auth[0] = sid_authusers.sub_auth[0]; |
|---|
| 821 | + |
|---|
| 822 | + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ |
|---|
| 823 | + pntace->size = cpu_to_le16(ace_size); |
|---|
| 824 | + return ace_size; |
|---|
| 825 | +} |
|---|
| 826 | + |
|---|
| 827 | +/* |
|---|
| 828 | + * Fill in the special SID based on the mode. See |
|---|
| 829 | + * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx |
|---|
| 830 | + */ |
|---|
| 831 | +unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) |
|---|
| 832 | +{ |
|---|
| 833 | + int i; |
|---|
| 834 | + unsigned int ace_size = 28; |
|---|
| 835 | + |
|---|
| 836 | + pntace->type = ACCESS_DENIED_ACE_TYPE; |
|---|
| 837 | + pntace->flags = 0x0; |
|---|
| 838 | + pntace->access_req = 0; |
|---|
| 839 | + pntace->sid.num_subauth = 3; |
|---|
| 840 | + pntace->sid.revision = 1; |
|---|
| 841 | + for (i = 0; i < NUM_AUTHS; i++) |
|---|
| 842 | + pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i]; |
|---|
| 843 | + |
|---|
| 844 | + pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0]; |
|---|
| 845 | + pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1]; |
|---|
| 846 | + pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777); |
|---|
| 847 | + |
|---|
| 848 | + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ |
|---|
| 849 | + pntace->size = cpu_to_le16(ace_size); |
|---|
| 850 | + return ace_size; |
|---|
| 851 | +} |
|---|
| 852 | + |
|---|
| 853 | +unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) |
|---|
| 854 | +{ |
|---|
| 855 | + int i; |
|---|
| 856 | + unsigned int ace_size = 28; |
|---|
| 857 | + |
|---|
| 858 | + pntace->type = ACCESS_ALLOWED_ACE_TYPE; |
|---|
| 859 | + pntace->flags = 0x0; |
|---|
| 860 | + pntace->access_req = cpu_to_le32(GENERIC_ALL); |
|---|
| 861 | + pntace->sid.num_subauth = 3; |
|---|
| 862 | + pntace->sid.revision = 1; |
|---|
| 863 | + for (i = 0; i < NUM_AUTHS; i++) |
|---|
| 864 | + pntace->sid.authority[i] = sid_unix_NFS_users.authority[i]; |
|---|
| 865 | + |
|---|
| 866 | + pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0]; |
|---|
| 867 | + pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1]; |
|---|
| 868 | + pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val); |
|---|
| 869 | + |
|---|
| 870 | + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ |
|---|
| 871 | + pntace->size = cpu_to_le16(ace_size); |
|---|
| 872 | + return ace_size; |
|---|
| 873 | +} |
|---|
| 796 | 874 | |
|---|
| 797 | 875 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, |
|---|
| 798 | | - struct cifs_sid *pgrpsid, __u64 nmode) |
|---|
| 876 | + struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) |
|---|
| 799 | 877 | { |
|---|
| 800 | 878 | u16 size = 0; |
|---|
| 879 | + u32 num_aces = 0; |
|---|
| 801 | 880 | struct cifs_acl *pnndacl; |
|---|
| 802 | 881 | |
|---|
| 803 | 882 | pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); |
|---|
| 804 | 883 | |
|---|
| 884 | + if (modefromsid) { |
|---|
| 885 | + struct cifs_ace *pntace = |
|---|
| 886 | + (struct cifs_ace *)((char *)pnndacl + size); |
|---|
| 887 | + |
|---|
| 888 | + size += setup_special_mode_ACE(pntace, nmode); |
|---|
| 889 | + num_aces++; |
|---|
| 890 | + } |
|---|
| 891 | + |
|---|
| 805 | 892 | size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size), |
|---|
| 806 | 893 | pownersid, nmode, S_IRWXU); |
|---|
| 894 | + num_aces++; |
|---|
| 807 | 895 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), |
|---|
| 808 | 896 | pgrpsid, nmode, S_IRWXG); |
|---|
| 897 | + num_aces++; |
|---|
| 809 | 898 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), |
|---|
| 810 | 899 | &sid_everyone, nmode, S_IRWXO); |
|---|
| 900 | + num_aces++; |
|---|
| 811 | 901 | |
|---|
| 902 | + pndacl->num_aces = cpu_to_le32(num_aces); |
|---|
| 812 | 903 | pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); |
|---|
| 813 | | - pndacl->num_aces = cpu_to_le32(3); |
|---|
| 814 | 904 | |
|---|
| 815 | 905 | return 0; |
|---|
| 816 | 906 | } |
|---|
| .. | .. |
|---|
| 851 | 941 | |
|---|
| 852 | 942 | /* Convert CIFS ACL to POSIX form */ |
|---|
| 853 | 943 | static int parse_sec_desc(struct cifs_sb_info *cifs_sb, |
|---|
| 854 | | - struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) |
|---|
| 944 | + struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, |
|---|
| 945 | + bool get_mode_from_special_sid) |
|---|
| 855 | 946 | { |
|---|
| 856 | 947 | int rc = 0; |
|---|
| 857 | 948 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
|---|
| .. | .. |
|---|
| 900 | 991 | |
|---|
| 901 | 992 | if (dacloffset) |
|---|
| 902 | 993 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, |
|---|
| 903 | | - group_sid_ptr, fattr); |
|---|
| 994 | + group_sid_ptr, fattr, get_mode_from_special_sid); |
|---|
| 904 | 995 | else |
|---|
| 905 | 996 | cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */ |
|---|
| 906 | 997 | |
|---|
| .. | .. |
|---|
| 909 | 1000 | |
|---|
| 910 | 1001 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
|---|
| 911 | 1002 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
|---|
| 912 | | - __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag) |
|---|
| 1003 | + __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, |
|---|
| 1004 | + bool mode_from_sid, bool id_from_sid, int *aclflag) |
|---|
| 913 | 1005 | { |
|---|
| 914 | 1006 | int rc = 0; |
|---|
| 915 | 1007 | __u32 dacloffset; |
|---|
| .. | .. |
|---|
| 934 | 1026 | ndacl_ptr->num_aces = 0; |
|---|
| 935 | 1027 | |
|---|
| 936 | 1028 | rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, |
|---|
| 937 | | - nmode); |
|---|
| 1029 | + nmode, mode_from_sid); |
|---|
| 938 | 1030 | sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); |
|---|
| 939 | 1031 | /* copy sec desc control portion & owner and group sids */ |
|---|
| 940 | 1032 | copy_sec_desc(pntsd, pnntsd, sidsoffset); |
|---|
| .. | .. |
|---|
| 950 | 1042 | if (!nowner_sid_ptr) |
|---|
| 951 | 1043 | return -ENOMEM; |
|---|
| 952 | 1044 | id = from_kuid(&init_user_ns, uid); |
|---|
| 953 | | - rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr); |
|---|
| 954 | | - if (rc) { |
|---|
| 955 | | - cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n", |
|---|
| 956 | | - __func__, rc, id); |
|---|
| 957 | | - kfree(nowner_sid_ptr); |
|---|
| 958 | | - return rc; |
|---|
| 1045 | + if (id_from_sid) { |
|---|
| 1046 | + struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr; |
|---|
| 1047 | + /* Populate the user ownership fields S-1-5-88-1 */ |
|---|
| 1048 | + osid->Revision = 1; |
|---|
| 1049 | + osid->NumAuth = 3; |
|---|
| 1050 | + osid->Authority[5] = 5; |
|---|
| 1051 | + osid->SubAuthorities[0] = cpu_to_le32(88); |
|---|
| 1052 | + osid->SubAuthorities[1] = cpu_to_le32(1); |
|---|
| 1053 | + osid->SubAuthorities[2] = cpu_to_le32(id); |
|---|
| 1054 | + } else { /* lookup sid with upcall */ |
|---|
| 1055 | + rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr); |
|---|
| 1056 | + if (rc) { |
|---|
| 1057 | + cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n", |
|---|
| 1058 | + __func__, rc, id); |
|---|
| 1059 | + kfree(nowner_sid_ptr); |
|---|
| 1060 | + return rc; |
|---|
| 1061 | + } |
|---|
| 959 | 1062 | } |
|---|
| 960 | 1063 | cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); |
|---|
| 961 | 1064 | kfree(nowner_sid_ptr); |
|---|
| .. | .. |
|---|
| 970 | 1073 | if (!ngroup_sid_ptr) |
|---|
| 971 | 1074 | return -ENOMEM; |
|---|
| 972 | 1075 | id = from_kgid(&init_user_ns, gid); |
|---|
| 973 | | - rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr); |
|---|
| 974 | | - if (rc) { |
|---|
| 975 | | - cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n", |
|---|
| 976 | | - __func__, rc, id); |
|---|
| 977 | | - kfree(ngroup_sid_ptr); |
|---|
| 978 | | - return rc; |
|---|
| 1076 | + if (id_from_sid) { |
|---|
| 1077 | + struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr; |
|---|
| 1078 | + /* Populate the group ownership fields S-1-5-88-2 */ |
|---|
| 1079 | + gsid->Revision = 1; |
|---|
| 1080 | + gsid->NumAuth = 3; |
|---|
| 1081 | + gsid->Authority[5] = 5; |
|---|
| 1082 | + gsid->SubAuthorities[0] = cpu_to_le32(88); |
|---|
| 1083 | + gsid->SubAuthorities[1] = cpu_to_le32(2); |
|---|
| 1084 | + gsid->SubAuthorities[2] = cpu_to_le32(id); |
|---|
| 1085 | + } else { /* lookup sid with upcall */ |
|---|
| 1086 | + rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr); |
|---|
| 1087 | + if (rc) { |
|---|
| 1088 | + cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n", |
|---|
| 1089 | + __func__, rc, id); |
|---|
| 1090 | + kfree(ngroup_sid_ptr); |
|---|
| 1091 | + return rc; |
|---|
| 1092 | + } |
|---|
| 979 | 1093 | } |
|---|
| 980 | 1094 | cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); |
|---|
| 981 | 1095 | kfree(ngroup_sid_ptr); |
|---|
| .. | .. |
|---|
| 1016 | 1130 | struct cifs_ntsd *pntsd = NULL; |
|---|
| 1017 | 1131 | int oplock = 0; |
|---|
| 1018 | 1132 | unsigned int xid; |
|---|
| 1019 | | - int rc, create_options = 0; |
|---|
| 1133 | + int rc; |
|---|
| 1020 | 1134 | struct cifs_tcon *tcon; |
|---|
| 1021 | 1135 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
|---|
| 1022 | 1136 | struct cifs_fid fid; |
|---|
| .. | .. |
|---|
| 1028 | 1142 | tcon = tlink_tcon(tlink); |
|---|
| 1029 | 1143 | xid = get_xid(); |
|---|
| 1030 | 1144 | |
|---|
| 1031 | | - if (backup_cred(cifs_sb)) |
|---|
| 1032 | | - create_options |= CREATE_OPEN_BACKUP_INTENT; |
|---|
| 1033 | | - |
|---|
| 1034 | 1145 | oparms.tcon = tcon; |
|---|
| 1035 | 1146 | oparms.cifs_sb = cifs_sb; |
|---|
| 1036 | 1147 | oparms.desired_access = READ_CONTROL; |
|---|
| 1037 | | - oparms.create_options = create_options; |
|---|
| 1148 | + oparms.create_options = cifs_create_options(cifs_sb, 0); |
|---|
| 1038 | 1149 | oparms.disposition = FILE_OPEN; |
|---|
| 1039 | 1150 | oparms.path = path; |
|---|
| 1040 | 1151 | oparms.fid = &fid; |
|---|
| .. | .. |
|---|
| 1079 | 1190 | { |
|---|
| 1080 | 1191 | int oplock = 0; |
|---|
| 1081 | 1192 | unsigned int xid; |
|---|
| 1082 | | - int rc, access_flags, create_options = 0; |
|---|
| 1193 | + int rc, access_flags; |
|---|
| 1083 | 1194 | struct cifs_tcon *tcon; |
|---|
| 1084 | 1195 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
|---|
| 1085 | 1196 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
|---|
| .. | .. |
|---|
| 1092 | 1203 | tcon = tlink_tcon(tlink); |
|---|
| 1093 | 1204 | xid = get_xid(); |
|---|
| 1094 | 1205 | |
|---|
| 1095 | | - if (backup_cred(cifs_sb)) |
|---|
| 1096 | | - create_options |= CREATE_OPEN_BACKUP_INTENT; |
|---|
| 1097 | | - |
|---|
| 1098 | 1206 | if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP) |
|---|
| 1099 | 1207 | access_flags = WRITE_OWNER; |
|---|
| 1100 | 1208 | else |
|---|
| .. | .. |
|---|
| 1103 | 1211 | oparms.tcon = tcon; |
|---|
| 1104 | 1212 | oparms.cifs_sb = cifs_sb; |
|---|
| 1105 | 1213 | oparms.desired_access = access_flags; |
|---|
| 1106 | | - oparms.create_options = create_options; |
|---|
| 1214 | + oparms.create_options = cifs_create_options(cifs_sb, 0); |
|---|
| 1107 | 1215 | oparms.disposition = FILE_OPEN; |
|---|
| 1108 | 1216 | oparms.path = path; |
|---|
| 1109 | 1217 | oparms.fid = &fid; |
|---|
| .. | .. |
|---|
| 1128 | 1236 | /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */ |
|---|
| 1129 | 1237 | int |
|---|
| 1130 | 1238 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
|---|
| 1131 | | - struct inode *inode, const char *path, |
|---|
| 1132 | | - const struct cifs_fid *pfid) |
|---|
| 1239 | + struct inode *inode, bool mode_from_special_sid, |
|---|
| 1240 | + const char *path, const struct cifs_fid *pfid) |
|---|
| 1133 | 1241 | { |
|---|
| 1134 | 1242 | struct cifs_ntsd *pntsd = NULL; |
|---|
| 1135 | 1243 | u32 acllen = 0; |
|---|
| .. | .. |
|---|
| 1156 | 1264 | if (IS_ERR(pntsd)) { |
|---|
| 1157 | 1265 | rc = PTR_ERR(pntsd); |
|---|
| 1158 | 1266 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
|---|
| 1267 | + } else if (mode_from_special_sid) { |
|---|
| 1268 | + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true); |
|---|
| 1269 | + kfree(pntsd); |
|---|
| 1159 | 1270 | } else { |
|---|
| 1160 | | - rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr); |
|---|
| 1271 | + /* get approximated mode from ACL */ |
|---|
| 1272 | + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false); |
|---|
| 1161 | 1273 | kfree(pntsd); |
|---|
| 1162 | 1274 | if (rc) |
|---|
| 1163 | 1275 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); |
|---|
| .. | .. |
|---|
| 1181 | 1293 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
|---|
| 1182 | 1294 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
|---|
| 1183 | 1295 | struct smb_version_operations *ops; |
|---|
| 1296 | + bool mode_from_sid, id_from_sid; |
|---|
| 1184 | 1297 | |
|---|
| 1185 | 1298 | if (IS_ERR(tlink)) |
|---|
| 1186 | 1299 | return PTR_ERR(tlink); |
|---|
| .. | .. |
|---|
| 1218 | 1331 | return -ENOMEM; |
|---|
| 1219 | 1332 | } |
|---|
| 1220 | 1333 | |
|---|
| 1334 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) |
|---|
| 1335 | + mode_from_sid = true; |
|---|
| 1336 | + else |
|---|
| 1337 | + mode_from_sid = false; |
|---|
| 1338 | + |
|---|
| 1339 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) |
|---|
| 1340 | + id_from_sid = true; |
|---|
| 1341 | + else |
|---|
| 1342 | + id_from_sid = false; |
|---|
| 1343 | + |
|---|
| 1221 | 1344 | rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, |
|---|
| 1222 | | - &aclflag); |
|---|
| 1345 | + mode_from_sid, id_from_sid, &aclflag); |
|---|
| 1223 | 1346 | |
|---|
| 1224 | 1347 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
|---|
| 1225 | 1348 | |
|---|