diff options
author | Shirish Pargaonkar <shirishpargaonkar@gmail.com> | 2011-10-13 11:26:03 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2011-10-17 10:11:11 -0400 |
commit | a5ff376966c079bd2f078524eff11b0c63cc2507 (patch) | |
tree | f0a6576a0987ba73589caaadc2b4fde1b24650b5 /fs/cifs | |
parent | d59dad2be038132259ac99a2837d65a87fd90588 (diff) |
cifs: Call id to SID mapping functions to change owner/group (try #4 repost)
Now build security descriptor to change either owner or group at the
server. Initially security descriptor was built to change only
(D)ACL, that functionality has been extended.
When either an Owner or a Group of a file object at the server is changed,
rest of security descriptor remains same (DACL etc.).
To set security descriptor, it is necessary to open that file
with permission bits of either WRITE_DAC if DACL is being modified or
WRITE_OWNER (Take Ownership) if Owner or Group is being changed.
It is the server that decides whether a set security descriptor with
either owner or group change succeeds or not.
Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsacl.c | 135 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 7 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 4 | ||||
-rw-r--r-- | fs/cifs/inode.c | 35 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 2 |
5 files changed, 113 insertions, 70 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 992f1fb299d1..72ddf23ef6f7 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -904,7 +904,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
904 | acl_size = sizeof(struct cifs_acl); | 904 | acl_size = sizeof(struct cifs_acl); |
905 | 905 | ||
906 | num_aces = le32_to_cpu(pdacl->num_aces); | 906 | num_aces = le32_to_cpu(pdacl->num_aces); |
907 | if (num_aces > 0) { | 907 | if (num_aces > 0) { |
908 | umode_t user_mask = S_IRWXU; | 908 | umode_t user_mask = S_IRWXU; |
909 | umode_t group_mask = S_IRWXG; | 909 | umode_t group_mask = S_IRWXG; |
910 | umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO; | 910 | umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO; |
@@ -1066,52 +1066,82 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, | |||
1066 | else | 1066 | else |
1067 | cFYI(1, "no ACL"); /* BB grant all or default perms? */ | 1067 | cFYI(1, "no ACL"); /* BB grant all or default perms? */ |
1068 | 1068 | ||
1069 | /* cifscred->uid = owner_sid_ptr->rid; | ||
1070 | cifscred->gid = group_sid_ptr->rid; | ||
1071 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | ||
1072 | sizeof(struct cifs_sid)); | ||
1073 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | ||
1074 | sizeof(struct cifs_sid)); */ | ||
1075 | |||
1076 | return rc; | 1069 | return rc; |
1077 | } | 1070 | } |
1078 | 1071 | ||
1079 | |||
1080 | /* Convert permission bits from mode to equivalent CIFS ACL */ | 1072 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
1081 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 1073 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
1082 | struct inode *inode, __u64 nmode) | 1074 | __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag) |
1083 | { | 1075 | { |
1084 | int rc = 0; | 1076 | int rc = 0; |
1085 | __u32 dacloffset; | 1077 | __u32 dacloffset; |
1086 | __u32 ndacloffset; | 1078 | __u32 ndacloffset; |
1087 | __u32 sidsoffset; | 1079 | __u32 sidsoffset; |
1088 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | 1080 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
1081 | struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; | ||
1089 | struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ | 1082 | struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ |
1090 | struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ | 1083 | struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ |
1091 | 1084 | ||
1092 | if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL)) | 1085 | if (nmode != NO_CHANGE_64) { /* chmod */ |
1093 | return -EIO; | 1086 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
1094 | |||
1095 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
1096 | le32_to_cpu(pntsd->osidoffset)); | 1087 | le32_to_cpu(pntsd->osidoffset)); |
1097 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 1088 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
1098 | le32_to_cpu(pntsd->gsidoffset)); | 1089 | le32_to_cpu(pntsd->gsidoffset)); |
1099 | 1090 | dacloffset = le32_to_cpu(pntsd->dacloffset); | |
1100 | dacloffset = le32_to_cpu(pntsd->dacloffset); | 1091 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); |
1101 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); | 1092 | ndacloffset = sizeof(struct cifs_ntsd); |
1102 | 1093 | ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); | |
1103 | ndacloffset = sizeof(struct cifs_ntsd); | 1094 | ndacl_ptr->revision = dacl_ptr->revision; |
1104 | ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); | 1095 | ndacl_ptr->size = 0; |
1105 | ndacl_ptr->revision = dacl_ptr->revision; | 1096 | ndacl_ptr->num_aces = 0; |
1106 | ndacl_ptr->size = 0; | 1097 | |
1107 | ndacl_ptr->num_aces = 0; | 1098 | rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, |
1108 | 1099 | nmode); | |
1109 | rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode); | 1100 | sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); |
1110 | 1101 | /* copy sec desc control portion & owner and group sids */ | |
1111 | sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); | 1102 | copy_sec_desc(pntsd, pnntsd, sidsoffset); |
1112 | 1103 | *aclflag = CIFS_ACL_DACL; | |
1113 | /* copy security descriptor control portion and owner and group sid */ | 1104 | } else { |
1114 | copy_sec_desc(pntsd, pnntsd, sidsoffset); | 1105 | memcpy(pnntsd, pntsd, secdesclen); |
1106 | if (uid != NO_CHANGE_32) { /* chown */ | ||
1107 | owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | ||
1108 | le32_to_cpu(pnntsd->osidoffset)); | ||
1109 | nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), | ||
1110 | GFP_KERNEL); | ||
1111 | if (!nowner_sid_ptr) | ||
1112 | return -ENOMEM; | ||
1113 | rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr); | ||
1114 | if (rc) { | ||
1115 | cFYI(1, "%s: Mapping error %d for owner id %d", | ||
1116 | __func__, rc, uid); | ||
1117 | kfree(nowner_sid_ptr); | ||
1118 | return rc; | ||
1119 | } | ||
1120 | memcpy(owner_sid_ptr, nowner_sid_ptr, | ||
1121 | sizeof(struct cifs_sid)); | ||
1122 | kfree(nowner_sid_ptr); | ||
1123 | *aclflag = CIFS_ACL_OWNER; | ||
1124 | } | ||
1125 | if (gid != NO_CHANGE_32) { /* chgrp */ | ||
1126 | group_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | ||
1127 | le32_to_cpu(pnntsd->gsidoffset)); | ||
1128 | ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), | ||
1129 | GFP_KERNEL); | ||
1130 | if (!ngroup_sid_ptr) | ||
1131 | return -ENOMEM; | ||
1132 | rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr); | ||
1133 | if (rc) { | ||
1134 | cFYI(1, "%s: Mapping error %d for group id %d", | ||
1135 | __func__, rc, gid); | ||
1136 | kfree(ngroup_sid_ptr); | ||
1137 | return rc; | ||
1138 | } | ||
1139 | memcpy(group_sid_ptr, ngroup_sid_ptr, | ||
1140 | sizeof(struct cifs_sid)); | ||
1141 | kfree(ngroup_sid_ptr); | ||
1142 | *aclflag = CIFS_ACL_GROUP; | ||
1143 | } | ||
1144 | } | ||
1115 | 1145 | ||
1116 | return rc; | 1146 | return rc; |
1117 | } | 1147 | } |
@@ -1192,13 +1222,15 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, | |||
1192 | return pntsd; | 1222 | return pntsd; |
1193 | } | 1223 | } |
1194 | 1224 | ||
1195 | static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, | 1225 | /* Set an ACL on the server */ |
1196 | struct cifs_ntsd *pnntsd, u32 acllen) | 1226 | int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, |
1227 | struct inode *inode, const char *path, int aclflag) | ||
1197 | { | 1228 | { |
1198 | int oplock = 0; | 1229 | int oplock = 0; |
1199 | int xid, rc, create_options = 0; | 1230 | int xid, rc, access_flags, create_options = 0; |
1200 | __u16 fid; | 1231 | __u16 fid; |
1201 | struct cifs_tcon *tcon; | 1232 | struct cifs_tcon *tcon; |
1233 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
1202 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | 1234 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
1203 | 1235 | ||
1204 | if (IS_ERR(tlink)) | 1236 | if (IS_ERR(tlink)) |
@@ -1210,15 +1242,20 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, | |||
1210 | if (backup_cred(cifs_sb)) | 1242 | if (backup_cred(cifs_sb)) |
1211 | create_options |= CREATE_OPEN_BACKUP_INTENT; | 1243 | create_options |= CREATE_OPEN_BACKUP_INTENT; |
1212 | 1244 | ||
1213 | rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, create_options, | 1245 | if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP) |
1214 | &fid, &oplock, NULL, cifs_sb->local_nls, | 1246 | access_flags = WRITE_OWNER; |
1215 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 1247 | else |
1248 | access_flags = WRITE_DAC; | ||
1249 | |||
1250 | rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags, | ||
1251 | create_options, &fid, &oplock, NULL, cifs_sb->local_nls, | ||
1252 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1216 | if (rc) { | 1253 | if (rc) { |
1217 | cERROR(1, "Unable to open file to set ACL"); | 1254 | cERROR(1, "Unable to open file to set ACL"); |
1218 | goto out; | 1255 | goto out; |
1219 | } | 1256 | } |
1220 | 1257 | ||
1221 | rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen); | 1258 | rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag); |
1222 | cFYI(DBG2, "SetCIFSACL rc = %d", rc); | 1259 | cFYI(DBG2, "SetCIFSACL rc = %d", rc); |
1223 | 1260 | ||
1224 | CIFSSMBClose(xid, tcon, fid); | 1261 | CIFSSMBClose(xid, tcon, fid); |
@@ -1228,17 +1265,6 @@ out: | |||
1228 | return rc; | 1265 | return rc; |
1229 | } | 1266 | } |
1230 | 1267 | ||
1231 | /* Set an ACL on the server */ | ||
1232 | int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | ||
1233 | struct inode *inode, const char *path) | ||
1234 | { | ||
1235 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
1236 | |||
1237 | cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode); | ||
1238 | |||
1239 | return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); | ||
1240 | } | ||
1241 | |||
1242 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 1268 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
1243 | int | 1269 | int |
1244 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | 1270 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
@@ -1270,9 +1296,12 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
1270 | } | 1296 | } |
1271 | 1297 | ||
1272 | /* Convert mode bits to an ACL so we can update the ACL on the server */ | 1298 | /* Convert mode bits to an ACL so we can update the ACL on the server */ |
1273 | int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode) | 1299 | int |
1300 | id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | ||
1301 | uid_t uid, gid_t gid) | ||
1274 | { | 1302 | { |
1275 | int rc = 0; | 1303 | int rc = 0; |
1304 | int aclflag = CIFS_ACL_DACL; /* default flag to set */ | ||
1276 | __u32 secdesclen = 0; | 1305 | __u32 secdesclen = 0; |
1277 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ | 1306 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
1278 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | 1307 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ |
@@ -1302,13 +1331,15 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode) | |||
1302 | return -ENOMEM; | 1331 | return -ENOMEM; |
1303 | } | 1332 | } |
1304 | 1333 | ||
1305 | rc = build_sec_desc(pntsd, pnntsd, inode, nmode); | 1334 | rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, |
1335 | &aclflag); | ||
1306 | 1336 | ||
1307 | cFYI(DBG2, "build_sec_desc rc: %d", rc); | 1337 | cFYI(DBG2, "build_sec_desc rc: %d", rc); |
1308 | 1338 | ||
1309 | if (!rc) { | 1339 | if (!rc) { |
1310 | /* Set the security descriptor */ | 1340 | /* Set the security descriptor */ |
1311 | rc = set_cifs_acl(pnntsd, secdesclen, inode, path); | 1341 | rc = set_cifs_acl(pnntsd, secdesclen, inode, |
1342 | path, aclflag); | ||
1312 | cFYI(DBG2, "set_cifs_acl rc: %d", rc); | 1343 | cFYI(DBG2, "set_cifs_acl rc: %d", rc); |
1313 | } | 1344 | } |
1314 | 1345 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 94834dbb46da..a1fa9cec05d6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -146,11 +146,12 @@ extern int cifs_get_inode_info_unix(struct inode **pinode, | |||
146 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | 146 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, |
147 | struct cifs_fattr *fattr, struct inode *inode, | 147 | struct cifs_fattr *fattr, struct inode *inode, |
148 | const char *path, const __u16 *pfid); | 148 | const char *path, const __u16 *pfid); |
149 | extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64); | 149 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, |
150 | uid_t, gid_t); | ||
150 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, | 151 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, |
151 | const char *, u32 *); | 152 | const char *, u32 *); |
152 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | 153 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, |
153 | const char *); | 154 | const char *, int); |
154 | 155 | ||
155 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 156 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
156 | struct cifs_sb_info *cifs_sb); | 157 | struct cifs_sb_info *cifs_sb); |
@@ -420,7 +421,7 @@ extern int CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, | |||
420 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, | 421 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, |
421 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); | 422 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); |
422 | extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16, | 423 | extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16, |
423 | struct cifs_ntsd *, __u32); | 424 | struct cifs_ntsd *, __u32, int); |
424 | extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon, | 425 | extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon, |
425 | const unsigned char *searchName, | 426 | const unsigned char *searchName, |
426 | char *acl_inf, const int buflen, const int acl_type, | 427 | char *acl_inf, const int buflen, const int acl_type, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index e33093f7ef0d..c824c106b2b7 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3463,7 +3463,7 @@ qsec_out: | |||
3463 | 3463 | ||
3464 | int | 3464 | int |
3465 | CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid, | 3465 | CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid, |
3466 | struct cifs_ntsd *pntsd, __u32 acllen) | 3466 | struct cifs_ntsd *pntsd, __u32 acllen, int aclflag) |
3467 | { | 3467 | { |
3468 | __u16 byte_count, param_count, data_count, param_offset, data_offset; | 3468 | __u16 byte_count, param_count, data_count, param_offset, data_offset; |
3469 | int rc = 0; | 3469 | int rc = 0; |
@@ -3500,7 +3500,7 @@ setCifsAclRetry: | |||
3500 | 3500 | ||
3501 | pSMB->Fid = fid; /* file handle always le */ | 3501 | pSMB->Fid = fid; /* file handle always le */ |
3502 | pSMB->Reserved2 = 0; | 3502 | pSMB->Reserved2 = 0; |
3503 | pSMB->AclFlags = cpu_to_le32(CIFS_ACL_DACL); | 3503 | pSMB->AclFlags = cpu_to_le32(aclflag); |
3504 | 3504 | ||
3505 | if (pntsd && acllen) { | 3505 | if (pntsd && acllen) { |
3506 | memcpy((char *) &pSMBr->hdr.Protocol + data_offset, | 3506 | memcpy((char *) &pSMBr->hdr.Protocol + data_offset, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a7b2dcd4a53e..663c4e313be4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -2096,6 +2096,8 @@ static int | |||
2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | 2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
2097 | { | 2097 | { |
2098 | int xid; | 2098 | int xid; |
2099 | uid_t uid = NO_CHANGE_32; | ||
2100 | gid_t gid = NO_CHANGE_32; | ||
2099 | struct inode *inode = direntry->d_inode; | 2101 | struct inode *inode = direntry->d_inode; |
2100 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 2102 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
2101 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 2103 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
@@ -2146,13 +2148,25 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2146 | goto cifs_setattr_exit; | 2148 | goto cifs_setattr_exit; |
2147 | } | 2149 | } |
2148 | 2150 | ||
2149 | /* | 2151 | if (attrs->ia_valid & ATTR_UID) |
2150 | * Without unix extensions we can't send ownership changes to the | 2152 | uid = attrs->ia_uid; |
2151 | * server, so silently ignore them. This is consistent with how | 2153 | |
2152 | * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With | 2154 | if (attrs->ia_valid & ATTR_GID) |
2153 | * CIFSACL support + proper Windows to Unix idmapping, we may be | 2155 | gid = attrs->ia_gid; |
2154 | * able to support this in the future. | 2156 | |
2155 | */ | 2157 | #ifdef CONFIG_CIFS_ACL |
2158 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
2159 | if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) { | ||
2160 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, | ||
2161 | uid, gid); | ||
2162 | if (rc) { | ||
2163 | cFYI(1, "%s: Setting id failed with error: %d", | ||
2164 | __func__, rc); | ||
2165 | goto cifs_setattr_exit; | ||
2166 | } | ||
2167 | } | ||
2168 | } else | ||
2169 | #endif /* CONFIG_CIFS_ACL */ | ||
2156 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) | 2170 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
2157 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); | 2171 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
2158 | 2172 | ||
@@ -2161,15 +2175,12 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2161 | attrs->ia_valid &= ~ATTR_MODE; | 2175 | attrs->ia_valid &= ~ATTR_MODE; |
2162 | 2176 | ||
2163 | if (attrs->ia_valid & ATTR_MODE) { | 2177 | if (attrs->ia_valid & ATTR_MODE) { |
2164 | cFYI(1, "Mode changed to 0%o", attrs->ia_mode); | ||
2165 | mode = attrs->ia_mode; | 2178 | mode = attrs->ia_mode; |
2166 | } | ||
2167 | |||
2168 | if (attrs->ia_valid & ATTR_MODE) { | ||
2169 | rc = 0; | 2179 | rc = 0; |
2170 | #ifdef CONFIG_CIFS_ACL | 2180 | #ifdef CONFIG_CIFS_ACL |
2171 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2181 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2172 | rc = mode_to_cifs_acl(inode, full_path, mode); | 2182 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
2183 | NO_CHANGE_32, NO_CHANGE_32); | ||
2173 | if (rc) { | 2184 | if (rc) { |
2174 | cFYI(1, "%s: Setting ACL failed with error: %d", | 2185 | cFYI(1, "%s: Setting ACL failed with error: %d", |
2175 | __func__, rc); | 2186 | __func__, rc); |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 2a22fb2989e4..fde15b1a1eb5 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -178,7 +178,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
178 | #ifdef CONFIG_CIFS_ACL | 178 | #ifdef CONFIG_CIFS_ACL |
179 | memcpy(pacl, ea_value, value_size); | 179 | memcpy(pacl, ea_value, value_size); |
180 | rc = set_cifs_acl(pacl, value_size, | 180 | rc = set_cifs_acl(pacl, value_size, |
181 | direntry->d_inode, full_path); | 181 | direntry->d_inode, full_path, CIFS_ACL_DACL); |
182 | if (rc == 0) /* force revalidate of the inode */ | 182 | if (rc == 0) /* force revalidate of the inode */ |
183 | CIFS_I(direntry->d_inode)->time = 0; | 183 | CIFS_I(direntry->d_inode)->time = 0; |
184 | kfree(pacl); | 184 | kfree(pacl); |