From 456bca5cbbfed9165d071b3e5e44b6237a86acab Mon Sep 17 00:00:00 2001 From: Vladimir Vid Date: Tue, 12 Mar 2019 15:29:17 +0100 Subject: [PATCH] cifsd: add package * add cifsd - kernel module * add cifsd-tools - userspace package Reference repos: https://github.com/namjaejeon/cifsd https://github.com/namjaejeon/cifsd-tools Signed-off-by: Vladimir Vid --- cifsd-tools/Makefile | 53 ++++++++ cifsd-tools/files/cifsd.config | 9 ++ cifsd-tools/files/cifsd.init | 124 ++++++++++++++++++ cifsd/001-fix_implicit_declarations.patch | 73 +++++++++++ cifsd/Makefile | 60 +++++++++ .../001-fix_implicit_declarations.patch | 69 ++++++++++ 6 files changed, 388 insertions(+) create mode 100644 cifsd-tools/Makefile create mode 100644 cifsd-tools/files/cifsd.config create mode 100644 cifsd-tools/files/cifsd.init create mode 100644 cifsd/001-fix_implicit_declarations.patch create mode 100644 cifsd/Makefile create mode 100644 cifsd/patches/001-fix_implicit_declarations.patch diff --git a/cifsd-tools/Makefile b/cifsd-tools/Makefile new file mode 100644 index 000000000..2507420ca --- /dev/null +++ b/cifsd-tools/Makefile @@ -0,0 +1,53 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=cifsd-tools +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd-tools.git +PKG_SOURCE_DATE:=2019-02-14 +PKG_SOURCE_VERSION:=a7d7dfc40524b88dbcb2052034a75f446b3cefdd +PKG_MIRROR_HASH:=a74f95a79c3cdcc78e66c080729141abee0d821e21a326d88b11d849738314fb + +PKG_MAINTAINER:=Andy Walsh +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING + +PKG_INSTALL:=1 +PKG_FIXUP:=autoreconf +PKG_REMOVE_FILES:=autogen.sh aclocal.m4 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/cifsd-tools + SECTION:=net + CATEGORY:=Network + SUBMENU:=Filesystem + TITLE:=Kernel CIFS/SMB server support and userspace tools + DEPENDS:=+kmod-fs-cifsd +glib2 +libnl-core +libnl-genl $(ICONV_DEPENDS) +endef + +define Package/cifsd-tools/description + Userspace tools (cifsd, cifsadmin) for the CIFS/SMB kernel fileserver. + The config file location is /etc/cifs/smb.conf +endef + +define Package/cifsd-tools/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcifsdtools.so* $(1)/usr/lib/ + + $(INSTALL_DIR) $(1)/etc/cifs + $(INSTALL_CONF) $(PKG_BUILD_DIR)/smb.conf.example $(1)/etc/cifs + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/cifsd.config $(1)/etc/config/cifsd + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/cifsd.init $(1)/etc/init.d/cifsd + + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{cifsadmin,cifsd} $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,cifsd-tools)) diff --git a/cifsd-tools/files/cifsd.config b/cifsd-tools/files/cifsd.config new file mode 100644 index 000000000..27865bbea --- /dev/null +++ b/cifsd-tools/files/cifsd.config @@ -0,0 +1,9 @@ +config global + option server_string 'CIFSD on OpenWRT' + option ipc_timeout '8' # IPC timeout is used as a workaround for uninterruptible sleep until this is fixed upstream. + +config share + option name 'share' + option comment 'Default guest share' + option path '/mnt' + option guest_ok 'yes' diff --git a/cifsd-tools/files/cifsd.init b/cifsd-tools/files/cifsd.init new file mode 100644 index 000000000..8ad2f3827 --- /dev/null +++ b/cifsd-tools/files/cifsd.init @@ -0,0 +1,124 @@ +#!/bin/sh /etc/rc.common + +START=90 +USE_PROCD=1 +PROG=/usr/sbin/cifsd +USER_DB=/etc/cifs/cifsdpwd.db + +EXTRA_COMMANDS="users" +EXTRA_HELP=" users Show list of users created by cifsadmin" + +users() { + [ -f "$USER_DB" ] && cut -d ':' $USER_DB -f1 || \ + printf "No users available.\n" +} + +validate_cifsd_global() { + uci_validate_section cifsd global "${1}" \ + 'server_string:string' \ + 'workgroup:string' \ + 'netbios_name:string' \ + 'ipc_timeout:uinteger' +} + +validate_cifsd_share() { + uci_validate_section cifsd share "${1}" \ + 'name:string' \ + 'comment:string' \ + 'path:string' \ + 'guest_ok:bool' \ + 'writeable:bool' \ + 'allow_hosts:list' \ + 'deny_hosts:list' \ + 'valid_users:list' \ + 'invalid_users:list' \ + 'max_connections:uinteger' \ + 'veto_files:list' +} + +load_cifsd_global() { + local server_string + local workgroup + local netbios name + local ipc_timeout + + echo -e "[global]" >> /var/etc/cifsd.conf + [ -n "$server_string" ] && echo -e "\tserver string = $server_string" >> /var/etc/cifsd.conf + [ -n "$workgroup" ] && echo -e "\tworkgroup = $workgroup" >> /var/etc/cifsd.conf + [ -n "$netbios_name" ] && echo -e "\tnetbios name = $netbios_name" >> /var/etc/cifsd.conf + [ -n "$ipc_timeout" ] && echo -e "\tipc timeout name = $ipc_timeout" >> /var/etc/cifsd.conf || \ + echo -e "\tipc timeout name = 8" >> /var/etc/cifsd.conf +} + +load_cifsd_share() { + local name + local comment + local path + local guest_ok + local writeable + local allow_hosts + local deny_hosts + local valid_users + local invalid_users + local max_connections + local veto_files + + config_get name $1 name + config_get comment $1 comment + config_get path $1 path + config_get guest_ok $1 guest_ok + config_get allow_hosts $1 allow_hosts + config_get deny_hosts $1 deny_hosts + config_get valid_users $1 valid_users + config_get invalid_users $1 invalid_users + config_get max_connections $1 max_connections + config_get veto_files $1 veto_files + + if [ -z "$name" -o -z "$path" ]; then + return + logread -t ${0} "Missing name or path." + fi + + echo -e "\n[$name]\n\tpath = $path" >> /var/etc/cifsd.conf + [ -n "$comment" ] && echo -e "\tcomment = $comment" >> /var/etc/cifsd.conf + [ -n "$guest_ok" ] && echo -e "\tguest ok = $guest_ok" >> /var/etc/cifsd.conf + [ -n "$writeable" ] && echo -e "\writeable = $writeable" >> /var/etc/cifsd.conf + [ -n "$allow_hosts" ] && echo -e "\tallow hosts = $allow_hosts" >> /var/etc/cifsd.conf + [ -n "$deny_hosts" ] && echo -e "\tdeny hosts = $deny_hosts" >> /var/etc/cifsd.conf + [ -n "$valid_users" ] && echo -e "\tvalid users = $valid_users" >> /var/etc/cifsd.conf + [ -n "$invalid_users" ] && echo -e "\tinvalid users = $invalid_users" >> /var/etc/cifsd.conf + [ -n "$max_connections" ] && echo -e "\tmax connections = $max_connections" >> /var/etc/cifsd.conf + [ -n "$veto_files" ] && echo -e "\tveto files = $veto_files" >> /var/etc/cifsd.conf +} + +service_triggers() +{ + procd_open_validate + validate_cifsd_global + validate_cifsd_share + procd_close_validate +} + +init_config() { + [ -f "/var/etc/cifsd.conf" ] && rm /var/etc/cifsd.conf + + config_load cifsd + load_cifsd_global + config_foreach load_cifsd_share +} + +start_service() { + . /lib/functions.sh + init_config + + [ ! "$(grep cifsd /proc/modules)" ] && modprobe cifsd + procd_open_instance + procd_set_param command /usr/bin/env LANG=en_US.UTF-8 $PROG -c /var/etc/cifsd.conf + procd_set_param respawn + procd_close_instance +} + +stop_service() { + killall cifsd + # IPC timeout will kill the remaining processes. +} diff --git a/cifsd/001-fix_implicit_declarations.patch b/cifsd/001-fix_implicit_declarations.patch new file mode 100644 index 000000000..a77ec8a08 --- /dev/null +++ b/cifsd/001-fix_implicit_declarations.patch @@ -0,0 +1,73 @@ +For some reason, fs.h on Inteno kernel is missing inode->i_mutex nesting subclasses for the lock validator +which is triggering implicit declaration error. To workaround this hardcore use of mutex_lock by removing +kernel version check. +--- +--- a/vfs.c ++++ b/vfs.c +@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work + + attrs->ia_valid |= ATTR_CTIME; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock(inode); +- err = notify_change(dentry, attrs, NULL); +- inode_unlock(inode); +-#else + mutex_lock(&inode->i_mutex); + err = notify_change(dentry, attrs, NULL); + mutex_unlock(&inode->i_mutex); +-#endif + + if (update_size) + put_write_access(inode); +@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name) + if (!dir->d_inode) + goto out; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT); +-#else + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); +-#endif ++ + dentry = lookup_one_len(last, dir, strlen(last)); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); +@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name) + + dput(dentry); + out_err: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_unlock(dir->d_inode); +-#else + mutex_unlock(&dir->d_inode->i_mutex); +-#endif + out: + path_put(&parent); + return err; +@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir, + int err = 0; + + dget(dentry); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock(dir->d_inode); +-#else + mutex_lock(&dir->d_inode->i_mutex); +-#endif ++ + if (!dentry->d_inode || !dentry->d_inode->i_nlink) { + err = -ENOENT; + goto out; +@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir, + err = vfs_unlink(dir->d_inode, dentry, NULL); + + out: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_unlock(dir->d_inode); +-#else + mutex_unlock(&dir->d_inode->i_mutex); +-#endif ++ + dput(dentry); + if (err) + cifsd_debug("failed to delete, err %d\n", err); diff --git a/cifsd/Makefile b/cifsd/Makefile new file mode 100644 index 000000000..842ff3881 --- /dev/null +++ b/cifsd/Makefile @@ -0,0 +1,60 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=cifsd +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd.git +PKG_SOURCE_DATE:=2019-03-05 +PKG_SOURCE_VERSION:=e1715ce125d55b125b1b58a6f1819ef8e54cc3ba +PKG_MIRROR_HASH:=521585ebfda0ecc02372b1a38ebf762fbbcead6d0b754a47599a5bf6bfdb3fb6 + +PKG_MAINTAINER:=Andy Walsh +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/fs-cifsd + SUBMENU:=Filesystems + TITLE:=CIFS/SMB kernel server support + FILES:=$(PKG_BUILD_DIR)/cifsd.$(LINUX_KMOD_SUFFIX) + DEPENDS+= \ + +kmod-nls-base \ + +kmod-nls-utf8 \ + +kmod-crypto-md4 \ + +kmod-crypto-md5 \ + +kmod-crypto-hmac \ + +kmod-crypto-ecb \ + +kmod-crypto-des \ + +kmod-crypto-sha256 \ + +kmod-crypto-cmac \ + +kmod-crypto-sha512 \ + +kmod-crypto-aead \ + +kmod-crypto-ccm + KCONFIG:= \ + CONFIG_KEYS=y \ + CONFIG_CRYPTO_ARC4=y +endef + +define KernelPackage/fs-cifsd/description + Kernel module for a CIFS/SMBv2,3 fileserver. +endef + +TARGET_CFLAGS+= -DCONFIG_CIFSD_ACL + +MAKE_OPTS:=\ + ARCH="$(LINUX_KARCH)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + M="$(PKG_BUILD_DIR)" + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + $(MAKE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + CONFIG_CIFS_SERVER=m \ + modules +endef + +$(eval $(call KernelPackage,fs-cifsd)) diff --git a/cifsd/patches/001-fix_implicit_declarations.patch b/cifsd/patches/001-fix_implicit_declarations.patch new file mode 100644 index 000000000..885f603fe --- /dev/null +++ b/cifsd/patches/001-fix_implicit_declarations.patch @@ -0,0 +1,69 @@ +--- a/vfs.c ++++ b/vfs.c +@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work + + attrs->ia_valid |= ATTR_CTIME; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock(inode); +- err = notify_change(dentry, attrs, NULL); +- inode_unlock(inode); +-#else + mutex_lock(&inode->i_mutex); + err = notify_change(dentry, attrs, NULL); + mutex_unlock(&inode->i_mutex); +-#endif + + if (update_size) + put_write_access(inode); +@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name) + if (!dir->d_inode) + goto out; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT); +-#else + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); +-#endif ++ + dentry = lookup_one_len(last, dir, strlen(last)); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); +@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name) + + dput(dentry); + out_err: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_unlock(dir->d_inode); +-#else + mutex_unlock(&dir->d_inode->i_mutex); +-#endif + out: + path_put(&parent); + return err; +@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir, + int err = 0; + + dget(dentry); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_lock(dir->d_inode); +-#else + mutex_lock(&dir->d_inode->i_mutex); +-#endif ++ + if (!dentry->d_inode || !dentry->d_inode->i_nlink) { + err = -ENOENT; + goto out; +@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir, + err = vfs_unlink(dir->d_inode, dentry, NULL); + + out: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +- inode_unlock(dir->d_inode); +-#else + mutex_unlock(&dir->d_inode->i_mutex); +-#endif ++ + dput(dentry); + if (err) + cifsd_debug("failed to delete, err %d\n", err);