mirror of https://gitee.com/openkylin/linux.git
cifs: match secType when searching for existing tcp session
The secType is a per-tcp session entity, but the current routine doesn't verify that it is acceptible when attempting to match an existing TCP session. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
4515148ef7
commit
daf5b0b6f3
|
@ -83,8 +83,7 @@ enum statusEnum {
|
|||
};
|
||||
|
||||
enum securityEnum {
|
||||
PLAINTXT = 0, /* Legacy with Plaintext passwords */
|
||||
LANMAN, /* Legacy LANMAN auth */
|
||||
LANMAN = 0, /* Legacy LANMAN auth */
|
||||
NTLM, /* Legacy NTLM012 auth with NTLM hash */
|
||||
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
|
||||
RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
|
||||
|
|
|
@ -1412,8 +1412,56 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
|
||||
{
|
||||
unsigned int secFlags;
|
||||
|
||||
if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
|
||||
secFlags = vol->secFlg;
|
||||
else
|
||||
secFlags = global_secflags | vol->secFlg;
|
||||
|
||||
switch (server->secType) {
|
||||
case LANMAN:
|
||||
if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
|
||||
return false;
|
||||
break;
|
||||
case NTLMv2:
|
||||
if (!(secFlags & CIFSSEC_MAY_NTLMV2))
|
||||
return false;
|
||||
break;
|
||||
case NTLM:
|
||||
if (!(secFlags & CIFSSEC_MAY_NTLM))
|
||||
return false;
|
||||
break;
|
||||
case Kerberos:
|
||||
if (!(secFlags & CIFSSEC_MAY_KRB5))
|
||||
return false;
|
||||
break;
|
||||
case RawNTLMSSP:
|
||||
if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* now check if signing mode is acceptible */
|
||||
if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
|
||||
(server->secMode & SECMODE_SIGN_REQUIRED))
|
||||
return false;
|
||||
else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
|
||||
(server->secMode &
|
||||
(SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct TCP_Server_Info *
|
||||
cifs_find_tcp_session(struct sockaddr *addr)
|
||||
cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
|
||||
{
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
|
@ -1431,6 +1479,9 @@ cifs_find_tcp_session(struct sockaddr *addr)
|
|||
if (!match_address(server, addr))
|
||||
continue;
|
||||
|
||||
if (!match_security(server, vol))
|
||||
continue;
|
||||
|
||||
++server->srv_count;
|
||||
write_unlock(&cifs_tcp_ses_lock);
|
||||
cFYI(1, "Existing tcp session with server found");
|
||||
|
@ -1501,7 +1552,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
|
|||
}
|
||||
|
||||
/* see if we already have a matching tcp_ses */
|
||||
tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr);
|
||||
tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
|
||||
if (tcp_ses)
|
||||
return tcp_ses;
|
||||
|
||||
|
|
Loading…
Reference in New Issue