diff options
Diffstat (limited to 'fs/smb/server/mgmt/user_session.c')
| -rw-r--r-- | fs/smb/server/mgmt/user_session.c | 28 | 
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 15f68ee05089..aec0a7a12405 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -156,7 +156,7 @@ void ksmbd_session_destroy(struct ksmbd_session *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; @@ -305,6 +305,32 @@ struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,  	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; + +	ksmbd_destroy_file_table(&prev_sess->file_table); +	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,  					   unsigned long long id)  {  |