Skip to content

Commit ef65aae

Browse files
spuiuksmfrench
authored andcommitted
smb2: Enforce sec= mount option
If the security type specified using a mount option is not supported, the SMB2 session setup code changes the security type to RawNTLMSSP. We should instead fail the mount and return an error. The patch changes the code for SMB2 to make it similar to the code used for SMB1. Like in SMB1, we now use the global security flags to select the security method to be used when no security method is specified and to return an error when the requested auth method is not available. For SMB2, we also use ntlmv2 as a synonym for nltmssp. Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Acked-by: Pavel Shilovsky <pshilov@microsoft.com> Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
1 parent 284316d commit ef65aae

File tree

8 files changed

+49
-7
lines changed

8 files changed

+49
-7
lines changed

fs/cifs/cifsglob.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ struct smb_version_operations {
443443
int (*is_transform_hdr)(void *buf);
444444
int (*receive_transform)(struct TCP_Server_Info *,
445445
struct mid_q_entry **);
446+
enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
447+
enum securityEnum);
448+
446449
};
447450

448451
struct smb_version_values {

fs/cifs/cifsproto.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,6 @@ int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
533533
int __cifs_calc_signature(struct smb_rqst *rqst,
534534
struct TCP_Server_Info *server, char *signature,
535535
struct shash_desc *shash);
536+
enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
537+
enum securityEnum);
536538
#endif /* _CIFSPROTO_H */

fs/cifs/connect.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2073,7 +2073,8 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
20732073
* that was specified, or "Unspecified" if that sectype was not
20742074
* compatible with the given NEGOTIATE request.
20752075
*/
2076-
if (select_sectype(server, vol->sectype) == Unspecified)
2076+
if (server->ops->select_sectype(server, vol->sectype)
2077+
== Unspecified)
20772078
return false;
20782079

20792080
/*

fs/cifs/sess.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
498498
}
499499

500500
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)
502502
{
503503
switch (server->negflavor) {
504504
case CIFS_NEGFLAVOR_EXTENDED:
@@ -1391,7 +1391,7 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
13911391
{
13921392
int type;
13931393

1394-
type = select_sectype(ses->server, ses->sectype);
1394+
type = cifs_select_sectype(ses->server, ses->sectype);
13951395
cifs_dbg(FYI, "sess setup type %d\n", type);
13961396
if (type == Unspecified) {
13971397
cifs_dbg(VFS,

fs/cifs/smb1ops.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,7 @@ struct smb_version_operations smb1_operations = {
10871087
.is_read_op = cifs_is_read_op,
10881088
.wp_retry_size = cifs_wp_retry_size,
10891089
.dir_needs_close = cifs_dir_needs_close,
1090+
.select_sectype = cifs_select_sectype,
10901091
#ifdef CONFIG_CIFS_XATTR
10911092
.query_all_EAs = CIFSSMBQAllEAs,
10921093
.set_EA = CIFSSMBSetEA,

fs/cifs/smb2ops.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,7 @@ struct smb_version_operations smb20_operations = {
23812381
.wp_retry_size = smb2_wp_retry_size,
23822382
.dir_needs_close = smb2_dir_needs_close,
23832383
.get_dfs_refer = smb2_get_dfs_refer,
2384+
.select_sectype = smb2_select_sectype,
23842385
};
23852386

23862387
struct smb_version_operations smb21_operations = {
@@ -2463,6 +2464,7 @@ struct smb_version_operations smb21_operations = {
24632464
.dir_needs_close = smb2_dir_needs_close,
24642465
.enum_snapshots = smb3_enum_snapshots,
24652466
.get_dfs_refer = smb2_get_dfs_refer,
2467+
.select_sectype = smb2_select_sectype,
24662468
};
24672469

24682470
struct smb_version_operations smb30_operations = {
@@ -2555,6 +2557,7 @@ struct smb_version_operations smb30_operations = {
25552557
.is_transform_hdr = smb3_is_transform_hdr,
25562558
.receive_transform = smb3_receive_transform,
25572559
.get_dfs_refer = smb2_get_dfs_refer,
2560+
.select_sectype = smb2_select_sectype,
25582561
};
25592562

25602563
#ifdef CONFIG_CIFS_SMB311
@@ -2648,6 +2651,7 @@ struct smb_version_operations smb311_operations = {
26482651
.is_transform_hdr = smb3_is_transform_hdr,
26492652
.receive_transform = smb3_receive_transform,
26502653
.get_dfs_refer = smb2_get_dfs_refer,
2654+
.select_sectype = smb2_select_sectype,
26512655
};
26522656
#endif /* CIFS_SMB311 */
26532657

fs/cifs/smb2pdu.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,28 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
657657
return -EIO;
658658
}
659659

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+
660682
struct SMB2_sess_data {
661683
unsigned int xid;
662684
struct cifs_ses *ses;
@@ -1009,18 +1031,25 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
10091031
static int
10101032
SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data)
10111033
{
1012-
if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP)
1013-
ses->sectype = RawNTLMSSP;
1034+
int type;
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+
}
10141043

1015-
switch (ses->sectype) {
1044+
switch (type) {
10161045
case Kerberos:
10171046
sess_data->func = SMB2_auth_kerberos;
10181047
break;
10191048
case RawNTLMSSP:
10201049
sess_data->func = SMB2_sess_auth_rawntlmssp_negotiate;
10211050
break;
10221051
default:
1023-
cifs_dbg(VFS, "secType %d not supported!\n", ses->sectype);
1052+
cifs_dbg(VFS, "secType %d not supported!\n", type);
10241053
return -EOPNOTSUPP;
10251054
}
10261055

fs/cifs/smb2proto.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,6 @@ extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
181181
__u8 *lease_key, const __le32 lease_state);
182182
extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
183183

184+
extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
185+
enum securityEnum);
184186
#endif /* _SMB2PROTO_H */

0 commit comments

Comments
 (0)