Re: [PATCH v2] smb2: Enforce sec= mount option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2017-01-25 5:36 GMT-08:00 Jeff Layton <jlayton@xxxxxxxxxx>:
> On Wed, 2017-01-18 at 15:35 +0530, Sachin Prabhu wrote:
>> 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@xxxxxxxxxx>
>> ---
>>  fs/cifs/cifsglob.h  |  3 +++
>>  fs/cifs/cifsproto.h |  2 ++
>>  fs/cifs/connect.c   |  3 ++-
>>  fs/cifs/sess.c      |  4 ++--
>>  fs/cifs/smb1ops.c   |  1 +
>>  fs/cifs/smb2ops.c   |  4 ++++
>>  fs/cifs/smb2pdu.c   | 37 +++++++++++++++++++++++++++++++++----
>>  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 7ea8a33..417af3f 100644
>> --- a/fs/cifs/cifsglob.h
>> +++ b/fs/cifs/cifsglob.h
>> @@ -433,6 +433,9 @@ struct smb_version_operations {
>>       bool (*dir_needs_close)(struct cifsFileInfo *);
>>       long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
>>                         loff_t);
>> +     enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
>> +                         enum securityEnum);
>> +
>>  };
>>
>>  struct smb_version_values {
>> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>> index c7b3c84..88da716 100644
>> --- a/fs/cifs/cifsproto.h
>> +++ b/fs/cifs/cifsproto.h
>> @@ -519,4 +519,6 @@ int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
>>  int __cifs_calc_signature(struct smb_rqst *rqst,
>>                       struct TCP_Server_Info *server, char *signature,
>>                       struct shash_desc *shash);
>> +enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
>> +                                     enum securityEnum);
>>  #endif                       /* _CIFSPROTO_H */
>> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
>> index 35ae49e..327a6cb 100644
>> --- a/fs/cifs/connect.c
>> +++ b/fs/cifs/connect.c
>> @@ -2057,7 +2057,8 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
>>        * that was specified, or "Unspecified" if that sectype was not
>>        * compatible with the given NEGOTIATE request.
>>        */
>> -     if (select_sectype(server, vol->sectype) == Unspecified)
>> +     if (server->ops->select_sectype(server, vol->sectype)
>> +          == Unspecified)
>>               return false;
>>
>>       /*
>> diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
>> index 538d9b5..55c337d 100644
>> --- a/fs/cifs/sess.c
>> +++ b/fs/cifs/sess.c
>> @@ -500,7 +500,7 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
>>  }
>>
>>  enum securityEnum
>> -select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
>> +cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
>>  {
>>       switch (server->negflavor) {
>>       case CIFS_NEGFLAVOR_EXTENDED:
>> @@ -1390,7 +1390,7 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
>>  {
>>       int type;
>>
>> -     type = select_sectype(ses->server, ses->sectype);
>> +     type = cifs_select_sectype(ses->server, ses->sectype);
>>       cifs_dbg(FYI, "sess setup type %d\n", type);
>>       if (type == Unspecified) {
>>               cifs_dbg(VFS,
>> diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
>> index fc537c2..1399671 100644
>> --- a/fs/cifs/smb1ops.c
>> +++ b/fs/cifs/smb1ops.c
>> @@ -1087,6 +1087,7 @@ struct smb_version_operations smb1_operations = {
>>       .is_read_op = cifs_is_read_op,
>>       .wp_retry_size = cifs_wp_retry_size,
>>       .dir_needs_close = cifs_dir_needs_close,
>> +     .select_sectype = cifs_select_sectype,
>>  #ifdef CONFIG_CIFS_XATTR
>>       .query_all_EAs = CIFSSMBQAllEAs,
>>       .set_EA = CIFSSMBSetEA,
>> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
>> index 5d456eb..8d9fda2 100644
>> --- a/fs/cifs/smb2ops.c
>> +++ b/fs/cifs/smb2ops.c
>> @@ -1623,6 +1623,7 @@ struct smb_version_operations smb20_operations = {
>>       .clone_range = smb2_clone_range,
>>       .wp_retry_size = smb2_wp_retry_size,
>>       .dir_needs_close = smb2_dir_needs_close,
>> +     .select_sectype = smb2_select_sectype,
>>  };
>>
>>  struct smb_version_operations smb21_operations = {
>> @@ -1704,6 +1705,7 @@ struct smb_version_operations smb21_operations = {
>>       .wp_retry_size = smb2_wp_retry_size,
>>       .dir_needs_close = smb2_dir_needs_close,
>>       .enum_snapshots = smb3_enum_snapshots,
>> +     .select_sectype = smb2_select_sectype,
>>  };
>>
>>  struct smb_version_operations smb30_operations = {
>> @@ -1791,6 +1793,7 @@ struct smb_version_operations smb30_operations = {
>>       .dir_needs_close = smb2_dir_needs_close,
>>       .fallocate = smb3_fallocate,
>>       .enum_snapshots = smb3_enum_snapshots,
>> +     .select_sectype = smb2_select_sectype,
>>  };
>>
>>  #ifdef CONFIG_CIFS_SMB311
>> @@ -1879,6 +1882,7 @@ struct smb_version_operations smb311_operations = {
>>       .dir_needs_close = smb2_dir_needs_close,
>>       .fallocate = smb3_fallocate,
>>       .enum_snapshots = smb3_enum_snapshots,
>> +     .select_sectype = smb2_select_sectype,
>>  };
>>  #endif /* CIFS_SMB311 */
>>
>> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
>> index 8745722..316045a 100644
>> --- a/fs/cifs/smb2pdu.c
>> +++ b/fs/cifs/smb2pdu.c
>> @@ -596,6 +596,28 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
>>       return -EIO;
>>  }
>>
>> +enum securityEnum
>> +smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
>> +{
>> +     switch (requested) {
>> +     case Kerberos:
>> +     case RawNTLMSSP:
>> +             return requested;
>> +     case NTLMv2:
>> +             return RawNTLMSSP;
>> +     case Unspecified:
>> +             if (server->sec_ntlmssp &&
>> +                     (global_secflags & CIFSSEC_MAY_NTLMSSP))
>> +                     return RawNTLMSSP;
>> +             if ((server->sec_kerberos || server->sec_mskerberos) &&
>> +                     (global_secflags & CIFSSEC_MAY_KRB5))
>> +                     return Kerberos;
>> +             /* Fallthrough */
>> +     default:
>> +             return Unspecified;
>> +     }
>> +}
>> +
>>  struct SMB2_sess_data {
>>       unsigned int xid;
>>       struct cifs_ses *ses;
>> @@ -958,10 +980,17 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
>>  static int
>>  SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data)
>>  {
>> -     if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP)
>> -             ses->sectype = RawNTLMSSP;
>> +     int type;
>> +
>> +     type = smb2_select_sectype(ses->server, ses->sectype);
>> +     cifs_dbg(FYI, "sess setup type %d\n", type);
>> +     if (type == Unspecified) {
>> +             cifs_dbg(VFS,
>> +                     "Unable to select appropriate authentication method!");
>> +             return -EINVAL;
>> +     }
>>
>> -     switch (ses->sectype) {
>> +     switch (type) {
>>       case Kerberos:
>>               sess_data->func = SMB2_auth_kerberos;
>>               break;
>> @@ -969,7 +998,7 @@ SMB2_select_sec(struct cifs_ses *ses, struct SMB2_sess_data *sess_data)
>>               sess_data->func = SMB2_sess_auth_rawntlmssp_negotiate;
>>               break;
>>       default:
>> -             cifs_dbg(VFS, "secType %d not supported!\n", ses->sectype);
>> +             cifs_dbg(VFS, "secType %d not supported!\n", type);
>>               return -EOPNOTSUPP;
>>       }
>>
>> diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
>> index f2d511a..2f0a5a2 100644
>> --- a/fs/cifs/smb2proto.h
>> +++ b/fs/cifs/smb2proto.h
>> @@ -175,4 +175,6 @@ extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
>>                           __u8 *lease_key, const __le32 lease_state);
>>  extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
>>
>> +extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
>> +                                     enum securityEnum);
>>  #endif                       /* _SMB2PROTO_H */
>
> Acked-by: Jeff Layton <jlayton@xxxxxxxxxx>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Acked-by: Pavel Shilovsky <pshilov@xxxxxxxxxxxxx>

-- 
Best regards,
Pavel Shilovsky
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux