|
|
|
|
@@ -67,8 +67,10 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
sess = ksmbd_session_lookup_all(conn, id);
|
|
|
|
|
if (sess)
|
|
|
|
|
if (sess) {
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
pr_err("Invalid user session id: %llu\n", id);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@@ -605,10 +607,8 @@ int smb2_check_user_session(struct ksmbd_work *work)
|
|
|
|
|
|
|
|
|
|
/* Check for validity of user session */
|
|
|
|
|
work->sess = ksmbd_session_lookup_all(conn, sess_id);
|
|
|
|
|
if (work->sess) {
|
|
|
|
|
ksmbd_user_session_get(work->sess);
|
|
|
|
|
if (work->sess)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id);
|
|
|
|
|
return -ENOENT;
|
|
|
|
|
}
|
|
|
|
|
@@ -1701,29 +1701,35 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|
|
|
|
|
|
|
|
|
if (conn->dialect != sess->dialect) {
|
|
|
|
|
rc = -EINVAL;
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
|
|
|
|
|
rc = -EINVAL;
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strncmp(conn->ClientGUID, sess->ClientGUID,
|
|
|
|
|
SMB2_CLIENT_GUID_SIZE)) {
|
|
|
|
|
rc = -ENOENT;
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sess->state == SMB2_SESSION_IN_PROGRESS) {
|
|
|
|
|
rc = -EACCES;
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sess->state == SMB2_SESSION_EXPIRED) {
|
|
|
|
|
rc = -EFAULT;
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
|
|
|
|
|
if (ksmbd_conn_need_reconnect(conn)) {
|
|
|
|
|
rc = -EFAULT;
|
|
|
|
|
@@ -1731,7 +1737,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ksmbd_session_lookup(conn, sess_id)) {
|
|
|
|
|
sess = ksmbd_session_lookup(conn, sess_id);
|
|
|
|
|
if (!sess) {
|
|
|
|
|
rc = -EACCES;
|
|
|
|
|
goto out_err;
|
|
|
|
|
}
|
|
|
|
|
@@ -1742,7 +1749,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn->binding = true;
|
|
|
|
|
ksmbd_user_session_get(sess);
|
|
|
|
|
} else if ((conn->dialect < SMB30_PROT_ID ||
|
|
|
|
|
server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
|
|
|
|
|
(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
|
|
|
|
|
@@ -1769,7 +1775,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn->binding = false;
|
|
|
|
|
ksmbd_user_session_get(sess);
|
|
|
|
|
}
|
|
|
|
|
work->sess = sess;
|
|
|
|
|
|
|
|
|
|
@@ -2197,9 +2202,9 @@ err_out:
|
|
|
|
|
int smb2_session_logoff(struct ksmbd_work *work)
|
|
|
|
|
{
|
|
|
|
|
struct ksmbd_conn *conn = work->conn;
|
|
|
|
|
struct ksmbd_session *sess = work->sess;
|
|
|
|
|
struct smb2_logoff_req *req;
|
|
|
|
|
struct smb2_logoff_rsp *rsp;
|
|
|
|
|
struct ksmbd_session *sess;
|
|
|
|
|
u64 sess_id;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
@@ -2221,11 +2226,6 @@ int smb2_session_logoff(struct ksmbd_work *work)
|
|
|
|
|
ksmbd_close_session_fds(work);
|
|
|
|
|
ksmbd_conn_wait_idle(conn);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Re-lookup session to validate if session is deleted
|
|
|
|
|
* while waiting request complete
|
|
|
|
|
*/
|
|
|
|
|
sess = ksmbd_session_lookup_all(conn, sess_id);
|
|
|
|
|
if (ksmbd_tree_conn_session_logoff(sess)) {
|
|
|
|
|
ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
|
|
|
|
|
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
|
|
|
|
|
@@ -4228,6 +4228,7 @@ static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,
|
|
|
|
|
/* dot and dotdot entries are already reserved */
|
|
|
|
|
if (!strcmp(".", name) || !strcmp("..", name))
|
|
|
|
|
return true;
|
|
|
|
|
d_info->num_scan++;
|
|
|
|
|
if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
|
|
|
|
|
return true;
|
|
|
|
|
if (!match_pattern(name, namlen, priv->search_pattern))
|
|
|
|
|
@@ -4390,8 +4391,17 @@ int smb2_query_dir(struct ksmbd_work *work)
|
|
|
|
|
query_dir_private.info_level = req->FileInformationClass;
|
|
|
|
|
dir_fp->readdir_data.private = &query_dir_private;
|
|
|
|
|
set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
|
|
|
|
|
|
|
|
|
|
again:
|
|
|
|
|
d_info.num_scan = 0;
|
|
|
|
|
rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
|
|
|
|
|
/*
|
|
|
|
|
* num_entry can be 0 if the directory iteration stops before reaching
|
|
|
|
|
* the end of the directory and no file is matched with the search
|
|
|
|
|
* pattern.
|
|
|
|
|
*/
|
|
|
|
|
if (rc >= 0 && !d_info.num_entry && d_info.num_scan &&
|
|
|
|
|
d_info.out_buf_len > 0)
|
|
|
|
|
goto again;
|
|
|
|
|
/*
|
|
|
|
|
* req->OutputBufferLength is too small to contain even one entry.
|
|
|
|
|
* In this case, it immediately returns OutputBufferLength 0 to client.
|
|
|
|
|
@@ -6016,15 +6026,13 @@ static int set_file_basic_info(struct ksmbd_file *fp,
|
|
|
|
|
attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrs.ia_valid |= ATTR_CTIME;
|
|
|
|
|
if (file_info->ChangeTime)
|
|
|
|
|
attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
|
|
|
|
|
else
|
|
|
|
|
attrs.ia_ctime = inode_get_ctime(inode);
|
|
|
|
|
inode_set_ctime_to_ts(inode,
|
|
|
|
|
ksmbd_NTtimeToUnix(file_info->ChangeTime));
|
|
|
|
|
|
|
|
|
|
if (file_info->LastWriteTime) {
|
|
|
|
|
attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
|
|
|
|
|
attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
|
|
|
|
|
attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (file_info->Attributes) {
|
|
|
|
|
@@ -6066,8 +6074,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,
|
|
|
|
|
return -EACCES;
|
|
|
|
|
|
|
|
|
|
inode_lock(inode);
|
|
|
|
|
inode_set_ctime_to_ts(inode, attrs.ia_ctime);
|
|
|
|
|
attrs.ia_valid &= ~ATTR_CTIME;
|
|
|
|
|
rc = notify_change(idmap, dentry, &attrs, NULL);
|
|
|
|
|
inode_unlock(inode);
|
|
|
|
|
}
|
|
|
|
|
@@ -8982,6 +8988,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
|
|
|
|
|
le64_to_cpu(tr_hdr->SessionId));
|
|
|
|
|
return -ECONNABORTED;
|
|
|
|
|
}
|
|
|
|
|
ksmbd_user_session_put(sess);
|
|
|
|
|
|
|
|
|
|
iov[0].iov_base = buf;
|
|
|
|
|
iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4;
|
|
|
|
|
|