hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/cifs/cifsacl.c
....@@ -39,8 +39,6 @@
3939 /* security id for Authenticated Users system group */
4040 static const struct cifs_sid sid_authusers = {
4141 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}, {} };
4442
4543 /* S-1-22-1 Unmapped Unix users */
4644 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
....@@ -51,7 +49,7 @@
5149 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
5250
5351 /*
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
5553 */
5654
5755 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
....@@ -340,11 +338,11 @@
340338 goto out_key_put;
341339 }
342340
343
-static int
341
+int
344342 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
345343 struct cifs_fattr *fattr, uint sidtype)
346344 {
347
- int rc;
345
+ int rc = 0;
348346 struct key *sidkey;
349347 char *sidstr;
350348 const struct cred *saved_cred;
....@@ -361,7 +359,8 @@
361359 return -EIO;
362360 }
363361
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)) {
365364 uint32_t unix_id;
366365 bool is_group;
367366
....@@ -452,11 +451,12 @@
452451 * fails then we just fall back to using the mnt_uid/mnt_gid.
453452 */
454453 got_valid_id:
454
+ rc = 0;
455455 if (sidtype == SIDOWNER)
456456 fattr->cf_uid = fuid;
457457 else
458458 fattr->cf_gid = fgid;
459
- return 0;
459
+ return rc;
460460 }
461461
462462 int
....@@ -701,10 +701,9 @@
701701 }
702702 #endif
703703
704
-
705704 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
706705 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
707
- struct cifs_fattr *fattr)
706
+ struct cifs_fattr *fattr, bool mode_from_special_sid)
708707 {
709708 int i;
710709 int num_aces = 0;
....@@ -757,22 +756,34 @@
757756 #ifdef CONFIG_CIFS_DEBUG2
758757 dump_ace(ppace[i], end_of_acl);
759758 #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)
761772 access_flags_to_mode(ppace[i]->access_req,
762773 ppace[i]->type,
763774 &fattr->cf_mode,
764775 &user_mask);
765
- if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
776
+ else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
766777 access_flags_to_mode(ppace[i]->access_req,
767778 ppace[i]->type,
768779 &fattr->cf_mode,
769780 &group_mask);
770
- if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
781
+ else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
771782 access_flags_to_mode(ppace[i]->access_req,
772783 ppace[i]->type,
773784 &fattr->cf_mode,
774785 &other_mask);
775
- if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
786
+ else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
776787 access_flags_to_mode(ppace[i]->access_req,
777788 ppace[i]->type,
778789 &fattr->cf_mode,
....@@ -793,24 +804,103 @@
793804 return;
794805 }
795806
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
+}
796874
797875 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)
799877 {
800878 u16 size = 0;
879
+ u32 num_aces = 0;
801880 struct cifs_acl *pnndacl;
802881
803882 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
804883
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
+
805892 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
806893 pownersid, nmode, S_IRWXU);
894
+ num_aces++;
807895 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
808896 pgrpsid, nmode, S_IRWXG);
897
+ num_aces++;
809898 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
810899 &sid_everyone, nmode, S_IRWXO);
900
+ num_aces++;
811901
902
+ pndacl->num_aces = cpu_to_le32(num_aces);
812903 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
813
- pndacl->num_aces = cpu_to_le32(3);
814904
815905 return 0;
816906 }
....@@ -851,7 +941,8 @@
851941
852942 /* Convert CIFS ACL to POSIX form */
853943 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)
855946 {
856947 int rc = 0;
857948 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
....@@ -900,7 +991,7 @@
900991
901992 if (dacloffset)
902993 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);
904995 else
905996 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
906997
....@@ -909,7 +1000,8 @@
9091000
9101001 /* Convert permission bits from mode to equivalent CIFS ACL */
9111002 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)
9131005 {
9141006 int rc = 0;
9151007 __u32 dacloffset;
....@@ -934,7 +1026,7 @@
9341026 ndacl_ptr->num_aces = 0;
9351027
9361028 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
937
- nmode);
1029
+ nmode, mode_from_sid);
9381030 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
9391031 /* copy sec desc control portion & owner and group sids */
9401032 copy_sec_desc(pntsd, pnntsd, sidsoffset);
....@@ -950,12 +1042,23 @@
9501042 if (!nowner_sid_ptr)
9511043 return -ENOMEM;
9521044 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
+ }
9591062 }
9601063 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
9611064 kfree(nowner_sid_ptr);
....@@ -970,12 +1073,23 @@
9701073 if (!ngroup_sid_ptr)
9711074 return -ENOMEM;
9721075 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
+ }
9791093 }
9801094 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
9811095 kfree(ngroup_sid_ptr);
....@@ -1016,7 +1130,7 @@
10161130 struct cifs_ntsd *pntsd = NULL;
10171131 int oplock = 0;
10181132 unsigned int xid;
1019
- int rc, create_options = 0;
1133
+ int rc;
10201134 struct cifs_tcon *tcon;
10211135 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
10221136 struct cifs_fid fid;
....@@ -1028,13 +1142,10 @@
10281142 tcon = tlink_tcon(tlink);
10291143 xid = get_xid();
10301144
1031
- if (backup_cred(cifs_sb))
1032
- create_options |= CREATE_OPEN_BACKUP_INTENT;
1033
-
10341145 oparms.tcon = tcon;
10351146 oparms.cifs_sb = cifs_sb;
10361147 oparms.desired_access = READ_CONTROL;
1037
- oparms.create_options = create_options;
1148
+ oparms.create_options = cifs_create_options(cifs_sb, 0);
10381149 oparms.disposition = FILE_OPEN;
10391150 oparms.path = path;
10401151 oparms.fid = &fid;
....@@ -1079,7 +1190,7 @@
10791190 {
10801191 int oplock = 0;
10811192 unsigned int xid;
1082
- int rc, access_flags, create_options = 0;
1193
+ int rc, access_flags;
10831194 struct cifs_tcon *tcon;
10841195 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
10851196 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
....@@ -1092,9 +1203,6 @@
10921203 tcon = tlink_tcon(tlink);
10931204 xid = get_xid();
10941205
1095
- if (backup_cred(cifs_sb))
1096
- create_options |= CREATE_OPEN_BACKUP_INTENT;
1097
-
10981206 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
10991207 access_flags = WRITE_OWNER;
11001208 else
....@@ -1103,7 +1211,7 @@
11031211 oparms.tcon = tcon;
11041212 oparms.cifs_sb = cifs_sb;
11051213 oparms.desired_access = access_flags;
1106
- oparms.create_options = create_options;
1214
+ oparms.create_options = cifs_create_options(cifs_sb, 0);
11071215 oparms.disposition = FILE_OPEN;
11081216 oparms.path = path;
11091217 oparms.fid = &fid;
....@@ -1128,8 +1236,8 @@
11281236 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
11291237 int
11301238 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)
11331241 {
11341242 struct cifs_ntsd *pntsd = NULL;
11351243 u32 acllen = 0;
....@@ -1156,8 +1264,12 @@
11561264 if (IS_ERR(pntsd)) {
11571265 rc = PTR_ERR(pntsd);
11581266 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);
11591270 } 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);
11611273 kfree(pntsd);
11621274 if (rc)
11631275 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
....@@ -1181,6 +1293,7 @@
11811293 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
11821294 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
11831295 struct smb_version_operations *ops;
1296
+ bool mode_from_sid, id_from_sid;
11841297
11851298 if (IS_ERR(tlink))
11861299 return PTR_ERR(tlink);
....@@ -1218,8 +1331,18 @@
12181331 return -ENOMEM;
12191332 }
12201333
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
+
12211344 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1222
- &aclflag);
1345
+ mode_from_sid, id_from_sid, &aclflag);
12231346
12241347 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
12251348