diff --git a/fs/ksmbd/ksmbd_server.h b/fs/ksmbd/ksmbd_netlink.h similarity index 55% rename from fs/ksmbd/ksmbd_server.h rename to fs/ksmbd/ksmbd_netlink.h index 55b7602b79bd..2fbe2bc1e093 100644 --- a/fs/ksmbd/ksmbd_server.h +++ b/fs/ksmbd/ksmbd_netlink.h @@ -10,6 +10,49 @@ #include +/* + * This is a userspace ABI to communicate data between ksmbd and user IPC + * daemon using netlink. This is added to track and cache user account DB + * and share configuration info from userspace. + * + * - KSMBD_EVENT_HEARTBEAT_REQUEST(ksmbd_heartbeat) + * This event is to check whether user IPC daemon is alive. If user IPC + * daemon is dead, ksmbd keep existing connection till disconnecting and + * new connection will be denied. + * + * - KSMBD_EVENT_STARTING_UP(ksmbd_startup_request) + * This event is to receive the information that initializes the ksmbd + * server from the user IPC daemon and to start the server. The global + * section parameters are given from smb.conf as initialization + * information. + * + * - KSMBD_EVENT_SHUTTING_DOWN(ksmbd_shutdown_request) + * This event is to shutdown ksmbd server. + * + * - KSMBD_EVENT_LOGIN_REQUEST/RESPONSE(ksmbd_login_request/response) + * This event is to get user account info to user IPC daemon. + * + * - KSMBD_EVENT_SHARE_CONFIG_REQUEST/RESPONSE(ksmbd_share_config_request/response) + * This event is to get net share configuration info. + * + * - KSMBD_EVENT_TREE_CONNECT_REQUEST/RESPONSE(ksmbd_tree_connect_request/response) + * This event is to get session and tree connect info. + * + * - KSMBD_EVENT_TREE_DISCONNECT_REQUEST(ksmbd_tree_disconnect_request) + * This event is to send tree disconnect info to user IPC daemon. + * + * - KSMBD_EVENT_LOGOUT_REQUEST(ksmbd_logout_request) + * This event is to send logout request to user IPC daemon. + * + * - KSMBD_EVENT_RPC_REQUEST/RESPONSE(ksmbd_rpc_command) + * This event is to make DCE/RPC request like srvsvc, wkssvc, lsarpc, + * samr to be processed in userspace. + * + * - KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST/RESPONSE(ksmbd_spnego_authen_request/response) + * This event is to make kerberos authentication to be processed in + * userspace. + */ + #define KSMBD_GENL_NAME "SMBD_GENL" #define KSMBD_GENL_VERSION 0x01 @@ -17,6 +60,9 @@ #define KSMBD_REQ_MAX_HASH_SZ 18 #define KSMBD_REQ_MAX_SHARE_NAME 64 +/* + * IPC heartbeat frame to check whether user IPC daemon is alive. + */ struct ksmbd_heartbeat { __u32 handle; }; @@ -29,53 +75,79 @@ struct ksmbd_heartbeat { #define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(1) #define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(2) +/* + * IPC request for ksmbd server startup + */ struct ksmbd_startup_request { - __u32 flags; - __s32 signing; - __s8 min_prot[16]; - __s8 max_prot[16]; + __u32 flags; /* Flags for global config */ + __s32 signing; /* Signing enabled */ + __s8 min_prot[16]; /* The minimum SMB protocol version */ + __s8 max_prot[16]; /* The maximum SMB protocol version */ __s8 netbios_name[16]; - __s8 work_group[64]; - __s8 server_string[64]; - __u16 tcp_port; - __u16 ipc_timeout; - __u32 deadtime; - __u32 file_max; - __u32 smb2_max_write; - __u32 smb2_max_read; - __u32 smb2_max_trans; - __u32 share_fake_fscaps; - __u32 sub_auth[3]; - __u32 ifc_list_sz; + __s8 work_group[64]; /* Workgroup */ + __s8 server_string[64]; /* Server string */ + __u16 tcp_port; /* tcp port */ + __u16 ipc_timeout; /* + * specifies the number of seconds + * server will wait for the userspace to + * reply to heartbeat frames. + */ + __u32 deadtime; /* Number of minutes of inactivity */ + __u32 file_max; /* Limits the maximum number of open files */ + __u32 smb2_max_write; /* MAX write size */ + __u32 smb2_max_read; /* MAX read size */ + __u32 smb2_max_trans; /* MAX trans size */ + __u32 share_fake_fscaps; /* + * Support some special application that + * makes QFSINFO calls to check whether + * we set the SPARSE_FILES bit (0x40). + */ + __u32 sub_auth[3]; /* Subauth value for Security ID */ + __u32 ifc_list_sz; /* interfaces list size */ __s8 ____payload[]; }; #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) +/* + * IPC request to shutdown ksmbd server. + */ struct ksmbd_shutdown_request { __s32 reserved; }; +/* + * IPC user login request. + */ struct ksmbd_login_request { __u32 handle; - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ }; +/* + * IPC user login response. + */ struct ksmbd_login_response { __u32 handle; - __u32 gid; - __u32 uid; - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __u32 gid; /* group id */ + __u32 uid; /* user id */ + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ __u16 status; - __u16 hash_sz; - __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; + __u16 hash_sz; /* hash size */ + __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; /* password hash */ }; +/* + * IPC request to fetch net share config. + */ struct ksmbd_share_config_request { __u32 handle; - __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; /* share name */ }; +/* + * IPC response to the net share config request. + */ struct ksmbd_share_config_response { __u32 handle; __u32 flags; @@ -102,6 +174,10 @@ ksmbd_share_config_path(struct ksmbd_share_config_response *sc) return p; } +/* + * IPC request for tree connection. This request include session and tree + * connect info from client. + */ struct ksmbd_tree_connect_request { __u32 handle; __u16 account_flags; @@ -113,21 +189,34 @@ struct ksmbd_tree_connect_request { __s8 peer_addr[64]; }; +/* + * IPC Response structure for tree connection. + */ struct ksmbd_tree_connect_response { __u32 handle; __u16 status; __u16 connection_flags; }; +/* + * IPC Request struture to disconnect tree connection. + */ struct ksmbd_tree_disconnect_request { - __u64 session_id; - __u64 connect_id; + __u64 session_id; /* session id */ + __u64 connect_id; /* tree connection id */ }; +/* + * IPC Response structure to logout user account. + */ struct ksmbd_logout_request { - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ }; +/* + * RPC command structure to send rpc request like srvsvc or wkssvc to + * IPC user daemon. + */ struct ksmbd_rpc_command { __u32 handle; __u32 flags; @@ -135,18 +224,36 @@ struct ksmbd_rpc_command { __u8 payload[]; }; +/* + * IPC Request Kerberos authentication + */ struct ksmbd_spnego_authen_request { __u32 handle; - __u16 spnego_blob_len; - __u8 spnego_blob[0]; + __u16 spnego_blob_len; /* the length of spnego_blob */ + __u8 spnego_blob[0]; /* + * the GSS token from SecurityBuffer of + * SMB2 SESSION SETUP request + */ }; +/* + * Response data which includes the GSS token and the session key generated by + * user daemon. + */ struct ksmbd_spnego_authen_response { __u32 handle; - struct ksmbd_login_response login_response; - __u16 session_key_len; - __u16 spnego_blob_len; - __u8 payload[]; /* session key + AP_REP */ + struct ksmbd_login_response login_response; /* + * the login response with + * a user identified by the + * GSS token from a client + */ + __u16 session_key_len; /* the length of the session key */ + __u16 spnego_blob_len; /* + * the length of the GSS token which will be + * stored in SecurityBuffer of SMB2 SESSION + * SETUP response + */ + __u8 payload[]; /* session key + AP_REP */ }; /* @@ -185,6 +292,9 @@ enum ksmbd_event { KSMBD_EVENT_MAX }; +/* + * Enumeration for IPC tree connect status. + */ enum KSMBD_TREE_CONN_STATUS { KSMBD_TREE_CONN_STATUS_OK = 0, KSMBD_TREE_CONN_STATUS_NOMEM, @@ -262,6 +372,9 @@ enum KSMBD_TREE_CONN_STATUS { #define KSMBD_RPC_LSARPC_METHOD_INVOKE BIT(11) #define KSMBD_RPC_LSARPC_METHOD_RETURN (KSMBD_RPC_LSARPC_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN) +/* + * RPC status definitions. + */ #define KSMBD_RPC_OK 0 #define KSMBD_RPC_EBAD_FUNC 0x00000001 #define KSMBD_RPC_EACCESS_DENIED 0x00000005 diff --git a/fs/ksmbd/ksmbd_work.c b/fs/ksmbd/ksmbd_work.c index 7c914451bbe1..fd58eb4809f6 100644 --- a/fs/ksmbd/ksmbd_work.c +++ b/fs/ksmbd/ksmbd_work.c @@ -12,7 +12,6 @@ #include "connection.h" #include "ksmbd_work.h" #include "mgmt/ksmbd_ida.h" -#include "ksmbd_server.h" static struct kmem_cache *work_cache; static struct workqueue_struct *ksmbd_wq; diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h index 4e40ec3f4774..18e2a996e0aa 100644 --- a/fs/ksmbd/mgmt/tree_connect.h +++ b/fs/ksmbd/mgmt/tree_connect.h @@ -8,7 +8,7 @@ #include -#include "../ksmbd_server.h" +#include "../ksmbd_netlink.h" struct ksmbd_share_config; struct ksmbd_user; diff --git a/fs/ksmbd/smb2ops.c b/fs/ksmbd/smb2ops.c index f7e5f21d4ae2..8262908e467c 100644 --- a/fs/ksmbd/smb2ops.c +++ b/fs/ksmbd/smb2ops.c @@ -12,7 +12,6 @@ #include "connection.h" #include "smb_common.h" #include "server.h" -#include "ksmbd_server.h" static struct smb_version_values smb21_server_values = { .version_string = SMB21_VERSION_STRING, diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c index 958937a548a1..d385c7045cc0 100644 --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -14,7 +14,6 @@ #include "smb_common.h" #include "server.h" #include "misc.h" -#include "ksmbd_server.h" #include "mgmt/share_config.h" static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5}, diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index ba12fea004b5..e30174a0e5a1 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -14,92 +14,7 @@ #include #include "smbacl.h" - -/* STREAM XATTR PREFIX */ -#define STREAM_PREFIX "DosStream." -#define STREAM_PREFIX_LEN (sizeof(STREAM_PREFIX) - 1) -#define XATTR_NAME_STREAM (XATTR_USER_PREFIX STREAM_PREFIX) -#define XATTR_NAME_STREAM_LEN (sizeof(XATTR_NAME_STREAM) - 1) - -enum { - XATTR_DOSINFO_ATTRIB = 0x00000001, - XATTR_DOSINFO_EA_SIZE = 0x00000002, - XATTR_DOSINFO_SIZE = 0x00000004, - XATTR_DOSINFO_ALLOC_SIZE = 0x00000008, - XATTR_DOSINFO_CREATE_TIME = 0x00000010, - XATTR_DOSINFO_CHANGE_TIME = 0x00000020, - XATTR_DOSINFO_ITIME = 0x00000040 -}; - -struct xattr_dos_attrib { - __u16 version; - __u32 flags; - __u32 attr; - __u32 ea_size; - __u64 size; - __u64 alloc_size; - __u64 create_time; - __u64 change_time; - __u64 itime; -}; - -/* DOS ATTRIBUITE XATTR PREFIX */ -#define DOS_ATTRIBUTE_PREFIX "DOSATTRIB" -#define DOS_ATTRIBUTE_PREFIX_LEN (sizeof(DOS_ATTRIBUTE_PREFIX) - 1) -#define XATTR_NAME_DOS_ATTRIBUTE \ - (XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) -#define XATTR_NAME_DOS_ATTRIBUTE_LEN \ - (sizeof(XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) - 1) - -#define XATTR_SD_HASH_TYPE_SHA256 0x1 -#define XATTR_SD_HASH_SIZE 64 - -#define SMB_ACL_READ 4 -#define SMB_ACL_WRITE 2 -#define SMB_ACL_EXECUTE 1 - -enum { - SMB_ACL_TAG_INVALID = 0, - SMB_ACL_USER, - SMB_ACL_USER_OBJ, - SMB_ACL_GROUP, - SMB_ACL_GROUP_OBJ, - SMB_ACL_OTHER, - SMB_ACL_MASK -}; - -struct xattr_acl_entry { - int type; - uid_t uid; - gid_t gid; - mode_t perm; -}; - -struct xattr_smb_acl { - int count; - int next; - struct xattr_acl_entry entries[0]; -}; - -struct xattr_ntacl { - __u16 version; - void *sd_buf; - __u32 sd_size; - __u16 hash_type; - __u8 desc[10]; - __u16 desc_len; - __u64 current_time; - __u8 hash[XATTR_SD_HASH_SIZE]; - __u8 posix_acl_hash[XATTR_SD_HASH_SIZE]; -}; - -/* SECURITY DESCRIPTOR XATTR PREFIX */ -#define SD_PREFIX "NTACL" -#define SD_PREFIX_LEN (sizeof(SD_PREFIX) - 1) -#define XATTR_NAME_SD \ - (XATTR_SECURITY_PREFIX SD_PREFIX) -#define XATTR_NAME_SD_LEN \ - (sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1) +#include "xattr.h" /* * Enumeration for stream type. diff --git a/fs/ksmbd/xattr.h b/fs/ksmbd/xattr.h new file mode 100644 index 000000000000..8857c01093d9 --- /dev/null +++ b/fs/ksmbd/xattr.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2021 Samsung Electronics Co., Ltd. + */ + +#ifndef __XATTR_H__ +#define __XATTR_H__ + +/* + * These are on-disk structures to store additional metadata into xattr to + * reproduce windows filesystem semantics. And they are encoded with NDR to + * compatible with samba's xattr meta format. The compatibility with samba + * is important because it can lose the information(file attribute, + * creation time, acls) about the existing files when switching between + * ksmbd and samba. + */ + +/* + * Dos attribute flags used for what variable is valid. + */ +enum { + XATTR_DOSINFO_ATTRIB = 0x00000001, + XATTR_DOSINFO_EA_SIZE = 0x00000002, + XATTR_DOSINFO_SIZE = 0x00000004, + XATTR_DOSINFO_ALLOC_SIZE = 0x00000008, + XATTR_DOSINFO_CREATE_TIME = 0x00000010, + XATTR_DOSINFO_CHANGE_TIME = 0x00000020, + XATTR_DOSINFO_ITIME = 0x00000040 +}; + +/* + * Dos attribute structure which is compatible with samba's one. + * Storing it into the xattr named "DOSATTRIB" separately from inode + * allows ksmbd to faithfully reproduce windows filesystem semantics + * on top of a POSIX filesystem. + */ +struct xattr_dos_attrib { + __u16 version; /* version 3 or version 4 */ + __u32 flags; /* valid flags */ + __u32 attr; /* Dos attribute */ + __u32 ea_size; /* EA size */ + __u64 size; + __u64 alloc_size; + __u64 create_time; /* File creation time */ + __u64 change_time; /* File change time */ + __u64 itime; /* Invented/Initial time */ +}; + +/* + * Enumeration is used for computing posix acl hash. + */ +enum { + SMB_ACL_TAG_INVALID = 0, + SMB_ACL_USER, + SMB_ACL_USER_OBJ, + SMB_ACL_GROUP, + SMB_ACL_GROUP_OBJ, + SMB_ACL_OTHER, + SMB_ACL_MASK +}; + +#define SMB_ACL_READ 4 +#define SMB_ACL_WRITE 2 +#define SMB_ACL_EXECUTE 1 + +struct xattr_acl_entry { + int type; + uid_t uid; + gid_t gid; + mode_t perm; +}; + +/* + * xattr_smb_acl structure is used for computing posix acl hash. + */ +struct xattr_smb_acl { + int count; + int next; + struct xattr_acl_entry entries[0]; +}; + +/* 64bytes hash in xattr_ntacl is computed with sha256 */ +#define XATTR_SD_HASH_TYPE_SHA256 0x1 +#define XATTR_SD_HASH_SIZE 64 + +/* + * xattr_ntacl is used for storing ntacl and hashes. + * Hash is used for checking valid posix acl and ntacl in xattr. + */ +struct xattr_ntacl { + __u16 version; /* version 4*/ + void *sd_buf; + __u32 sd_size; + __u16 hash_type; /* hash type */ + __u8 desc[10]; /* posix_acl description */ + __u16 desc_len; + __u64 current_time; + __u8 hash[XATTR_SD_HASH_SIZE]; /* 64bytes hash for ntacl */ + __u8 posix_acl_hash[XATTR_SD_HASH_SIZE]; /* 64bytes hash for posix acl */ +}; + +/* DOS ATTRIBUITE XATTR PREFIX */ +#define DOS_ATTRIBUTE_PREFIX "DOSATTRIB" +#define DOS_ATTRIBUTE_PREFIX_LEN (sizeof(DOS_ATTRIBUTE_PREFIX) - 1) +#define XATTR_NAME_DOS_ATTRIBUTE (XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) +#define XATTR_NAME_DOS_ATTRIBUTE_LEN \ + (sizeof(XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) - 1) + +/* STREAM XATTR PREFIX */ +#define STREAM_PREFIX "DosStream." +#define STREAM_PREFIX_LEN (sizeof(STREAM_PREFIX) - 1) +#define XATTR_NAME_STREAM (XATTR_USER_PREFIX STREAM_PREFIX) +#define XATTR_NAME_STREAM_LEN (sizeof(XATTR_NAME_STREAM) - 1) + +/* SECURITY DESCRIPTOR(NTACL) XATTR PREFIX */ +#define SD_PREFIX "NTACL" +#define SD_PREFIX_LEN (sizeof(SD_PREFIX) - 1) +#define XATTR_NAME_SD (XATTR_SECURITY_PREFIX SD_PREFIX) +#define XATTR_NAME_SD_LEN \ + (sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1) + +#endif /* __XATTR_H__ */