diff options
-rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 3 | ||||
-rw-r--r-- | fs/cifs/sess.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 1 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 37 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 2 |
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 | ||
448 | struct smb_version_values { | 451 | struct 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, | |||
533 | int __cifs_calc_signature(struct smb_rqst *rqst, | 533 | int __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); |
536 | enum 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 | ||
500 | enum securityEnum | 500 | enum securityEnum |
501 | select_sectype(struct TCP_Server_Info *server, enum securityEnum requested) | 501 | cifs_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 | ||
2386 | struct smb_version_operations smb21_operations = { | 2387 | struct 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 | ||
2468 | struct smb_version_operations smb30_operations = { | 2470 | struct 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 | ||
660 | enum securityEnum | ||
661 | smb2_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 | |||
660 | struct SMB2_sess_data { | 682 | struct 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: | |||
1009 | static int | 1031 | static int |
1010 | SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data) | 1032 | SMB2_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); |
182 | extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); | 182 | extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); |
183 | 183 | ||
184 | extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, | ||
185 | enum securityEnum); | ||
184 | #endif /* _SMB2PROTO_H */ | 186 | #endif /* _SMB2PROTO_H */ |