aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsacl.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2014-02-03 00:31:47 -0500
committerSteve French <smfrench@gmail.com>2014-02-07 12:08:17 -0500
commit83e3bc23ef9ce7c03b7b4e5d3d790246ea59db3e (patch)
tree956aac2ae24b12abc9be303bd74a890c480b434b /fs/cifs/cifsacl.c
parentd979f3b0a1f0b5499ab85e68cdf02b56852918b6 (diff)
retrieving CIFS ACLs when mounted with SMB2 fails dropping session
The get/set ACL xattr support for CIFS ACLs attempts to send old cifs dialect protocol requests even when mounted with SMB2 or later dialects. Sending cifs requests on an smb2 session causes problems - the server drops the session due to the illegal request. This patch makes CIFS ACL operations protocol specific to fix that. Attempting to query/set CIFS ACLs for SMB2 will now return EOPNOTSUPP (until we add worker routines for sending query ACL requests via SMB2) instead of sending invalid (cifs) requests. A separate followon patch will be needed to fix cifs_acl_to_fattr (which takes a cifs specific u16 fid so can't be abstracted to work with SMB2 until that is changed) and will be needed to fix mount problems when "cifsacl" is specified on mount with e.g. vers=2.1 Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com> CC: Stable <stable@kernel.org>
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r--fs/cifs/cifsacl.c28
1 files changed, 24 insertions, 4 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}