forked from luck/tmp_suning_uos_patched
CIFS: Allow to switch on encryption with seal mount option
This allows users to inforce encryption for SMB3 shares if a server supports it. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
This commit is contained in:
parent
c42a6abe30
commit
ae6f8dd4d0
@ -2630,12 +2630,18 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
static int match_tcon(struct cifs_tcon *tcon, const char *unc)
|
||||
static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
|
||||
{
|
||||
if (tcon->tidStatus == CifsExiting)
|
||||
return 0;
|
||||
if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
|
||||
if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE))
|
||||
return 0;
|
||||
if (tcon->seal != volume_info->seal)
|
||||
return 0;
|
||||
#ifdef CONFIG_CIFS_SMB2
|
||||
if (tcon->snapshot_time != volume_info->snapshot_time)
|
||||
return 0;
|
||||
#endif /* CONFIG_CIFS_SMB2 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2648,14 +2654,8 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each(tmp, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
|
||||
if (!match_tcon(tcon, volume_info->UNC))
|
||||
if (!match_tcon(tcon, volume_info))
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB2
|
||||
if (tcon->snapshot_time != volume_info->snapshot_time)
|
||||
continue;
|
||||
#endif /* CONFIG_CIFS_SMB2 */
|
||||
|
||||
++tcon->tc_count;
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return tcon;
|
||||
@ -2701,8 +2701,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
||||
cifs_dbg(FYI, "Found match on UNC path\n");
|
||||
/* existing tcon already has a reference */
|
||||
cifs_put_smb_ses(ses);
|
||||
if (tcon->seal != volume_info->seal)
|
||||
cifs_dbg(VFS, "transport encryption setting conflicts with existing tid\n");
|
||||
return tcon;
|
||||
}
|
||||
|
||||
@ -2758,7 +2756,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
||||
tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
|
||||
cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
|
||||
}
|
||||
tcon->seal = volume_info->seal;
|
||||
tcon->use_persistent = false;
|
||||
/* check if SMB2 or later, CIFS does not support persistent handles */
|
||||
if (volume_info->persistent) {
|
||||
@ -2795,6 +2792,24 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
||||
tcon->use_resilient = true;
|
||||
}
|
||||
|
||||
if (volume_info->seal) {
|
||||
if (ses->server->vals->protocol_id == 0) {
|
||||
cifs_dbg(VFS,
|
||||
"SMB3 or later required for encryption\n");
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out_fail;
|
||||
#ifdef CONFIG_CIFS_SMB2
|
||||
} else if (tcon->ses->server->capabilities &
|
||||
SMB2_GLOBAL_CAP_ENCRYPTION)
|
||||
tcon->seal = true;
|
||||
else {
|
||||
cifs_dbg(VFS, "Encryption is not supported on share\n");
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out_fail;
|
||||
#endif /* CONFIG_CIFS_SMB2 */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We can have only one retry value for a connection to a share so for
|
||||
* 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)
|
||||
|
||||
if (!match_server(tcp_srv, volume_info) ||
|
||||
!match_session(ses, volume_info) ||
|
||||
!match_tcon(tcon, volume_info->UNC) ||
|
||||
!match_tcon(tcon, volume_info) ||
|
||||
!match_prepath(sb, mnt_data)) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
|
@ -79,9 +79,14 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
|
||||
|
||||
static int encryption_required(const struct cifs_tcon *tcon)
|
||||
{
|
||||
if (!tcon)
|
||||
return 0;
|
||||
if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
|
||||
(tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
|
||||
return 1;
|
||||
if (tcon->seal &&
|
||||
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -835,8 +840,6 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
|
||||
ses->Suid = rsp->hdr.sync_hdr.SessionId;
|
||||
|
||||
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
|
||||
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
|
||||
cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
|
||||
|
||||
rc = SMB2_sess_establish_session(sess_data);
|
||||
out_put_spnego_key:
|
||||
@ -933,8 +936,6 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
|
||||
|
||||
ses->Suid = rsp->hdr.sync_hdr.SessionId;
|
||||
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
|
||||
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
|
||||
cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
|
||||
|
||||
out:
|
||||
kfree(ntlmssp_blob);
|
||||
@ -993,8 +994,6 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
|
||||
|
||||
ses->Suid = rsp->hdr.sync_hdr.SessionId;
|
||||
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
|
||||
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
|
||||
cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
|
||||
|
||||
rc = SMB2_sess_establish_session(sess_data);
|
||||
out:
|
||||
@ -1145,12 +1144,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
||||
if (tcon && tcon->bad_network_name)
|
||||
return -ENOENT;
|
||||
|
||||
if ((tcon && tcon->seal) &&
|
||||
((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
|
||||
cifs_dbg(VFS, "encryption requested but no server support");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
|
||||
if (unc_path == NULL)
|
||||
return -ENOMEM;
|
||||
@ -1168,15 +1161,16 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
|
||||
flags |= CIFS_TRANSFORM_REQ;
|
||||
|
||||
if (tcon == NULL) {
|
||||
if ((ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA))
|
||||
flags |= CIFS_TRANSFORM_REQ;
|
||||
|
||||
/* since no tcon, smb2_init can not do this, so do here */
|
||||
req->hdr.sync_hdr.SessionId = ses->Suid;
|
||||
/* if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
|
||||
req->hdr.Flags |= SMB2_FLAGS_SIGNED; */
|
||||
}
|
||||
} else if (encryption_required(tcon))
|
||||
flags |= CIFS_TRANSFORM_REQ;
|
||||
|
||||
iov[0].iov_base = (char *)req;
|
||||
/* 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,
|
||||
if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
|
||||
((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
|
||||
cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
|
||||
|
||||
if (tcon->seal &&
|
||||
!(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
||||
cifs_dbg(VFS, "Encryption is requested but not supported\n");
|
||||
|
||||
init_copy_chunk_defaults(tcon);
|
||||
if (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)
|
||||
cifs_dbg(VFS, "Encrypted shares not supported");
|
||||
if (tcon->ses->server->ops->validate_negotiate)
|
||||
rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
|
||||
tcon_exit:
|
||||
|
Loading…
Reference in New Issue
Block a user