@@ -885,12 +885,17 @@ unsigned int setup_authusers_ACE(struct smb_ace *pntace)
885885 * Fill in the special SID based on the mode. See
886886 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887887 */
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 )
889891{
890892 int i ;
891893 unsigned int ace_size = 28 ;
892894
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 ;
894899 pntace -> flags = 0x0 ;
895900 pntace -> access_req = 0 ;
896901 pntace -> sid .num_subauth = 3 ;
@@ -933,7 +938,8 @@ static void populate_new_aces(char *nacl_base,
933938 struct smb_sid * pownersid ,
934939 struct smb_sid * pgrpsid ,
935940 __u64 * pnmode , u32 * pnum_aces , u16 * pnsize ,
936- bool modefromsid )
941+ bool modefromsid ,
942+ bool posix )
937943{
938944 __u64 nmode ;
939945 u32 num_aces = 0 ;
@@ -950,13 +956,15 @@ static void populate_new_aces(char *nacl_base,
950956 num_aces = * pnum_aces ;
951957 nsize = * pnsize ;
952958
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 ) {
957960 pnntace = (struct smb_ace * ) (nacl_base + nsize );
958- nsize += setup_authusers_ACE (pnntace );
961+ nsize += setup_special_mode_ACE (pnntace , posix , nmode );
959962 num_aces ++ ;
963+ if (modefromsid ) {
964+ pnntace = (struct smb_ace * ) (nacl_base + nsize );
965+ nsize += setup_authusers_ACE (pnntace );
966+ num_aces ++ ;
967+ }
960968 goto set_size ;
961969 }
962970
@@ -1076,7 +1084,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
10761084
10771085static int set_chmod_dacl (struct smb_acl * pdacl , struct smb_acl * pndacl ,
10781086 struct smb_sid * pownersid , struct smb_sid * pgrpsid ,
1079- __u64 * pnmode , bool mode_from_sid )
1087+ __u64 * pnmode , bool mode_from_sid , bool posix )
10801088{
10811089 int i ;
10821090 u16 size = 0 ;
@@ -1094,11 +1102,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
10941102 nsize = sizeof (struct smb_acl );
10951103
10961104 /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1097- if (!pdacl ) {
1105+ if (!pdacl || posix ) {
10981106 populate_new_aces (nacl_base ,
10991107 pownersid , pgrpsid ,
11001108 pnmode , & num_aces , & nsize ,
1101- mode_from_sid );
1109+ mode_from_sid , posix );
11021110 goto finalize_dacl ;
11031111 }
11041112
@@ -1115,7 +1123,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11151123 populate_new_aces (nacl_base ,
11161124 pownersid , pgrpsid ,
11171125 pnmode , & num_aces , & nsize ,
1118- mode_from_sid );
1126+ mode_from_sid , posix );
11191127
11201128 new_aces_set = true;
11211129 }
@@ -1144,7 +1152,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11441152 populate_new_aces (nacl_base ,
11451153 pownersid , pgrpsid ,
11461154 pnmode , & num_aces , & nsize ,
1147- mode_from_sid );
1155+ mode_from_sid , posix );
11481156
11491157 new_aces_set = true;
11501158 }
@@ -1251,7 +1259,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
12511259/* Convert permission bits from mode to equivalent CIFS ACL */
12521260static int build_sec_desc (struct smb_ntsd * pntsd , struct smb_ntsd * pnntsd ,
12531261 __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 )
12551263{
12561264 int rc = 0 ;
12571265 __u32 dacloffset ;
@@ -1288,7 +1296,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
12881296 ndacl_ptr -> num_aces = cpu_to_le32 (0 );
12891297
12901298 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 );
12921300
12931301 sidsoffset = ndacloffset + le16_to_cpu (ndacl_ptr -> size );
12941302 /* copy the non-dacl portion of secdesc */
@@ -1587,6 +1595,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
15871595 struct tcon_link * tlink = cifs_sb_tlink (cifs_sb );
15881596 struct smb_version_operations * ops ;
15891597 bool mode_from_sid , id_from_sid ;
1598+ bool posix = tlink_tcon (tlink )-> posix_extensions ;
15901599 const u32 info = 0 ;
15911600
15921601 if (IS_ERR (tlink ))
@@ -1622,12 +1631,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
16221631 id_from_sid = false;
16231632
16241633 /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1625- nsecdesclen = secdesclen ;
16261634 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 ));
16291639 else /* cifsacl */
1630- nsecdesclen += 5 * sizeof (struct smb_ace );
1640+ nsecdesclen = secdesclen + ( 5 * sizeof (struct smb_ace ) );
16311641 } else { /* chown */
16321642 /* When ownership changes, changes new owner sid length could be different */
16331643 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,
16571667 }
16581668
16591669 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 );
16611671
16621672 cifs_dbg (NOISY , "build_sec_desc rc: %d\n" , rc );
16631673
0 commit comments