aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/connect.c41
-rw-r--r--fs/cifs/smb2pdu.c33
2 files changed, 43 insertions, 31 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 325e3cb17c4c..777ad9f4fc3c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2630,12 +2630,18 @@ get_ses_fail:
2630 return ERR_PTR(rc); 2630 return ERR_PTR(rc);
2631} 2631}
2632 2632
2633static int match_tcon(struct cifs_tcon *tcon, const char *unc) 2633static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
2634{ 2634{
2635 if (tcon->tidStatus == CifsExiting) 2635 if (tcon->tidStatus == CifsExiting)
2636 return 0; 2636 return 0;
2637 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE)) 2637 if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE))
2638 return 0; 2638 return 0;
2639 if (tcon->seal != volume_info->seal)
2640 return 0;
2641#ifdef CONFIG_CIFS_SMB2
2642 if (tcon->snapshot_time != volume_info->snapshot_time)
2643 return 0;
2644#endif /* CONFIG_CIFS_SMB2 */
2639 return 1; 2645 return 1;
2640} 2646}
2641 2647
@@ -2648,14 +2654,8 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2648 spin_lock(&cifs_tcp_ses_lock); 2654 spin_lock(&cifs_tcp_ses_lock);
2649 list_for_each(tmp, &ses->tcon_list) { 2655 list_for_each(tmp, &ses->tcon_list) {
2650 tcon = list_entry(tmp, struct cifs_tcon, tcon_list); 2656 tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
2651 if (!match_tcon(tcon, volume_info->UNC)) 2657 if (!match_tcon(tcon, volume_info))
2652 continue;
2653
2654#ifdef CONFIG_CIFS_SMB2
2655 if (tcon->snapshot_time != volume_info->snapshot_time)
2656 continue; 2658 continue;
2657#endif /* CONFIG_CIFS_SMB2 */
2658
2659 ++tcon->tc_count; 2659 ++tcon->tc_count;
2660 spin_unlock(&cifs_tcp_ses_lock); 2660 spin_unlock(&cifs_tcp_ses_lock);
2661 return tcon; 2661 return tcon;
@@ -2701,8 +2701,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2701 cifs_dbg(FYI, "Found match on UNC path\n"); 2701 cifs_dbg(FYI, "Found match on UNC path\n");
2702 /* existing tcon already has a reference */ 2702 /* existing tcon already has a reference */
2703 cifs_put_smb_ses(ses); 2703 cifs_put_smb_ses(ses);
2704 if (tcon->seal != volume_info->seal)
2705 cifs_dbg(VFS, "transport encryption setting conflicts with existing tid\n");
2706 return tcon; 2704 return tcon;
2707 } 2705 }
2708 2706
@@ -2758,7 +2756,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2758 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; 2756 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2759 cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags); 2757 cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
2760 } 2758 }
2761 tcon->seal = volume_info->seal;
2762 tcon->use_persistent = false; 2759 tcon->use_persistent = false;
2763 /* check if SMB2 or later, CIFS does not support persistent handles */ 2760 /* check if SMB2 or later, CIFS does not support persistent handles */
2764 if (volume_info->persistent) { 2761 if (volume_info->persistent) {
@@ -2795,6 +2792,24 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2795 tcon->use_resilient = true; 2792 tcon->use_resilient = true;
2796 } 2793 }
2797 2794
2795 if (volume_info->seal) {
2796 if (ses->server->vals->protocol_id == 0) {
2797 cifs_dbg(VFS,
2798 "SMB3 or later required for encryption\n");
2799 rc = -EOPNOTSUPP;
2800 goto out_fail;
2801#ifdef CONFIG_CIFS_SMB2
2802 } else if (tcon->ses->server->capabilities &
2803 SMB2_GLOBAL_CAP_ENCRYPTION)
2804 tcon->seal = true;
2805 else {
2806 cifs_dbg(VFS, "Encryption is not supported on share\n");
2807 rc = -EOPNOTSUPP;
2808 goto out_fail;
2809#endif /* CONFIG_CIFS_SMB2 */
2810 }
2811 }
2812
2798 /* 2813 /*
2799 * We can have only one retry value for a connection to a share so for 2814 * We can have only one retry value for a connection to a share so for
2800 * resources mounted more than once to the same server share the last 2815 * resources mounted more than once to the same server share the last
@@ -2926,7 +2941,7 @@ cifs_match_super(struct super_block *sb, void *data)
2926 2941
2927 if (!match_server(tcp_srv, volume_info) || 2942 if (!match_server(tcp_srv, volume_info) ||
2928 !match_session(ses, volume_info) || 2943 !match_session(ses, volume_info) ||
2929 !match_tcon(tcon, volume_info->UNC) || 2944 !match_tcon(tcon, volume_info) ||
2930 !match_prepath(sb, mnt_data)) { 2945 !match_prepath(sb, mnt_data)) {
2931 rc = 0; 2946 rc = 0;
2932 goto out; 2947 goto out;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 0abeb5fb452f..ad83b3db2840 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -79,9 +79,14 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
79 79
80static int encryption_required(const struct cifs_tcon *tcon) 80static int encryption_required(const struct cifs_tcon *tcon)
81{ 81{
82 if (!tcon)
83 return 0;
82 if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) || 84 if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
83 (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)) 85 (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
84 return 1; 86 return 1;
87 if (tcon->seal &&
88 (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
89 return 1;
85 return 0; 90 return 0;
86} 91}
87 92
@@ -835,8 +840,6 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
835 ses->Suid = rsp->hdr.sync_hdr.SessionId; 840 ses->Suid = rsp->hdr.sync_hdr.SessionId;
836 841
837 ses->session_flags = le16_to_cpu(rsp->SessionFlags); 842 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
838 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
839 cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
840 843
841 rc = SMB2_sess_establish_session(sess_data); 844 rc = SMB2_sess_establish_session(sess_data);
842out_put_spnego_key: 845out_put_spnego_key:
@@ -933,8 +936,6 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
933 936
934 ses->Suid = rsp->hdr.sync_hdr.SessionId; 937 ses->Suid = rsp->hdr.sync_hdr.SessionId;
935 ses->session_flags = le16_to_cpu(rsp->SessionFlags); 938 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
936 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
937 cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
938 939
939out: 940out:
940 kfree(ntlmssp_blob); 941 kfree(ntlmssp_blob);
@@ -993,8 +994,6 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
993 994
994 ses->Suid = rsp->hdr.sync_hdr.SessionId; 995 ses->Suid = rsp->hdr.sync_hdr.SessionId;
995 ses->session_flags = le16_to_cpu(rsp->SessionFlags); 996 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
996 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
997 cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
998 997
999 rc = SMB2_sess_establish_session(sess_data); 998 rc = SMB2_sess_establish_session(sess_data);
1000out: 999out:
@@ -1145,12 +1144,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1145 if (tcon && tcon->bad_network_name) 1144 if (tcon && tcon->bad_network_name)
1146 return -ENOENT; 1145 return -ENOENT;
1147 1146
1148 if ((tcon && tcon->seal) &&
1149 ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
1150 cifs_dbg(VFS, "encryption requested but no server support");
1151 return -EOPNOTSUPP;
1152 }
1153
1154 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); 1147 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
1155 if (unc_path == NULL) 1148 if (unc_path == NULL)
1156 return -ENOMEM; 1149 return -ENOMEM;
@@ -1168,15 +1161,16 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1168 return rc; 1161 return rc;
1169 } 1162 }
1170 1163
1171 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
1172 flags |= CIFS_TRANSFORM_REQ;
1173
1174 if (tcon == NULL) { 1164 if (tcon == NULL) {
1165 if ((ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA))
1166 flags |= CIFS_TRANSFORM_REQ;
1167
1175 /* since no tcon, smb2_init can not do this, so do here */ 1168 /* since no tcon, smb2_init can not do this, so do here */
1176 req->hdr.sync_hdr.SessionId = ses->Suid; 1169 req->hdr.sync_hdr.SessionId = ses->Suid;
1177 /* if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED) 1170 /* if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
1178 req->hdr.Flags |= SMB2_FLAGS_SIGNED; */ 1171 req->hdr.Flags |= SMB2_FLAGS_SIGNED; */
1179 } 1172 } else if (encryption_required(tcon))
1173 flags |= CIFS_TRANSFORM_REQ;
1180 1174
1181 iov[0].iov_base = (char *)req; 1175 iov[0].iov_base = (char *)req;
1182 /* 4 for rfc1002 length field and 1 for pad */ 1176 /* 4 for rfc1002 length field and 1 for pad */
@@ -1233,9 +1227,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1233 if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) && 1227 if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
1234 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) 1228 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
1235 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n"); 1229 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
1230
1231 if (tcon->seal &&
1232 !(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
1233 cifs_dbg(VFS, "Encryption is requested but not supported\n");