aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/connect.c3
-rw-r--r--fs/cifs/sess.c4
-rw-r--r--fs/cifs/smb1ops.c1
-rw-r--r--fs/cifs/smb2ops.c4
-rw-r--r--fs/cifs/smb2pdu.c37
-rw-r--r--fs/cifs/smb2proto.h2
8 files changed, 49 insertions, 7 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index af224cda8697..d42dd3288647 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -443,6 +443,9 @@ struct smb_version_operations {
443 int (*is_transform_hdr)(void *buf); 443 int (*is_transform_hdr)(void *buf);
444 int (*receive_transform)(struct TCP_Server_Info *, 444 int (*receive_transform)(struct TCP_Server_Info *,
445 struct mid_q_entry **); 445 struct mid_q_entry **);
446 enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
447 enum securityEnum);
448
446}; 449};
447 450
448struct smb_version_values { 451struct smb_version_values {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 9ee46c1c3ebd..97e5d236d265 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -533,4 +533,6 @@ int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
533int __cifs_calc_signature(struct smb_rqst *rqst, 533int __cifs_calc_signature(struct smb_rqst *rqst,
534 struct TCP_Server_Info *server, char *signature, 534 struct TCP_Server_Info *server, char *signature,
535 struct shash_desc *shash); 535 struct shash_desc *shash);
536enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
537 enum securityEnum);
536#endif /* _CIFSPROTO_H */ 538#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 777ad9f4fc3c..de4c56e8fb37 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2073,7 +2073,8 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
2073 * that was specified, or "Unspecified" if that sectype was not 2073 * that was specified, or "Unspecified" if that sectype was not
2074 * compatible with the given NEGOTIATE request. 2074 * compatible with the given NEGOTIATE request.
2075 */ 2075 */
2076 if (select_sectype(server, vol->sectype) == Unspecified) 2076 if (server->ops->select_sectype(server, vol->sectype)
2077 == Unspecified)
2077 return false; 2078 return false;
2078 2079
2079 /* 2080 /*
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index dcbcc927399a..8b0502cd39af 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -498,7 +498,7 @@ setup_ntlmv2_ret:
498} 498}
499 499
500enum securityEnum 500enum securityEnum
501select_sectype(struct TCP_Server_Info *server, enum securityEnum requested) 501cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
502{ 502{
503 switch (server->negflavor) { 503 switch (server->negflavor) {
504 case CIFS_NEGFLAVOR_EXTENDED: 504 case CIFS_NEGFLAVOR_EXTENDED:
@@ -1391,7 +1391,7 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
1391{ 1391{
1392 int type; 1392 int type;
1393 1393
1394 type = select_sectype(ses->server, ses->sectype); 1394 type = cifs_select_sectype(ses->server, ses->sectype);
1395 cifs_dbg(FYI, "sess setup type %d\n", type); 1395 cifs_dbg(FYI, "sess setup type %d\n", type);
1396 if (type == Unspecified) { 1396 if (type == Unspecified) {
1397 cifs_dbg(VFS, 1397 cifs_dbg(VFS,
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 67a987e4d026..cc93ba4da9b5 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -1087,6 +1087,7 @@ struct smb_version_operations smb1_operations = {
1087 .is_read_op = cifs_is_read_op, 1087 .is_read_op = cifs_is_read_op,
1088 .wp_retry_size = cifs_wp_retry_size, 1088 .wp_retry_size = cifs_wp_retry_size,
1089 .dir_needs_close = cifs_dir_needs_close, 1089 .dir_needs_close = cifs_dir_needs_close,
1090 .select_sectype = cifs_select_sectype,
1090#ifdef CONFIG_CIFS_XATTR 1091#ifdef CONFIG_CIFS_XATTR
1091 .query_all_EAs = CIFSSMBQAllEAs, 1092 .query_all_EAs = CIFSSMBQAllEAs,
1092 .set_EA = CIFSSMBSetEA, 1093 .set_EA = CIFSSMBSetEA,
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index b360c381b00e..0231108d9387 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2381,6 +2381,7 @@ struct smb_version_operations smb20_operations = {
2381 .wp_retry_size = smb2_wp_retry_size, 2381 .wp_retry_size = smb2_wp_retry_size,
2382 .dir_needs_close = smb2_dir_needs_close, 2382 .dir_needs_close = smb2_dir_needs_close,
2383 .get_dfs_refer = smb2_get_dfs_refer, 2383 .get_dfs_refer = smb2_get_dfs_refer,
2384 .select_sectype = smb2_select_sectype,
2384}; 2385};
2385 2386
2386struct smb_version_operations smb21_operations = { 2387struct smb_version_operations smb21_operations = {
@@ -2463,6 +2464,7 @@ struct smb_version_operations smb21_operations = {
2463 .dir_needs_close = smb2_dir_needs_close, 2464 .dir_needs_close = smb2_dir_needs_close,
2464 .enum_snapshots = smb3_enum_snapshots, 2465 .enum_snapshots = smb3_enum_snapshots,
2465 .get_dfs_refer = smb2_get_dfs_refer, 2466 .get_dfs_refer = smb2_get_dfs_refer,
2467 .select_sectype = smb2_select_sectype,
2466}; 2468};
2467 2469
2468struct smb_version_operations smb30_operations = { 2470struct smb_version_operations smb30_operations = {
@@ -2555,6 +2557,7 @@ struct smb_version_operations smb30_operations = {
2555 .is_transform_hdr = smb3_is_transform_hdr, 2557 .is_transform_hdr = smb3_is_transform_hdr,
2556 .receive_transform = smb3_receive_transform, 2558 .receive_transform = smb3_receive_transform,
2557 .get_dfs_refer = smb2_get_dfs_refer, 2559 .get_dfs_refer = smb2_get_dfs_refer,
2560 .select_sectype = smb2_select_sectype,
2558}; 2561};
2559 2562
2560#ifdef CONFIG_CIFS_SMB311 2563#ifdef CONFIG_CIFS_SMB311
@@ -2648,6 +2651,7 @@ struct smb_version_operations smb311_operations = {
2648 .is_transform_hdr = smb3_is_transform_hdr, 2651 .is_transform_hdr = smb3_is_transform_hdr,
2649 .receive_transform = smb3_receive_transform, 2652 .receive_transform = smb3_receive_transform,
2650 .get_dfs_refer = smb2_get_dfs_refer, 2653 .get_dfs_refer = smb2_get_dfs_refer,
2654 .select_sectype = smb2_select_sectype,
2651}; 2655};
2652#endif /* CIFS_SMB311 */ 2656#endif /* CIFS_SMB311 */
2653 2657
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 2069431b32e3..7446496850a3 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -657,6 +657,28 @@ vneg_out:
657 return -EIO; 657 return -EIO;
658} 658}
659 659
660enum securityEnum
661smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
662{
663 switch (requested) {
664 case Kerberos:
665 case RawNTLMSSP:
666 return requested;
667 case NTLMv2:
668 return RawNTLMSSP;
669 case Unspecified:
670 if (server->sec_ntlmssp &&
671 (global_secflags & CIFSSEC_MAY_NTLMSSP))
672 return RawNTLMSSP;
673 if ((server->sec_kerberos || server->sec_mskerberos) &&
674 (global_secflags & CIFSSEC_MAY_KRB5))
675 return Kerberos;
676 /* Fallthrough */
677 default:
678 return Unspecified;
679 }
680}
681
660struct SMB2_sess_data { 682struct SMB2_sess_data {
661 unsigned int xid; 683 unsigned int xid;
662 struct cifs_ses *ses; 684 struct cifs_ses *ses;
@@ -1009,10 +1031,17 @@ out:
1009static int 1031static int
1010SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data) 1032SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data)
1011{ 1033{
1012 if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP) 1034 int type;
1013 ses->sectype = RawNTLMSSP; 1035
1036 type = smb2_select_sectype(ses->server, ses->sectype);
1037 cifs_dbg(FYI, "sess setup type %d\n", type);
1038 if (type == Unspecified) {
1039 cifs_dbg(VFS,
1040 "Unable to select appropriate authentication method!");
1041 return -EINVAL;
1042 }
1014 1043
1015 switch (ses->sectype) { 1044 switch (type) {
1016 case Kerberos: 1045 case Kerberos:
1017 sess_data->func = SMB2_auth_kerberos; 1046 sess_data->func = SMB2_auth_kerberos;
1018 break; 1047 break;
@@ -1020,7 +1049,7 @@ SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data)
1020 sess_data->func = SMB2_sess_auth_rawntlmssp_negotiate; 1049 sess_data->func = SMB2_sess_auth_rawntlmssp_negotiate;
1021 break; 1050 break;
1022 default: 1051 default:
1023 cifs_dbg(VFS, "secType %d not supported!\n", ses->sectype); 1052 cifs_dbg(VFS, "secType %d not supported!\n", type);
1024 return -EOPNOTSUPP; 1053 return -EOPNOTSUPP;
1025 } 1054 }
1026 1055
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 11d9f3013db8..69e35873b1de 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -181,4 +181,6 @@ extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
181 __u8 *lease_key, const __le32 lease_state); 181 __u8 *lease_key, const __le32 lease_state);
182extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); 182extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
183 183
184extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
185 enum securityEnum);
184#endif /* _SMB2PROTO_H */ 186#endif /* _SMB2PROTO_H */