mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-08 09:18:29 +00:00
ksmbd: mark SMB2_SESSION_EXPIRED to session when destroying previous session
Currently ksmbd exit connection as well destroying previous session. When testing durable handle feaure, I found that destroy_previous_session() should destroy only session, i.e. the connection should be still alive. This patch mark SMB2_SESSION_EXPIRED on the previous session to be destroyed later and not used anymore. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
34cd86b663
commit
fa9415d402
@ -156,7 +156,7 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
|
|||||||
kfree(sess);
|
kfree(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ksmbd_session *__session_lookup(unsigned long long id)
|
struct ksmbd_session *__session_lookup(unsigned long long id)
|
||||||
{
|
{
|
||||||
struct ksmbd_session *sess;
|
struct ksmbd_session *sess;
|
||||||
|
|
||||||
@ -305,6 +305,31 @@ struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
|
|||||||
return sess;
|
return sess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroy_previous_session(struct ksmbd_conn *conn,
|
||||||
|
struct ksmbd_user *user, u64 id)
|
||||||
|
{
|
||||||
|
struct ksmbd_session *prev_sess;
|
||||||
|
struct ksmbd_user *prev_user;
|
||||||
|
|
||||||
|
down_write(&sessions_table_lock);
|
||||||
|
down_write(&conn->session_lock);
|
||||||
|
prev_sess = __session_lookup(id);
|
||||||
|
if (!prev_sess || prev_sess->state == SMB2_SESSION_EXPIRED)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
prev_user = prev_sess->user;
|
||||||
|
if (!prev_user ||
|
||||||
|
strcmp(user->name, prev_user->name) ||
|
||||||
|
user->passkey_sz != prev_user->passkey_sz ||
|
||||||
|
memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
prev_sess->state = SMB2_SESSION_EXPIRED;
|
||||||
|
out:
|
||||||
|
up_write(&conn->session_lock);
|
||||||
|
up_write(&sessions_table_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static bool ksmbd_preauth_session_id_match(struct preauth_session *sess,
|
static bool ksmbd_preauth_session_id_match(struct preauth_session *sess,
|
||||||
unsigned long long id)
|
unsigned long long id)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -88,8 +88,11 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
|
|||||||
int ksmbd_session_register(struct ksmbd_conn *conn,
|
int ksmbd_session_register(struct ksmbd_conn *conn,
|
||||||
struct ksmbd_session *sess);
|
struct ksmbd_session *sess);
|
||||||
void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
|
void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
|
||||||
|
struct ksmbd_session *__session_lookup(unsigned long long id);
|
||||||
struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
|
struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
|
||||||
unsigned long long id);
|
unsigned long long id);
|
||||||
|
void destroy_previous_session(struct ksmbd_conn *conn,
|
||||||
|
struct ksmbd_user *user, u64 id);
|
||||||
struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
|
struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
|
||||||
u64 sess_id);
|
u64 sess_id);
|
||||||
struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn,
|
struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn,
|
||||||
|
|||||||
@ -607,30 +607,6 @@ int smb2_check_user_session(struct ksmbd_work *work)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_previous_session(struct ksmbd_conn *conn,
|
|
||||||
struct ksmbd_user *user, u64 id)
|
|
||||||
{
|
|
||||||
struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
|
|
||||||
struct ksmbd_user *prev_user;
|
|
||||||
struct channel *chann;
|
|
||||||
long index;
|
|
||||||
|
|
||||||
if (!prev_sess)
|
|
||||||
return;
|
|
||||||
|
|
||||||
prev_user = prev_sess->user;
|
|
||||||
|
|
||||||
if (!prev_user ||
|
|
||||||
strcmp(user->name, prev_user->name) ||
|
|
||||||
user->passkey_sz != prev_user->passkey_sz ||
|
|
||||||
memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
|
|
||||||
return;
|
|
||||||
|
|
||||||
prev_sess->state = SMB2_SESSION_EXPIRED;
|
|
||||||
xa_for_each(&prev_sess->ksmbd_chann_list, index, chann)
|
|
||||||
ksmbd_conn_set_exiting(chann->conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smb2_get_name() - get filename string from on the wire smb format
|
* smb2_get_name() - get filename string from on the wire smb format
|
||||||
* @src: source buffer
|
* @src: source buffer
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user