@@ -885,12 +885,17 @@ unsigned int setup_authusers_ACE(struct smb_ace *pntace)
885
885
* Fill in the special SID based on the mode. See
886
886
* https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887
887
*/
888
- unsigned int setup_special_mode_ACE (struct smb_ace * pntace , __u64 nmode )
888
+ unsigned int setup_special_mode_ACE (struct smb_ace * pntace ,
889
+ bool posix ,
890
+ __u64 nmode )
889
891
{
890
892
int i ;
891
893
unsigned int ace_size = 28 ;
892
894
893
- pntace -> type = ACCESS_DENIED_ACE_TYPE ;
895
+ if (posix )
896
+ pntace -> type = ACCESS_ALLOWED_ACE_TYPE ;
897
+ else
898
+ pntace -> type = ACCESS_DENIED_ACE_TYPE ;
894
899
pntace -> flags = 0x0 ;
895
900
pntace -> access_req = 0 ;
896
901
pntace -> sid .num_subauth = 3 ;
@@ -933,7 +938,8 @@ static void populate_new_aces(char *nacl_base,
933
938
struct smb_sid * pownersid ,
934
939
struct smb_sid * pgrpsid ,
935
940
__u64 * pnmode , u32 * pnum_aces , u16 * pnsize ,
936
- bool modefromsid )
941
+ bool modefromsid ,
942
+ bool posix )
937
943
{
938
944
__u64 nmode ;
939
945
u32 num_aces = 0 ;
@@ -950,13 +956,15 @@ static void populate_new_aces(char *nacl_base,
950
956
num_aces = * pnum_aces ;
951
957
nsize = * pnsize ;
952
958
953
- if (modefromsid ) {
954
- pnntace = (struct smb_ace * ) (nacl_base + nsize );
955
- nsize += setup_special_mode_ACE (pnntace , nmode );
956
- num_aces ++ ;
959
+ if (modefromsid || posix ) {
957
960
pnntace = (struct smb_ace * ) (nacl_base + nsize );
958
- nsize += setup_authusers_ACE (pnntace );
961
+ nsize += setup_special_mode_ACE (pnntace , posix , nmode );
959
962
num_aces ++ ;
963
+ if (modefromsid ) {
964
+ pnntace = (struct smb_ace * ) (nacl_base + nsize );
965
+ nsize += setup_authusers_ACE (pnntace );
966
+ num_aces ++ ;
967
+ }
960
968
goto set_size ;
961
969
}
962
970
@@ -1076,7 +1084,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
1076
1084
1077
1085
static int set_chmod_dacl (struct smb_acl * pdacl , struct smb_acl * pndacl ,
1078
1086
struct smb_sid * pownersid , struct smb_sid * pgrpsid ,
1079
- __u64 * pnmode , bool mode_from_sid )
1087
+ __u64 * pnmode , bool mode_from_sid , bool posix )
1080
1088
{
1081
1089
int i ;
1082
1090
u16 size = 0 ;
@@ -1094,11 +1102,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1094
1102
nsize = sizeof (struct smb_acl );
1095
1103
1096
1104
/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1097
- if (!pdacl ) {
1105
+ if (!pdacl || posix ) {
1098
1106
populate_new_aces (nacl_base ,
1099
1107
pownersid , pgrpsid ,
1100
1108
pnmode , & num_aces , & nsize ,
1101
- mode_from_sid );
1109
+ mode_from_sid , posix );
1102
1110
goto finalize_dacl ;
1103
1111
}
1104
1112
@@ -1115,7 +1123,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1115
1123
populate_new_aces (nacl_base ,
1116
1124
pownersid , pgrpsid ,
1117
1125
pnmode , & num_aces , & nsize ,
1118
- mode_from_sid );
1126
+ mode_from_sid , posix );
1119
1127
1120
1128
new_aces_set = true;
1121
1129
}
@@ -1144,7 +1152,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1144
1152
populate_new_aces (nacl_base ,
1145
1153
pownersid , pgrpsid ,
1146
1154
pnmode , & num_aces , & nsize ,
1147
- mode_from_sid );
1155
+ mode_from_sid , posix );
1148
1156
1149
1157
new_aces_set = true;
1150
1158
}
@@ -1251,7 +1259,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1251
1259
/* Convert permission bits from mode to equivalent CIFS ACL */
1252
1260
static int build_sec_desc (struct smb_ntsd * pntsd , struct smb_ntsd * pnntsd ,
1253
1261
__u32 secdesclen , __u32 * pnsecdesclen , __u64 * pnmode , kuid_t uid , kgid_t gid ,
1254
- bool mode_from_sid , bool id_from_sid , int * aclflag )
1262
+ bool mode_from_sid , bool id_from_sid , bool posix , int * aclflag )
1255
1263
{
1256
1264
int rc = 0 ;
1257
1265
__u32 dacloffset ;
@@ -1288,7 +1296,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1288
1296
ndacl_ptr -> num_aces = cpu_to_le32 (0 );
1289
1297
1290
1298
rc = set_chmod_dacl (dacl_ptr , ndacl_ptr , owner_sid_ptr , group_sid_ptr ,
1291
- pnmode , mode_from_sid );
1299
+ pnmode , mode_from_sid , posix );
1292
1300
1293
1301
sidsoffset = ndacloffset + le16_to_cpu (ndacl_ptr -> size );
1294
1302
/* copy the non-dacl portion of secdesc */
@@ -1587,6 +1595,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1587
1595
struct tcon_link * tlink = cifs_sb_tlink (cifs_sb );
1588
1596
struct smb_version_operations * ops ;
1589
1597
bool mode_from_sid , id_from_sid ;
1598
+ bool posix = tlink_tcon (tlink )-> posix_extensions ;
1590
1599
const u32 info = 0 ;
1591
1600
1592
1601
if (IS_ERR (tlink ))
@@ -1622,12 +1631,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1622
1631
id_from_sid = false;
1623
1632
1624
1633
/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1625
- nsecdesclen = secdesclen ;
1626
1634
if (pnmode && * pnmode != NO_CHANGE_64 ) { /* chmod */
1627
- if (mode_from_sid )
1628
- nsecdesclen += 2 * sizeof (struct smb_ace );
1635
+ if (posix )
1636
+ nsecdesclen = 1 * sizeof (struct smb_ace );
1637
+ else if (mode_from_sid )
1638
+ nsecdesclen = secdesclen + (2 * sizeof (struct smb_ace ));
1629
1639
else /* cifsacl */
1630
- nsecdesclen += 5 * sizeof (struct smb_ace );
1640
+ nsecdesclen = secdesclen + ( 5 * sizeof (struct smb_ace ) );
1631
1641
} else { /* chown */
1632
1642
/* When ownership changes, changes new owner sid length could be different */
1633
1643
nsecdesclen = sizeof (struct smb_ntsd ) + (sizeof (struct smb_sid ) * 2 );
@@ -1657,7 +1667,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1657
1667
}
1658
1668
1659
1669
rc = build_sec_desc (pntsd , pnntsd , secdesclen , & nsecdesclen , pnmode , uid , gid ,
1660
- mode_from_sid , id_from_sid , & aclflag );
1670
+ mode_from_sid , id_from_sid , posix , & aclflag );
1661
1671
1662
1672
cifs_dbg (NOISY , "build_sec_desc rc: %d\n" , rc );
1663
1673
0 commit comments