diff options
author | Steve French <stfrench@microsoft.com> | 2023-05-22 04:46:30 +0300 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2023-05-25 00:29:21 +0300 |
commit | 38c8a9a52082579090e34c033d439ed2cd1a462d (patch) | |
tree | ca6c3bf5b2b912f32735c1aa0a045cd21a47a205 /fs/ksmbd/mgmt | |
parent | cb8b02fd6343228966324528adf920bfb8b8e681 (diff) | |
download | linux-38c8a9a52082579090e34c033d439ed2cd1a462d.tar.xz |
smb: move client and server files to common directory fs/smb
Move CIFS/SMB3 related client and server files (cifs.ko and ksmbd.ko
and helper modules) to new fs/smb subdirectory:
fs/cifs --> fs/smb/client
fs/ksmbd --> fs/smb/server
fs/smbfs_common --> fs/smb/common
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/ksmbd/mgmt')
-rw-r--r-- | fs/ksmbd/mgmt/ksmbd_ida.c | 46 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/ksmbd_ida.h | 34 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/share_config.c | 234 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/share_config.h | 82 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/tree_connect.c | 147 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/tree_connect.h | 61 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/user_config.c | 79 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/user_config.h | 68 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/user_session.c | 391 | ||||
-rw-r--r-- | fs/ksmbd/mgmt/user_session.h | 103 |
10 files changed, 0 insertions, 1245 deletions
diff --git a/fs/ksmbd/mgmt/ksmbd_ida.c b/fs/ksmbd/mgmt/ksmbd_ida.c deleted file mode 100644 index 54194d959a5e..000000000000 --- a/fs/ksmbd/mgmt/ksmbd_ida.c +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include "ksmbd_ida.h" - -static inline int __acquire_id(struct ida *ida, int from, int to) -{ - return ida_simple_get(ida, from, to, GFP_KERNEL); -} - -int ksmbd_acquire_smb2_tid(struct ida *ida) -{ - int id; - - id = __acquire_id(ida, 1, 0xFFFFFFFF); - - return id; -} - -int ksmbd_acquire_smb2_uid(struct ida *ida) -{ - int id; - - id = __acquire_id(ida, 1, 0); - if (id == 0xFFFE) - id = __acquire_id(ida, 1, 0); - - return id; -} - -int ksmbd_acquire_async_msg_id(struct ida *ida) -{ - return __acquire_id(ida, 1, 0); -} - -int ksmbd_acquire_id(struct ida *ida) -{ - return __acquire_id(ida, 0, 0); -} - -void ksmbd_release_id(struct ida *ida, int id) -{ - ida_simple_remove(ida, id); -} diff --git a/fs/ksmbd/mgmt/ksmbd_ida.h b/fs/ksmbd/mgmt/ksmbd_ida.h deleted file mode 100644 index 2bc07b16cfde..000000000000 --- a/fs/ksmbd/mgmt/ksmbd_ida.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __KSMBD_IDA_MANAGEMENT_H__ -#define __KSMBD_IDA_MANAGEMENT_H__ - -#include <linux/slab.h> -#include <linux/idr.h> - -/* - * 2.2.1.6.7 TID Generation - * The value 0xFFFF MUST NOT be used as a valid TID. All other - * possible values for TID, including zero (0x0000), are valid. - * The value 0xFFFF is used to specify all TIDs or no TID, - * depending upon the context in which it is used. - */ -int ksmbd_acquire_smb2_tid(struct ida *ida); - -/* - * 2.2.1.6.8 UID Generation - * The value 0xFFFE was declared reserved in the LAN Manager 1.0 - * documentation, so a value of 0xFFFE SHOULD NOT be used as a - * valid UID.<21> All other possible values for a UID, excluding - * zero (0x0000), are valid. - */ -int ksmbd_acquire_smb2_uid(struct ida *ida); -int ksmbd_acquire_async_msg_id(struct ida *ida); - -int ksmbd_acquire_id(struct ida *ida); - -void ksmbd_release_id(struct ida *ida, int id); -#endif /* __KSMBD_IDA_MANAGEMENT_H__ */ diff --git a/fs/ksmbd/mgmt/share_config.c b/fs/ksmbd/mgmt/share_config.c deleted file mode 100644 index 328a412259dc..000000000000 --- a/fs/ksmbd/mgmt/share_config.c +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include <linux/list.h> -#include <linux/jhash.h> -#include <linux/slab.h> -#include <linux/rwsem.h> -#include <linux/parser.h> -#include <linux/namei.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include "share_config.h" -#include "user_config.h" -#include "user_session.h" -#include "../transport_ipc.h" -#include "../misc.h" - -#define SHARE_HASH_BITS 3 -static DEFINE_HASHTABLE(shares_table, SHARE_HASH_BITS); -static DECLARE_RWSEM(shares_table_lock); - -struct ksmbd_veto_pattern { - char *pattern; - struct list_head list; -}; - -static unsigned int share_name_hash(const char *name) -{ - return jhash(name, strlen(name), 0); -} - -static void kill_share(struct ksmbd_share_config *share) -{ - while (!list_empty(&share->veto_list)) { - struct ksmbd_veto_pattern *p; - - p = list_entry(share->veto_list.next, - struct ksmbd_veto_pattern, - list); - list_del(&p->list); - kfree(p->pattern); - kfree(p); - } - - if (share->path) - path_put(&share->vfs_path); - kfree(share->name); - kfree(share->path); - kfree(share); -} - -void ksmbd_share_config_del(struct ksmbd_share_config *share) -{ - down_write(&shares_table_lock); - hash_del(&share->hlist); - up_write(&shares_table_lock); -} - -void __ksmbd_share_config_put(struct ksmbd_share_config *share) -{ - ksmbd_share_config_del(share); - kill_share(share); -} - -static struct ksmbd_share_config * -__get_share_config(struct ksmbd_share_config *share) -{ - if (!atomic_inc_not_zero(&share->refcount)) - return NULL; - return share; -} - -static struct ksmbd_share_config *__share_lookup(const char *name) -{ - struct ksmbd_share_config *share; - unsigned int key = share_name_hash(name); - - hash_for_each_possible(shares_table, share, hlist, key) { - if (!strcmp(name, share->name)) - return share; - } - return NULL; -} - -static int parse_veto_list(struct ksmbd_share_config *share, - char *veto_list, - int veto_list_sz) -{ - int sz = 0; - - if (!veto_list_sz) - return 0; - - while (veto_list_sz > 0) { - struct ksmbd_veto_pattern *p; - - sz = strlen(veto_list); - if (!sz) - break; - - p = kzalloc(sizeof(struct ksmbd_veto_pattern), GFP_KERNEL); - if (!p) - return -ENOMEM; - - p->pattern = kstrdup(veto_list, GFP_KERNEL); - if (!p->pattern) { - kfree(p); - return -ENOMEM; - } - - list_add(&p->list, &share->veto_list); - - veto_list += sz + 1; - veto_list_sz -= (sz + 1); - } - - return 0; -} - -static struct ksmbd_share_config *share_config_request(struct unicode_map *um, - const char *name) -{ - struct ksmbd_share_config_response *resp; - struct ksmbd_share_config *share = NULL; - struct ksmbd_share_config *lookup; - int ret; - - resp = ksmbd_ipc_share_config_request(name); - if (!resp) - return NULL; - - if (resp->flags == KSMBD_SHARE_FLAG_INVALID) - goto out; - - if (*resp->share_name) { - char *cf_resp_name; - bool equal; - - cf_resp_name = ksmbd_casefold_sharename(um, resp->share_name); - if (IS_ERR(cf_resp_name)) - goto out; - equal = !strcmp(cf_resp_name, name); - kfree(cf_resp_name); - if (!equal) - goto out; - } - - share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL); - if (!share) - goto out; - - share->flags = resp->flags; - atomic_set(&share->refcount, 1); - INIT_LIST_HEAD(&share->veto_list); - share->name = kstrdup(name, GFP_KERNEL); - - if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) { - share->path = kstrdup(ksmbd_share_config_path(resp), - GFP_KERNEL); - if (share->path) - share->path_sz = strlen(share->path); - share->create_mask = resp->create_mask; - share->directory_mask = resp->directory_mask; - share->force_create_mode = resp->force_create_mode; - share->force_directory_mode = resp->force_directory_mode; - share->force_uid = resp->force_uid; - share->force_gid = resp->force_gid; - ret = parse_veto_list(share, - KSMBD_SHARE_CONFIG_VETO_LIST(resp), - resp->veto_list_sz); - if (!ret && share->path) { - ret = kern_path(share->path, 0, &share->vfs_path); - if (ret) { - ksmbd_debug(SMB, "failed to access '%s'\n", - share->path); - /* Avoid put_path() */ - kfree(share->path); - share->path = NULL; - } - } - if (ret || !share->name) { - kill_share(share); - share = NULL; - goto out; - } - } - - down_write(&shares_table_lock); - lookup = __share_lookup(name); - if (lookup) - lookup = __get_share_config(lookup); - if (!lookup) { - hash_add(shares_table, &share->hlist, share_name_hash(name)); - } else { - kill_share(share); - share = lookup; - } - up_write(&shares_table_lock); - -out: - kvfree(resp); - return share; -} - -struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, - const char *name) -{ - struct ksmbd_share_config *share; - - down_read(&shares_table_lock); - share = __share_lookup(name); - if (share) - share = __get_share_config(share); - up_read(&shares_table_lock); - - if (share) - return share; - return share_config_request(um, name); -} - -bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, - const char *filename) -{ - struct ksmbd_veto_pattern *p; - - list_for_each_entry(p, &share->veto_list, list) { - if (match_wildcard(p->pattern, filename)) - return true; - } - return false; -} diff --git a/fs/ksmbd/mgmt/share_config.h b/fs/ksmbd/mgmt/share_config.h deleted file mode 100644 index 3fd338293942..000000000000 --- a/fs/ksmbd/mgmt/share_config.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __SHARE_CONFIG_MANAGEMENT_H__ -#define __SHARE_CONFIG_MANAGEMENT_H__ - -#include <linux/workqueue.h> -#include <linux/hashtable.h> -#include <linux/path.h> -#include <linux/unicode.h> - -struct ksmbd_share_config { - char *name; - char *path; - - unsigned int path_sz; - unsigned int flags; - struct list_head veto_list; - - struct path vfs_path; - - atomic_t refcount; - struct hlist_node hlist; - unsigned short create_mask; - unsigned short directory_mask; - unsigned short force_create_mode; - unsigned short force_directory_mode; - unsigned short force_uid; - unsigned short force_gid; -}; - -#define KSMBD_SHARE_INVALID_UID ((__u16)-1) -#define KSMBD_SHARE_INVALID_GID ((__u16)-1) - -static inline int share_config_create_mode(struct ksmbd_share_config *share, - umode_t posix_mode) -{ - if (!share->force_create_mode) { - if (!posix_mode) - return share->create_mask; - else - return posix_mode & share->create_mask; - } - return share->force_create_mode & share->create_mask; -} - -static inline int share_config_directory_mode(struct ksmbd_share_config *share, - umode_t posix_mode) -{ - if (!share->force_directory_mode) { - if (!posix_mode) - return share->directory_mask; - else - return posix_mode & share->directory_mask; - } - - return share->force_directory_mode & share->directory_mask; -} - -static inline int test_share_config_flag(struct ksmbd_share_config *share, - int flag) -{ - return share->flags & flag; -} - -void ksmbd_share_config_del(struct ksmbd_share_config *share); -void __ksmbd_share_config_put(struct ksmbd_share_config *share); - -static inline void ksmbd_share_config_put(struct ksmbd_share_config *share) -{ - if (!atomic_dec_and_test(&share->refcount)) - return; - __ksmbd_share_config_put(share); -} - -struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, - const char *name); -bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, - const char *filename); -#endif /* __SHARE_CONFIG_MANAGEMENT_H__ */ diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c deleted file mode 100644 index f07a05f37651..000000000000 --- a/fs/ksmbd/mgmt/tree_connect.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/xarray.h> - -#include "../transport_ipc.h" -#include "../connection.h" - -#include "tree_connect.h" -#include "user_config.h" -#include "share_config.h" -#include "user_session.h" - -struct ksmbd_tree_conn_status -ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, - const char *share_name) -{ - struct ksmbd_tree_conn_status status = {-ENOENT, NULL}; - struct ksmbd_tree_connect_response *resp = NULL; - struct ksmbd_share_config *sc; - struct ksmbd_tree_connect *tree_conn = NULL; - struct sockaddr *peer_addr; - int ret; - - sc = ksmbd_share_config_get(conn->um, share_name); - if (!sc) - return status; - - tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), GFP_KERNEL); - if (!tree_conn) { - status.ret = -ENOMEM; - goto out_error; - } - - tree_conn->id = ksmbd_acquire_tree_conn_id(sess); - if (tree_conn->id < 0) { - status.ret = -EINVAL; - goto out_error; - } - - peer_addr = KSMBD_TCP_PEER_SOCKADDR(conn); - resp = ksmbd_ipc_tree_connect_request(sess, - sc, - tree_conn, - peer_addr); - if (!resp) { - status.ret = -EINVAL; - goto out_error; - } - - status.ret = resp->status; - if (status.ret != KSMBD_TREE_CONN_STATUS_OK) - goto out_error; - - tree_conn->flags = resp->connection_flags; - if (test_tree_conn_flag(tree_conn, KSMBD_TREE_CONN_FLAG_UPDATE)) { - struct ksmbd_share_config *new_sc; - - ksmbd_share_config_del(sc); - new_sc = ksmbd_share_config_get(conn->um, share_name); - if (!new_sc) { - pr_err("Failed to update stale share config\n"); - status.ret = -ESTALE; - goto out_error; - } - ksmbd_share_config_put(sc); - sc = new_sc; - } - - tree_conn->user = sess->user; - tree_conn->share_conf = sc; - status.tree_conn = tree_conn; - - ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, - GFP_KERNEL)); - if (ret) { - status.ret = -ENOMEM; - goto out_error; - } - kvfree(resp); - return status; - -out_error: - if (tree_conn) - ksmbd_release_tree_conn_id(sess, tree_conn->id); - ksmbd_share_config_put(sc); - kfree(tree_conn); - kvfree(resp); - return status; -} - -int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, - struct ksmbd_tree_connect *tree_conn) -{ - int ret; - - ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); - ksmbd_release_tree_conn_id(sess, tree_conn->id); - xa_erase(&sess->tree_conns, tree_conn->id); - ksmbd_share_config_put(tree_conn->share_conf); - kfree(tree_conn); - return ret; -} - -struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess, - unsigned int id) -{ - struct ksmbd_tree_connect *tcon; - - tcon = xa_load(&sess->tree_conns, id); - if (tcon) { - if (test_bit(TREE_CONN_EXPIRE, &tcon->status)) - tcon = NULL; - } - - return tcon; -} - -struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess, - unsigned int id) -{ - struct ksmbd_tree_connect *tc; - - tc = ksmbd_tree_conn_lookup(sess, id); - if (tc) - return tc->share_conf; - return NULL; -} - -int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess) -{ - int ret = 0; - struct ksmbd_tree_connect *tc; - unsigned long id; - - if (!sess) - return -EINVAL; - - xa_for_each(&sess->tree_conns, id, tc) - ret |= ksmbd_tree_conn_disconnect(sess, tc); - xa_destroy(&sess->tree_conns); - return ret; -} diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h deleted file mode 100644 index 700df36cf3e3..000000000000 --- a/fs/ksmbd/mgmt/tree_connect.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __TREE_CONNECT_MANAGEMENT_H__ -#define __TREE_CONNECT_MANAGEMENT_H__ - -#include <linux/hashtable.h> - -#include "../ksmbd_netlink.h" - -struct ksmbd_share_config; -struct ksmbd_user; -struct ksmbd_conn; - -#define TREE_CONN_EXPIRE 1 - -struct ksmbd_tree_connect { - int id; - - unsigned int flags; - struct ksmbd_share_config *share_conf; - struct ksmbd_user *user; - - struct list_head list; - - int maximal_access; - bool posix_extensions; - unsigned long status; -}; - -struct ksmbd_tree_conn_status { - unsigned int ret; - struct ksmbd_tree_connect *tree_conn; -}; - -static inline int test_tree_conn_flag(struct ksmbd_tree_connect *tree_conn, - int flag) -{ - return tree_conn->flags & flag; -} - -struct ksmbd_session; - -struct ksmbd_tree_conn_status -ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, - const char *share_name); - -int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, - struct ksmbd_tree_connect *tree_conn); - -struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess, - unsigned int id); - -struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess, - unsigned int id); - -int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess); - -#endif /* __TREE_CONNECT_MANAGEMENT_H__ */ diff --git a/fs/ksmbd/mgmt/user_config.c b/fs/ksmbd/mgmt/user_config.c deleted file mode 100644 index 279d00feff21..000000000000 --- a/fs/ksmbd/mgmt/user_config.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include <linux/slab.h> -#include <linux/mm.h> - -#include "user_config.h" -#include "../transport_ipc.h" - -struct ksmbd_user *ksmbd_login_user(const char *account) -{ - struct ksmbd_login_response *resp; - struct ksmbd_user *user = NULL; - - resp = ksmbd_ipc_login_request(account); - if (!resp) - return NULL; - - if (!(resp->status & KSMBD_USER_FLAG_OK)) - goto out; - - user = ksmbd_alloc_user(resp); -out: - kvfree(resp); - return user; -} - -struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp) -{ - struct ksmbd_user *user = NULL; - - user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL); - if (!user) - return NULL; - - user->name = kstrdup(resp->account, GFP_KERNEL); - user->flags = resp->status; - user->gid = resp->gid; - user->uid = resp->uid; - user->passkey_sz = resp->hash_sz; - user->passkey = kmalloc(resp->hash_sz, GFP_KERNEL); - if (user->passkey) - memcpy(user->passkey, resp->hash, resp->hash_sz); - - if (!user->name || !user->passkey) { - kfree(user->name); - kfree(user->passkey); - kfree(user); - user = NULL; - } - return user; -} - -void ksmbd_free_user(struct ksmbd_user *user) -{ - ksmbd_ipc_logout_request(user->name, user->flags); - kfree(user->name); - kfree(user->passkey); - kfree(user); -} - -int ksmbd_anonymous_user(struct ksmbd_user *user) -{ - if (user->name[0] == '\0') - return 1; - return 0; -} - -bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2) -{ - if (strcmp(u1->name, u2->name)) - return false; - if (memcmp(u1->passkey, u2->passkey, u1->passkey_sz)) - return false; - - return true; -} diff --git a/fs/ksmbd/mgmt/user_config.h b/fs/ksmbd/mgmt/user_config.h deleted file mode 100644 index 6a44109617f1..000000000000 --- a/fs/ksmbd/mgmt/user_config.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __USER_CONFIG_MANAGEMENT_H__ -#define __USER_CONFIG_MANAGEMENT_H__ - -#include "../glob.h" - -struct ksmbd_user { - unsigned short flags; - - unsigned int uid; - unsigned int gid; - - char *name; - - size_t passkey_sz; - char *passkey; - unsigned int failed_login_count; -}; - -static inline bool user_guest(struct ksmbd_user *user) -{ - return user->flags & KSMBD_USER_FLAG_GUEST_ACCOUNT; -} - -static inline void set_user_flag(struct ksmbd_user *user, int flag) -{ - user->flags |= flag; -} - -static inline int test_user_flag(struct ksmbd_user *user, int flag) -{ - return user->flags & flag; -} - -static inline void set_user_guest(struct ksmbd_user *user) -{ -} - -static inline char *user_passkey(struct ksmbd_user *user) -{ - return user->passkey; -} - -static inline char *user_name(struct ksmbd_user *user) -{ - return user->name; -} - -static inline unsigned int user_uid(struct ksmbd_user *user) -{ - return user->uid; -} - -static inline unsigned int user_gid(struct ksmbd_user *user) -{ - return user->gid; -} - -struct ksmbd_user *ksmbd_login_user(const char *account); -struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp); -void ksmbd_free_user(struct ksmbd_user *user); -int ksmbd_anonymous_user(struct ksmbd_user *user); -bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2); -#endif /* __USER_CONFIG_MANAGEMENT_H__ */ diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c deleted file mode 100644 index 8a5dcab05614..000000000000 --- a/fs/ksmbd/mgmt/user_session.c +++ /dev/null @@ -1,391 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/rwsem.h> -#include <linux/xarray.h> - -#include "ksmbd_ida.h" -#include "user_session.h" -#include "user_config.h" -#include "tree_connect.h" -#include "../transport_ipc.h" -#include "../connection.h" -#include "../vfs_cache.h" - -static DEFINE_IDA(session_ida); - -#define SESSION_HASH_BITS 3 -static DEFINE_HASHTABLE(sessions_table, SESSION_HASH_BITS); -static DECLARE_RWSEM(sessions_table_lock); - -struct ksmbd_session_rpc { - int id; - unsigned int method; -}; - -static void free_channel_list(struct ksmbd_session *sess) -{ - struct channel *chann; - unsigned long index; - - xa_for_each(&sess->ksmbd_chann_list, index, chann) { - xa_erase(&sess->ksmbd_chann_list, index); - kfree(chann); - } - - xa_destroy(&sess->ksmbd_chann_list); -} - -static void __session_rpc_close(struct ksmbd_session *sess, - struct ksmbd_session_rpc *entry) -{ - struct ksmbd_rpc_command *resp; - - resp = ksmbd_rpc_close(sess, entry->id); - if (!resp) - pr_err("Unable to close RPC pipe %d\n", entry->id); - - kvfree(resp); - ksmbd_rpc_id_free(entry->id); - kfree(entry); -} - -static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess) -{ - struct ksmbd_session_rpc *entry; - long index; - - xa_for_each(&sess->rpc_handle_list, index, entry) { - xa_erase(&sess->rpc_handle_list, index); - __session_rpc_close(sess, entry); - } - - xa_destroy(&sess->rpc_handle_list); -} - -static int __rpc_method(char *rpc_name) -{ - if (!strcmp(rpc_name, "\\srvsvc") || !strcmp(rpc_name, "srvsvc")) - return KSMBD_RPC_SRVSVC_METHOD_INVOKE; - - if (!strcmp(rpc_name, "\\wkssvc") || !strcmp(rpc_name, "wkssvc")) - return KSMBD_RPC_WKSSVC_METHOD_INVOKE; - - if (!strcmp(rpc_name, "LANMAN") || !strcmp(rpc_name, "lanman")) - return KSMBD_RPC_RAP_METHOD; - - if (!strcmp(rpc_name, "\\samr") || !strcmp(rpc_name, "samr")) - return KSMBD_RPC_SAMR_METHOD_INVOKE; - - if (!strcmp(rpc_name, "\\lsarpc") || !strcmp(rpc_name, "lsarpc")) - return KSMBD_RPC_LSARPC_METHOD_INVOKE; - - pr_err("Unsupported RPC: %s\n", rpc_name); - return 0; -} - -int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) -{ - struct ksmbd_session_rpc *entry; - struct ksmbd_rpc_command *resp; - int method; - - method = __rpc_method(rpc_name); - if (!method) - return -EINVAL; - - entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - entry->method = method; - entry->id = ksmbd_ipc_id_alloc(); - if (entry->id < 0) - goto free_entry; - xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL); - - resp = ksmbd_rpc_open(sess, entry->id); - if (!resp) - goto free_id; - - kvfree(resp); - return entry->id; -free_id: - xa_erase(&sess->rpc_handle_list, entry->id); - ksmbd_rpc_id_free(entry->id); -free_entry: - kfree(entry); - return -EINVAL; -} - -void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) -{ - struct ksmbd_session_rpc *entry; - - entry = xa_erase(&sess->rpc_handle_list, id); - if (entry) - __session_rpc_close(sess, entry); -} - -int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) -{ - struct ksmbd_session_rpc *entry; - - entry = xa_load(&sess->rpc_handle_list, id); - return entry ? entry->method : 0; -} - -void ksmbd_session_destroy(struct ksmbd_session *sess) -{ - if (!sess) - return; - - if (sess->user) - ksmbd_free_user(sess->user); - - ksmbd_tree_conn_session_logoff(sess); - ksmbd_destroy_file_table(&sess->file_table); - ksmbd_session_rpc_clear_list(sess); - free_channel_list(sess); - kfree(sess->Preauth_HashValue); - ksmbd_release_id(&session_ida, sess->id); - kfree(sess); -} - -static struct ksmbd_session *__session_lookup(unsigned long long id) -{ - struct ksmbd_session *sess; - - hash_for_each_possible(sessions_table, sess, hlist, id) { - if (id == sess->id) { - sess->last_active = jiffies; - return sess; - } - } - return NULL; -} - -static void ksmbd_expire_session(struct ksmbd_conn *conn) -{ - unsigned long id; - struct ksmbd_session *sess; - - down_write(&sessions_table_lock); - xa_for_each(&conn->sessions, id, sess) { - if (sess->state != SMB2_SESSION_VALID || - time_after(jiffies, - sess->last_active + SMB2_SESSION_TIMEOUT)) { - xa_erase(&conn->sessions, sess->id); - hash_del(&sess->hlist); - ksmbd_session_destroy(sess); - continue; - } - } - up_write(&sessions_table_lock); -} - -int ksmbd_session_register(struct ksmbd_conn *conn, - struct ksmbd_session *sess) -{ - sess->dialect = conn->dialect; - memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE); - ksmbd_expire_session(conn); - return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL)); -} - -static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess) -{ - struct channel *chann; - - chann = xa_erase(&sess->ksmbd_chann_list, (long)conn); - if (!chann) - return -ENOENT; - - kfree(chann); - return 0; -} - -void ksmbd_sessions_deregister(struct ksmbd_conn *conn) -{ - struct ksmbd_session *sess; - unsigned long id; - - down_write(&sessions_table_lock); - if (conn->binding) { - int bkt; - struct hlist_node *tmp; - - hash_for_each_safe(sessions_table, bkt, tmp, sess, hlist) { - if (!ksmbd_chann_del(conn, sess) && - xa_empty(&sess->ksmbd_chann_list)) { - hash_del(&sess->hlist); - ksmbd_session_destroy(sess); - } - } - } - - xa_for_each(&conn->sessions, id, sess) { - unsigned long chann_id; - struct channel *chann; - - xa_for_each(&sess->ksmbd_chann_list, chann_id, chann) { - if (chann->conn != conn) - ksmbd_conn_set_exiting(chann->conn); - } - - ksmbd_chann_del(conn, sess); - if (xa_empty(&sess->ksmbd_chann_list)) { - xa_erase(&conn->sessions, sess->id); - hash_del(&sess->hlist); - ksmbd_session_destroy(sess); - } - } - up_write(&sessions_table_lock); -} - -struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, - unsigned long long id) -{ - struct ksmbd_session *sess; - - sess = xa_load(&conn->sessions, id); - if (sess) - sess->last_active = jiffies; - return sess; -} - -struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id) -{ - struct ksmbd_session *sess; - - down_read(&sessions_table_lock); - sess = __session_lookup(id); - if (sess) - sess->last_active = jiffies; - up_read(&sessions_table_lock); - - return sess; -} - -struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, - unsigned long long id) -{ - struct ksmbd_session *sess; - - sess = ksmbd_session_lookup(conn, id); - if (!sess && conn->binding) - sess = ksmbd_session_lookup_slowpath(id); - if (sess && sess->state != SMB2_SESSION_VALID) - sess = NULL; - return sess; -} - -struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, - u64 sess_id) -{ - struct preauth_session *sess; - - sess = kmalloc(sizeof(struct preauth_session), GFP_KERNEL); - if (!sess) - return NULL; - - sess->id = sess_id; - memcpy(sess->Preauth_HashValue, conn->preauth_info->Preauth_HashValue, - PREAUTH_HASHVALUE_SIZE); - list_add(&sess->preauth_entry, &conn->preauth_sess_table); - - return sess; -} - -static bool ksmbd_preauth_session_id_match(struct preauth_session *sess, - unsigned long long id) -{ - return sess->id == id; -} - -struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn, - unsigned long long id) -{ - struct preauth_session *sess = NULL; - - list_for_each_entry(sess, &conn->preauth_sess_table, preauth_entry) { - if (ksmbd_preauth_session_id_match(sess, id)) - return sess; - } - return NULL; -} - -static int __init_smb2_session(struct ksmbd_session *sess) -{ - int id = ksmbd_acquire_smb2_uid(&session_ida); - - if (id < 0) - return -EINVAL; - sess->id = id; - return 0; -} - -static struct ksmbd_session *__session_create(int protocol) -{ - struct ksmbd_session *sess; - int ret; - - if (protocol != CIFDS_SESSION_FLAG_SMB2) - return NULL; - - sess = kzalloc(sizeof(struct ksmbd_session), GFP_KERNEL); - if (!sess) - return NULL; - - if (ksmbd_init_file_table(&sess->file_table)) - goto error; - - sess->last_active = jiffies; - sess->state = SMB2_SESSION_IN_PROGRESS; - set_session_flag(sess, protocol); - xa_init(&sess->tree_conns); - xa_init(&sess->ksmbd_chann_list); - xa_init(&sess->rpc_handle_list); - sess->sequence_number = 1; - - ret = __init_smb2_session(sess); - if (ret) - goto error; - - ida_init(&sess->tree_conn_ida); - - down_write(&sessions_table_lock); - hash_add(sessions_table, &sess->hlist, sess->id); - up_write(&sessions_table_lock); - - return sess; - -error: - ksmbd_session_destroy(sess); - return NULL; -} - -struct ksmbd_session *ksmbd_smb2_session_create(void) -{ - return __session_create(CIFDS_SESSION_FLAG_SMB2); -} - -int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess) -{ - int id = -EINVAL; - - if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2)) - id = ksmbd_acquire_smb2_tid(&sess->tree_conn_ida); - - return id; -} - -void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id) -{ - if (id >= 0) - ksmbd_release_id(&sess->tree_conn_ida, id); -} diff --git a/fs/ksmbd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h deleted file mode 100644 index f99d475b28db..000000000000 --- a/fs/ksmbd/mgmt/user_session.h +++ /dev/null @@ -1,103 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __USER_SESSION_MANAGEMENT_H__ -#define __USER_SESSION_MANAGEMENT_H__ - -#include <linux/hashtable.h> -#include <linux/xarray.h> - -#include "../smb_common.h" -#include "../ntlmssp.h" - -#define CIFDS_SESSION_FLAG_SMB2 BIT(1) - -#define PREAUTH_HASHVALUE_SIZE 64 - -struct ksmbd_file_table; - -struct channel { - __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; - struct ksmbd_conn *conn; -}; - -struct preauth_session { - __u8 Preauth_HashValue[PREAUTH_HASHVALUE_SIZE]; - u64 id; - struct list_head preauth_entry; -}; - -struct ksmbd_session { - u64 id; - - __u16 dialect; - char ClientGUID[SMB2_CLIENT_GUID_SIZE]; - - struct ksmbd_user *user; - unsigned int sequence_number; - unsigned int flags; - - bool sign; - bool enc; - bool is_anonymous; - - int state; - __u8 *Preauth_HashValue; - - char sess_key[CIFS_KEY_SIZE]; - - struct hlist_node hlist; - struct xarray ksmbd_chann_list; - struct xarray tree_conns; - struct ida tree_conn_ida; - struct xarray rpc_handle_list; - - __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; - __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; - __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; - - struct ksmbd_file_table file_table; - unsigned long last_active; -}; - -static inline int test_session_flag(struct ksmbd_session *sess, int bit) -{ - return sess->flags & bit; -} - -static inline void set_session_flag(struct ksmbd_session *sess, int bit) -{ - sess->flags |= bit; -} - -static inline void clear_session_flag(struct ksmbd_session *sess, int bit) -{ - sess->flags &= ~bit; -} - -struct ksmbd_session *ksmbd_smb2_session_create(void); - -void ksmbd_session_destroy(struct ksmbd_session *sess); - -struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id); -struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, - unsigned long long id); -int ksmbd_session_register(struct ksmbd_conn *conn, - struct ksmbd_session *sess); -void ksmbd_sessions_deregister(struct ksmbd_conn *conn); -struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, - unsigned long long id); -struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, - u64 sess_id); -struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn, - unsigned long long id); - -int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess); -void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id); - -int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name); -void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id); -int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id); -#endif /* __USER_SESSION_MANAGEMENT_H__ */ |