aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsacl.c28
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/smb1ops.c4
-rw-r--r--fs/cifs/xattr.c15
4 files changed, 43 insertions, 8 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 8f9b4f710d4a..c819b0bd491a 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -1043,15 +1043,30 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1043 __u32 secdesclen = 0; 1043 __u32 secdesclen = 0;
1044 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ 1044 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1045 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ 1045 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1046 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1047 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1048 struct cifs_tcon *tcon;
1049
1050 if (IS_ERR(tlink))
1051 return PTR_ERR(tlink);
1052 tcon = tlink_tcon(tlink);
1046 1053
1047 cifs_dbg(NOISY, "set ACL from mode for %s\n", path); 1054 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1048 1055
1049 /* Get the security descriptor */ 1056 /* Get the security descriptor */
1050 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); 1057
1058 if (tcon->ses->server->ops->get_acl == NULL) {
1059 cifs_put_tlink(tlink);
1060 return -EOPNOTSUPP;
1061 }
1062
1063 pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path,
1064 &secdesclen);
1051 if (IS_ERR(pntsd)) { 1065 if (IS_ERR(pntsd)) {
1052 rc = PTR_ERR(pntsd); 1066 rc = PTR_ERR(pntsd);
1053 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); 1067 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1054 goto out; 1068 cifs_put_tlink(tlink);
1069 return rc;
1055 } 1070 }
1056 1071
1057 /* 1072 /*
@@ -1064,6 +1079,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1064 pnntsd = kmalloc(secdesclen, GFP_KERNEL); 1079 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1065 if (!pnntsd) { 1080 if (!pnntsd) {
1066 kfree(pntsd); 1081 kfree(pntsd);
1082 cifs_put_tlink(tlink);
1067 return -ENOMEM; 1083 return -ENOMEM;
1068 } 1084 }
1069 1085
@@ -1072,14 +1088,18 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1072 1088
1073 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); 1089 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1074 1090
1091 if (tcon->ses->server->ops->set_acl == NULL)
1092 rc = -EOPNOTSUPP;
1093
1075 if (!rc) { 1094 if (!rc) {
1076 /* Set the security descriptor */ 1095 /* Set the security descriptor */
1077 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag); 1096 rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode,
1097 path, aclflag);
1078 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); 1098 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1079 } 1099 }
1100 cifs_put_tlink(tlink);
1080 1101
1081 kfree(pnntsd); 1102 kfree(pnntsd);
1082 kfree(pntsd); 1103 kfree(pntsd);
1083out:
1084 return rc; 1104 return rc;
1085} 1105}
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a245d1809ed8..615e35ab7ef6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -395,6 +395,10 @@ struct smb_version_operations {
395 int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, 395 int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
396 const char *, const void *, const __u16, 396 const char *, const void *, const __u16,
397 const struct nls_table *, int); 397 const struct nls_table *, int);
398 struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *,
399 const char *, u32 *);
400 int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *,
401 int);
398}; 402};
399 403
400struct smb_version_values { 404struct smb_version_values {
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 3e4ff79e3031..bfd66d84831e 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -1071,6 +1071,10 @@ struct smb_version_operations smb1_operations = {
1071 .query_all_EAs = CIFSSMBQAllEAs, 1071 .query_all_EAs = CIFSSMBQAllEAs,
1072 .set_EA = CIFSSMBSetEA, 1072 .set_EA = CIFSSMBSetEA,
1073#endif /* CIFS_XATTR */ 1073#endif /* CIFS_XATTR */
1074#ifdef CONFIG_CIFS_ACL
1075 .get_acl = get_cifs_acl,
1076 .set_acl = set_cifs_acl,
1077#endif /* CIFS_ACL */
1074}; 1078};
1075 1079
1076struct smb_version_values smb1_values = { 1080struct smb_version_values smb1_values = {
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 95c43bb20335..5ac836a86b18 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -176,8 +176,12 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
176 rc = -ENOMEM; 176 rc = -ENOMEM;
177 } else { 177 } else {
178 memcpy(pacl, ea_value, value_size); 178 memcpy(pacl, ea_value, value_size);
179 rc = set_cifs_acl(pacl, value_size, 179 if (pTcon->ses->server->ops->set_acl)
180 direntry->d_inode, full_path, CIFS_ACL_DACL); 180 rc = pTcon->ses->server->ops->set_acl(pacl,
181 value_size, direntry->d_inode,
182 full_path, CIFS_ACL_DACL);
183 else
184 rc = -EOPNOTSUPP;
181 if (rc == 0) /* force revalidate of the inode */ 185 if (rc == 0) /* force revalidate of the inode */
182 CIFS_I(direntry->d_inode)->time = 0; 186 CIFS_I(direntry->d_inode)->time = 0;
183 kfree(pacl); 187 kfree(pacl);
@@ -323,8 +327,11 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
323 u32 acllen; 327 u32 acllen;
324 struct cifs_ntsd *pacl; 328 struct cifs_ntsd *pacl;
325 329
326 pacl = get_cifs_acl(cifs_sb, direntry->d_inode, 330 if (pTcon->ses->server->ops->get_acl == NULL)
327 full_path, &acllen); 331 goto get_ea_exit; /* rc already EOPNOTSUPP */
332
333 pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
334 direntry->d_inode, full_path, &acllen);
328 if (IS_ERR(pacl)) { 335 if (IS_ERR(pacl)) {
329 rc = PTR_ERR(pacl); 336 rc = PTR_ERR(pacl);
330 cifs_dbg(VFS, "%s: error %zd getting sec desc\n", 337 cifs_dbg(VFS, "%s: error %zd getting sec desc\n",