mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 06:57:30 -04:00
ksmbd: handle channel binding with a different user
When an authenticated user tries to bind a channel to a session owned by a different user, ksmbd returns STATUS_LOGON_FAILURE. Windows instead rejects this attempt with STATUS_ACCESS_DENIED. The supplied credentials are valid but cannot be used with the existing session. Use a distinct internal error for a user mismatch in both NTLM and Kerberos authentication and map it to STATUS_ACCESS_DENIED during SESSION_SETUP. Keep ordinary authentication failures mapped to STATUS_LOGON_FAILURE. A failed SMB 3.1.1 binding also leaves its preauthentication context on the connection. A subsequent binding attempt for the same session reuses the stale hash and derives an incorrect channel signing key. Remove the binding preauthentication context on failure so a valid retry starts with a fresh hash. This fixes smb2.session.bind_different_user. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
committed by
Steve French
parent
faf8578c77
commit
1c5daa2ea9
@@ -451,7 +451,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
|
||||
} else {
|
||||
if (!ksmbd_compare_user(sess->user, user)) {
|
||||
ksmbd_debug(AUTH, "different user tried to reuse session\n");
|
||||
retval = -EPERM;
|
||||
retval = -EKEYREJECTED;
|
||||
ksmbd_free_user(user);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1734,7 +1734,7 @@ static int ntlm_authenticate(struct ksmbd_work *work,
|
||||
|
||||
if (!ksmbd_compare_user(sess->user, user)) {
|
||||
ksmbd_free_user(user);
|
||||
return -EPERM;
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
ksmbd_free_user(user);
|
||||
} else {
|
||||
@@ -1845,7 +1845,8 @@ static int krb5_authenticate(struct ksmbd_work *work,
|
||||
out_blob, &out_len, auth_key);
|
||||
if (retval) {
|
||||
ksmbd_debug(SMB, "krb5 authentication failed\n");
|
||||
retval = -EINVAL;
|
||||
if (retval != -EKEYREJECTED)
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2139,6 +2140,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
else if (rc == -EOPNOTSUPP)
|
||||
rsp->hdr.Status = STATUS_NOT_SUPPORTED;
|
||||
else if (rc == -EKEYREJECTED)
|
||||
rsp->hdr.Status = STATUS_ACCESS_DENIED;
|
||||
else if (rc)
|
||||
rsp->hdr.Status = STATUS_LOGON_FAILURE;
|
||||
|
||||
@@ -2148,6 +2151,16 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
if (sess && (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
|
||||
struct preauth_session *preauth_sess;
|
||||
|
||||
preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
|
||||
if (preauth_sess) {
|
||||
list_del(&preauth_sess->preauth_entry);
|
||||
kfree(preauth_sess);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SecurityBufferOffset should be set to zero
|
||||
* in session setup error response.
|
||||
|
||||
Reference in New Issue
Block a user