Merge pull request #20261 from pprindeville/strongswan-update-5.9.9
authorPhilip Prindeville <philipp@redfish-solutions.com>
Mon, 13 Mar 2023 00:27:50 +0000 (18:27 -0600)
committerGitHub <noreply@github.com>
Mon, 13 Mar 2023 00:27:50 +0000 (18:27 -0600)
strongswan: Update to 5.9.9

77 files changed:
lang/lua-eco/Makefile
lang/perl-ack/Makefile
lang/rust/Config.in [new file with mode: 0644]
lang/rust/Makefile [new file with mode: 0644]
lang/rust/maturin/Makefile [new file with mode: 0644]
lang/rust/patches/0001-Update-xz2-and-use-it-static.patch [new file with mode: 0644]
lang/rust/rust-host.mk [new file with mode: 0644]
lang/rust/rust-package.mk [new file with mode: 0644]
lang/rust/rust_config.mk [new file with mode: 0644]
libs/icu/Makefile
libs/libb64/Makefile [new file with mode: 0644]
libs/libb64/patches/100-no-Werror.patch [new file with mode: 0644]
libs/libdaq3/Makefile
libs/libdeflate/Makefile [new file with mode: 0644]
libs/libdht/Makefile [new file with mode: 0644]
libs/libmbim/Makefile
libs/libqmi/Makefile
libs/libutp/Makefile [new file with mode: 0644]
libs/msgpack-c/Makefile
libs/msgpack-c/patches/010-no-gtest.patch [deleted file]
libs/openblas/Makefile
libs/protobuf-c/Makefile
libs/tiff/Makefile
multimedia/yt-dlp/Makefile
net/adguardhome/Makefile
net/banip/Makefile
net/banip/files/README.md
net/banip/files/banip-functions.sh
net/banip/files/banip-service.sh
net/banip/files/banip.conf
net/banip/files/banip.init
net/cni-protocol/Makefile [new file with mode: 0644]
net/cni-protocol/files/cni.sh [new file with mode: 0755]
net/frp/Makefile
net/frp/files/frpc.init
net/frp/files/frps.init
net/haproxy/Makefile
net/haproxy/get-latest-patches.sh
net/ksmbd-tools/Makefile
net/ksmbd-tools/patches/010-muon.patch [deleted file]
net/ksmbd-tools/patches/020-meson.patch [deleted file]
net/miniupnpd/Makefile
net/modemmanager/Makefile
net/netbird/Makefile
net/netifyd/Makefile
net/pdns-recursor/Makefile
net/samba4/Makefile
net/samba4/patches/021-source4-msgsock-nvram-fix.patch
net/simple-adblock/Makefile
net/simple-adblock/files/simple-adblock.conf
net/simple-adblock/files/simple-adblock.init
net/sing-box/Makefile
net/snort3/Makefile
net/tmate-ssh-server/Makefile
net/tmate-ssh-server/patches/010-msgpack-c.patch [new file with mode: 0644]
net/tmate/Makefile
net/tmate/patches/020-msgpack-c.patch [new file with mode: 0644]
net/transmission/Makefile
net/transmission/files/transmission-daemon.json
net/transmission/files/transmission.init
net/transmission/patches/001-apply-dscp-to-udp-sockets.patch [deleted file]
net/transmission/patches/010-no-intltool.patch [deleted file]
net/transmission/patches/020-mbedcrypto.patch [deleted file]
net/transmission/patches/030-wolfssl.patch [deleted file]
net/transmission/patches/080-disable-webseeding.patch [deleted file]
net/udp-broadcast-relay-redux-openwrt/Makefile
net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init
net/v2raya/Makefile
net/v2raya/files/v2raya.config
net/v2raya/files/v2raya.init
net/v2raya/patches/019-fix-simple-obfs.patch [new file with mode: 0644]
net/v2raya/patches/020-feat-add-nftables-support.patch [new file with mode: 0644]
utils/conmon/Makefile
utils/coremark/Makefile
utils/lolcat/Makefile
utils/mv88e6xxx_dump/Makefile
utils/ripgrep/Makefile [new file with mode: 0644]

index c836de92e2648d7a30c89620eab473ef6440c2bb..88728ec7e37e552dc1d2d699102531819d0d66cc 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=lua-eco
-PKG_VERSION:=2.0.0
+PKG_VERSION:=2.2.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL=https://github.com/zhaojh329/lua-eco/releases/download/v$(PKG_VERSION)
-PKG_HASH:=df2bed363ac89ce5c776c02baa914fbf4b096e0b87cbf4347d1a48cb4d3b8428
+PKG_HASH:=b45073ba93123d93ab7521b1e699c0f8f8f7de513342b16e2115a0f5a26f8014
 
 PKG_MAINTAINER:=Jianhui Zhao <zhaojh329@gmail.com>
 PKG_LICENSE:=MIT
@@ -30,10 +30,9 @@ define Package/lua-eco
 endef
 
 define Package/lua-eco/description
-  Lua-eco is a Lua interpreter with a built-in libev event loop. It makes all Lua code
-  running in Lua coroutines so code that does I/O can be suspended until data is ready.
-  This allows you write code as if you're using blocking I/O, while still allowing code
-  in other coroutines to run when you'd otherwise wait for I/O. It's kind of like Goroutines.
+  Lua-eco is a Lua interpreter with a built-in event loop for scheduling
+  lightweight coroutines automatically, enabling efficient concurrency in
+  Lua. Build high-performance, scalable applications.
 endef
 
 define Package/lua-eco/Module
@@ -56,15 +55,16 @@ Package/lua-eco-ssl=$(call Package/lua-eco/Module,ssl,\
   +LUA_ECO_OPENSSL:libopenssl +LUA_ECO_WOLFSSL:libwolfssl \
   +LUA_ECO_MBEDTLS:libmbedtls +LUA_ECO_MBEDTLS:zlib +lua-eco-socket)
 Package/lua-eco-ubus=$(call Package/lua-eco/Module,ubus,+libubus)
-Package/lua-eco-termios=$(call Package/lua-eco/Module,termios)
 Package/lua-eco-http=$(call Package/lua-eco/Module,http/https,+lua-eco-dns +lua-eco-ssl +lua-eco-log)
 Package/lua-eco-mqtt=$(call Package/lua-eco/Module,mqtt,+lua-eco-socket +lua-eco-dns +lua-mosquitto)
 Package/lua-eco-websocket=$(call Package/lua-eco/Module,websocket,+lua-eco-http +lua-eco-base64 +lua-eco-sha1)
+Package/lua-eco-termios=$(call Package/lua-eco/Module,termios)
+Package/lua-eco-network=$(call Package/lua-eco/Module,network)
 
 define Package/lua-eco-ssl/config
        choice
                prompt "SSL Library"
-               default LUA_ECO_WOLFSSL
+               default LUA_ECO_MBEDTLS
 
                config LUA_ECO_OPENSSL
                        bool "OpenSSL"
@@ -170,6 +170,11 @@ define Package/lua-eco-termios/install
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/lua/eco/termios.so $(1)/usr/lib/lua/eco
 endef
 
+define Package/lua-eco-network/install
+       $(INSTALL_DIR) $(1)/usr/lib/lua/eco
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/lua/eco/network.so $(1)/usr/lib/lua/eco
+endef
+
 $(eval $(call BuildPackage,lua-eco))
 $(eval $(call BuildPackage,lua-eco-log))
 $(eval $(call BuildPackage,lua-eco-sys))
@@ -184,3 +189,4 @@ $(eval $(call BuildPackage,lua-eco-http))
 $(eval $(call BuildPackage,lua-eco-mqtt))
 $(eval $(call BuildPackage,lua-eco-websocket))
 $(eval $(call BuildPackage,lua-eco-termios))
+$(eval $(call BuildPackage,lua-eco-network))
index 6fee0c87e62ddd5a9a98c3b1b159b350a71d91c2..fc8202109feb02d71eeba3de079bf667ca8ca5ac 100644 (file)
@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-ack
-PKG_VERSION:=3.6.0
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_VERSION:=3.7.0
+PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/P/PE/PETDANCE/
 PKG_SOURCE:=ack-v$(PKG_VERSION).tar.gz
-PKG_HASH:=03144d1070649e92f6a1b7d20bdc535e2bb1ac258daabe482e9aa8277b48f005
+PKG_HASH:=ea7caa14f757de083310ed2cba298661ddcca5dee06ec8f18043ea625a79df20
 
 PKG_LICENSE:=Artistic-2.0
 PKG_LICENSE_FILE:=LICENSE.md
diff --git a/lang/rust/Config.in b/lang/rust/Config.in
new file mode 100644 (file)
index 0000000..490322f
--- /dev/null
@@ -0,0 +1,95 @@
+# Rust Language Options
+menu "Compiler Options"
+       visible if PACKAGE_rust
+
+       config RUST_DEBUG
+               bool "Enables Debugging Environment (--enable-debug)"
+
+       config RUST_DOCS
+               bool "Build standard library documentation (--enable-docs)"
+
+       config RUST_COMPILER_DOCS
+               bool "Build compiler documentation (--enable-compiler-docs)"
+
+       config RUST_OPTIMIZE_TESTS
+               bool "Build tests with optimizations (--enable-optimized-tests)"
+
+       config RUST_PARALLEL
+               bool "Build with multi-threaded support (--enable-parallel-compiler)"
+
+       config RUST_VERBOSE_TESTS
+               bool "Enable verbose output when running tests (--enable-verbose-tests)"
+
+       config RUST_CCACHE
+               bool "Build with ccache enabled (--enable-ccache)"
+
+       config RUST_LLVM_STATIC
+               bool "Statically link to libstdc++ to LLVM (--enable-llvm-static-stdccp)"
+
+       config RUST_LLVM_SHARED
+               bool "Prefer shared linking to LLVM (--enable-llvm-link-shared)"
+
+       config RUST_CODEGEN_TESTS
+               bool "Run the src/test/codegen tests (--enable-codegen-tests)"
+
+       config RUST_OPTION_CHECKING
+               bool "Complain about unrecognized options in this configure script (--enable-option-checking)"
+               default y
+
+       config RUST_ENABLE_NINJA
+               bool "Build LLVM using the Ninja generator (--enable-ninja)"
+               default y
+
+       config RUST_LOCKED_DEPS
+               bool "Force Cargo.lock to be up to date (--enable-locked-deps)"
+
+       config RUST_VENDOR
+               bool "Enable usage of vendored Rust crates (--enable-vendor)"
+
+       config RUST_SANITIZERS
+               bool "Build the sanitizer runtimes (asan, lsan, msan, tsan) (--enable-sanitizers)"
+
+       config RUST_DIST_SRC
+               bool "When building tarballs enables building a source tarball (--enable-dist-src)"
+
+       config RUST_CARGO_NATIVE_STATIC
+               bool "Build static native libraries in Cargo (--enable-cargo-native-static)"
+
+       config RUST_PROFILER
+               bool "Build the profiler runtime (--enable-profiler)"
+
+       config RUST_FULL_TOOLS
+               bool "Build all tools (--enable-full-tools)"
+
+       config RUST_MISSING_TOOLS
+               bool "Allow failures when building tools (--enable-missing-tools)"
+               default y
+
+       config RUST_USE_LIBCXX
+               bool "Build LLVM with libc++ (--enable-use-libcxx)"
+
+       config RUST_CONTROL_FLOW_GUARD
+               bool "Enable Control Flow Guard (--enable-control-flow-guard)"
+
+       config RUST_OPTIMIZE_LLVM
+               bool "Build optimized LLVM (--enable-optimize-llvm)"
+               default y
+
+       config RUST_LLVM_ASSERTIONS
+               bool "Build LLVM with assertions (--enable-llvm-assertions)"
+
+       config RUST_DEBUG_ASSERTIONS
+               bool "Build with debugging assertions (--enable-debug-assertions)"
+
+       config RUST_LLVM_RELEASE_DEBUGINFO
+               bool "Build LLVM with debugger metadata (--enable-llvm-release-debuginfo)"
+
+       config RUST_MANAGE_SUBMODULES
+               bool "Let the build manage the git submodules (--enable-manage-submodules)"
+               default y
+
+       config RUST_FULL_BOOTSTRAP
+               bool "Full Bootstrap - Build three compilers instead of two (--enable-full-bootstrap)"
+
+endmenu
+
diff --git a/lang/rust/Makefile b/lang/rust/Makefile
new file mode 100644 (file)
index 0000000..97d861f
--- /dev/null
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato and Donald Hoskins
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rust
+PKG_VERSION:=1.67.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=rustc-$(PKG_VERSION)-src.tar.gz
+PKG_SOURCE_URL:=https://static.rust-lang.org/dist/
+PKG_HASH:=46483d3e5de85a3bd46f8e7a3ae1837496391067dbe713a25d3cf051b3d9ff6e
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/rustc-$(PKG_VERSION)-src/
+
+PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
+PKG_LICENSE:=Apache-2.0 MIT
+PKG_LICENSE_FILES:=LICENSE-APACHE LICENSE-MIT
+
+HOST_BUILD_DEPENDS:=python3/host
+PKG_HOST_ONLY:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+# rust environment variables
+include ./rust-host.mk
+
+# Rust Temp Directory
+RUST_TMP_DIR:=$(TMP_DIR)/rust-install
+
+RUST_INSTALL_HOST_FILENAME:=$(PKG_NAME)-$(PKG_VERSION)-$(RUSTC_HOST_ARCH)-install.tar.xz
+RUST_INSTALL_TARGET_FILENAME:=$(PKG_NAME)-$(PKG_VERSION)-$(RUSTC_TARGET_ARCH)-install.tar.xz
+
+# Rust-lang has an uninstall script
+RUST_UNINSTALL:=$(CARGO_HOME)/lib/rustlib/uninstall.sh
+
+# Target Flags
+TARGET_CONFIGURE_ARGS = \
+       --set=target.$(RUSTC_TARGET_ARCH).ar=$(TARGET_AR) \
+       --set=target.$(RUSTC_TARGET_ARCH).cc=$(TARGET_CC_NOCACHE) \
+       --set=target.$(RUSTC_TARGET_ARCH).cxx=$(TARGET_CXX_NOCACHE) \
+       --set=target.$(RUSTC_TARGET_ARCH).linker=$(TARGET_CC_NOCACHE) \
+       --set=target.$(RUSTC_TARGET_ARCH).musl-root=$(TOOLCHAIN_DIR) \
+       --set=target.$(RUSTC_TARGET_ARCH).ranlib=$(TARGET_RANLIB)
+
+# CARGO_HOME is an environmental
+HOST_CONFIGURE_OPTS += CARGO_HOME="$(CARGO_HOME)"
+
+# Rust Configuration Arguments
+HOST_CONFIGURE_ARGS = \
+       --build=$(RUSTC_HOST_ARCH) \
+       --target=$(RUSTC_TARGET_ARCH),$(RUSTC_HOST_ARCH) \
+       --host=$(RUSTC_HOST_ARCH) \
+       --prefix=$(CARGO_HOME) \
+       --bindir=$(CARGO_HOME)/bin \
+       --libdir=$(CARGO_HOME)/lib \
+       --sysconfdir=$(CARGO_HOME)/etc \
+       --datadir=$(CARGO_HOME)/share \
+       --mandir=$(CARGO_HOME)/man \
+       --dist-compression-formats=xz \
+       --enable-llvm-link-shared \
+       --enable-llvm-plugins \
+       --enable-missing-tools \
+       --enable-ninja \
+       --disable-sanitizers \
+       --release-channel=stable \
+       --enable-cargo-native-static \
+       $(TARGET_CONFIGURE_ARGS)
+
+define Host/Prepare
+       # Ensure rust temp directory
+       [ -d $(RUST_TMP_DIR) ] || \
+         mkdir -p $(RUST_TMP_DIR)
+
+       $(call Host/Prepare/Default)
+endef
+
+define Host/Uninstall
+       # Call the Uninstall script
+       [ -f $(RUST_UNINSTALL) ] && \
+         $(BASH) $(RUST_UNINSTALL) || echo No Uninstall
+
+       rm -rf $(RUST_TMP_DIR)
+endef
+
+# Makes and then packages the dist artifacts
+define Host/Compile
+       cd $(HOST_BUILD_DIR) && \
+         $(PYTHON) x.py --config ./config.toml dist build-manifest cargo llvm-tools \
+           rustc rust-std rust-src
+
+       $(call Host/PackageDist)
+endef
+
+# Distribution Artifacts are packaged by Host/PackageDist
+# We just need to extract and install
+define Host/Install
+       $(TAR) -C $(RUST_TMP_DIR) -xJf $(DL_DIR)/$(RUST_INSTALL_HOST_FILENAME) && \
+       $(TAR) -C $(RUST_TMP_DIR) -xJf $(DL_DIR)/$(RUST_INSTALL_TARGET_FILENAME)
+
+       cd $(RUST_TMP_DIR) && \
+         find -iname "*.xz" -exec tar -xJf {} ";" && \
+         find ./* -type f -name install.sh -execdir sh {} --prefix=$(CARGO_HOME) --disable-ldconfig \;
+
+       echo -e "[target.$(RUSTC_TARGET_ARCH)]\nlinker = \"$(TARGET_CC_NOCACHE)\"\nrustflags = [\"-Ctarget-feature=-crt-static\", \"-Clink-args=$(RUSTC_LDFLAGS)\"]" > $(CARGO_HOME)/config
+       echo -e "\n[profile.stripped]\ninherits = \"release\"\nopt-level = \"s\"\nstrip = true" >> $(CARGO_HOME)/config
+endef
+
+# Packages the Distribution Artifacts into HOST and TARGET bundles.
+define Host/PackageDist
+       ( \
+               cd $(HOST_BUILD_DIR)/build/dist ; \
+               $(TAR) -cJf $(DL_DIR)/$(RUST_INSTALL_TARGET_FILENAME) \
+                       rust-*-$(RUSTC_TARGET_ARCH).tar.xz ; \
+               $(TAR) -cJf $(DL_DIR)/$(RUST_INSTALL_HOST_FILENAME) \
+                       --exclude rust-*-$(RUSTC_TARGET_ARCH).tar.xz *.xz ; \
+       )
+endef
+
+define Package/rust
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Rust Programming Language Compiler
+  URL:=https://www.rust-lang.org/
+  DEPENDS:=$(RUST_ARCH_DEPENDS) \
+    +pkg-config +libunwind +libopenssl +liblzma +libc
+endef
+
+define Package/rust/description
+  Rust is a multi-paradigm, general-purpose programming language designed for performance
+  and safety, especially safe concurrency. Rust is syntactically similar to C++, but can
+  guarantee memory safety by using a borrow checker to validate references.
+endef
+
+define Package/rust/config
+       source "$(SOURCE)/Config.in"
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,rust))
diff --git a/lang/rust/maturin/Makefile b/lang/rust/maturin/Makefile
new file mode 100644 (file)
index 0000000..c2ed4bc
--- /dev/null
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=maturin
+PKG_VERSION:=0.14.10
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/PyO3/maturin/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=8fc9bcdcb7f1535d5e3e8bb500c348ca1bff5a6dce87b0ab7dbc5a49723da28a
+
+PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
+PKG_LICENSE:=Apache-2.0 MIT
+PKG_LICENSE_FILES:=license-apache license-mit
+
+HOST_BUILD_DEPENDS:=rust/host
+PKG_BUILD_DEPENDS:=rust/host
+
+PKG_BUILD_PARALLEL:=1
+PKG_HOST_ONLY:=1
+
+include ../rust-package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/maturin
+  SECTION:=lang
+  CATEGORY:=Languages
+  SUBMENU:=Rust
+  TITLE:=Build and publish crates as python packages
+  DEPENDS:=$(RUST_ARCH_DEPENDS)
+  URL:=https://maturin.rs
+endef
+
+define Host/Compile
+       $(call Host/Compile/Cargo)
+endef
+
+define Package/maturin/description
+  Build and publish crates with pyo3, rust-cpython, cffi and uniffi
+  bindings as well as rust binaries as python packages.
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin
+       $(INSTALL_BIN) $(HOST_INSTALL_DIR)/bin/maturin $(STAGING_DIR_HOSTPKG)/bin/maturin
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,maturin))
diff --git a/lang/rust/patches/0001-Update-xz2-and-use-it-static.patch b/lang/rust/patches/0001-Update-xz2-and-use-it-static.patch
new file mode 100644 (file)
index 0000000..8c4ec68
--- /dev/null
@@ -0,0 +1,573 @@
+From cfa7506a303537ee7211bd46c39a96bbc5cea9cf Mon Sep 17 00:00:00 2001
+From: Luca Barbato <lu_zero@gentoo.org>
+Date: Fri, 27 Jan 2023 15:34:36 +0100
+Subject: [PATCH] Update xz2 and lzma-sys
+
+And use the static build.
+---
+ Cargo.lock               | 140 +++++++--------------------------------
+ src/bootstrap/Cargo.lock |   8 +--
+ src/bootstrap/Cargo.toml |   2 +-
+ 3 files changed, 28 insertions(+), 122 deletions(-)
+
+diff --git a/Cargo.lock b/Cargo.lock
+index 6a15105805e..d4ecc363071 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -295,45 +295,44 @@ version = "1.0.9"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
+ dependencies = [
+  "serde",
+ ]
+ [[package]]
+ name = "cargo"
+-version = "0.68.0"
++version = "0.67.1"
+ dependencies = [
+  "anyhow",
++ "atty",
+  "base64",
+  "bytesize",
+  "cargo-platform 0.1.2",
+  "cargo-test-macro",
+  "cargo-test-support",
+  "cargo-util",
+  "clap 4.0.15",
+  "crates-io",
+  "curl",
+  "curl-sys",
+- "env_logger 0.10.0",
++ "env_logger 0.9.0",
+  "filetime",
+  "flate2",
+  "fwdansi",
+  "git2",
+  "git2-curl",
+  "glob",
+  "hex 0.4.2",
+  "hmac",
+  "home",
+- "http-auth",
+  "humantime 2.0.1",
+  "ignore",
+  "im-rc",
+  "indexmap",
+- "is-terminal",
+  "itertools",
+  "jobserver",
+  "lazy_static",
+  "lazycell",
+  "libc",
+  "libgit2-sys",
+  "log",
+  "memchr",
+@@ -363,38 +362,38 @@ dependencies = [
+  "unicode-xid",
+  "url",
+  "walkdir",
+  "winapi",
+ ]
+ [[package]]
+ name = "cargo-credential"
+-version = "0.2.0"
++version = "0.1.0"
+ [[package]]
+ name = "cargo-credential-1password"
+-version = "0.2.0"
++version = "0.1.0"
+ dependencies = [
+  "cargo-credential",
+  "serde",
+  "serde_json",
+ ]
+ [[package]]
+ name = "cargo-credential-macos-keychain"
+-version = "0.2.0"
++version = "0.1.0"
+ dependencies = [
+  "cargo-credential",
+  "security-framework",
+ ]
+ [[package]]
+ name = "cargo-credential-wincred"
+-version = "0.2.0"
++version = "0.1.0"
+ dependencies = [
+  "cargo-credential",
+  "winapi",
+ ]
+ [[package]]
+ name = "cargo-miri"
+ version = "0.1.0"
+@@ -438,38 +437,39 @@ dependencies = [
+  "cargo-util",
+  "crates-io",
+  "filetime",
+  "flate2",
+  "git2",
+  "glob",
+  "itertools",
+  "lazy_static",
++ "remove_dir_all",
+  "serde_json",
+  "snapbox",
+  "tar",
+  "termcolor",
+  "toml_edit",
+  "url",
+  "winapi",
+ ]
+ [[package]]
+ name = "cargo-util"
+-version = "0.2.3"
++version = "0.2.2"
+ dependencies = [
+  "anyhow",
+  "core-foundation",
+  "crypto-hash",
+  "filetime",
+  "hex 0.4.2",
+  "jobserver",
+  "libc",
+  "log",
+- "miow 0.5.0",
++ "miow",
+  "same-file",
+  "shell-escape",
+  "tempfile",
+  "walkdir",
+  "winapi",
+ ]
+ [[package]]
+@@ -832,17 +832,17 @@ version = "0.0.0"
+ dependencies = [
+  "colored",
+  "diff",
+  "getopts",
+  "glob",
+  "lazy_static",
+  "lazycell",
+  "libc",
+- "miow 0.3.7",
++ "miow",
+  "miropt-test-tools",
+  "regex",
+  "rustfix",
+  "serde",
+  "serde_json",
+  "tracing",
+  "tracing-subscriber",
+  "unified-diff",
+@@ -857,43 +857,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "70489bbb718aea4f92e5f48f2e3b5be670c2051de30e57cb6e5377b4aa08b372"
+ dependencies = [
+  "diff",
+  "filetime",
+  "getopts",
+  "lazy_static",
+  "libc",
+  "log",
+- "miow 0.3.7",
++ "miow",
+  "regex",
+  "rustfix",
+  "serde",
+  "serde_derive",
+  "serde_json",
+  "tempfile",
+  "tester",
+  "winapi",
+ ]
+ [[package]]
+ name = "concolor"
+-version = "0.0.9"
++version = "0.0.8"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37"
++checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af"
+ dependencies = [
+  "atty",
+  "bitflags",
+  "concolor-query",
+ ]
+ [[package]]
+ name = "concolor-query"
+-version = "0.1.0"
++version = "0.0.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317"
++checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449"
+ [[package]]
+ name = "content_inspector"
+ version = "0.2.4"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
+ dependencies = [
+  "memchr",
+@@ -939,17 +939,17 @@ version = "0.2.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+ dependencies = [
+  "libc",
+ ]
+ [[package]]
+ name = "crates-io"
+-version = "0.35.0"
++version = "0.34.0"
+ dependencies = [
+  "anyhow",
+  "curl",
+  "percent-encoding",
+  "serde",
+  "serde_json",
+  "url",
+ ]
+@@ -1258,50 +1258,16 @@ checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+ dependencies = [
+  "atty",
+  "humantime 2.0.1",
+  "log",
+  "regex",
+  "termcolor",
+ ]
+-[[package]]
+-name = "env_logger"
+-version = "0.10.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
+-dependencies = [
+- "humantime 2.0.1",
+- "is-terminal",
+- "log",
+- "regex",
+- "termcolor",
+-]
+-
+-[[package]]
+-name = "errno"
+-version = "0.2.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+-dependencies = [
+- "errno-dragonfly",
+- "libc",
+- "winapi",
+-]
+-
+-[[package]]
+-name = "errno-dragonfly"
+-version = "0.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+-dependencies = [
+- "cc",
+- "libc",
+-]
+-
+ [[package]]
+ name = "error_index_generator"
+ version = "0.0.0"
+ dependencies = [
+  "mdbook",
+ ]
+ [[package]]
+@@ -1795,25 +1761,16 @@ dependencies = [
+  "log",
+  "mac",
+  "markup5ever",
+  "proc-macro2",
+  "quote",
+  "syn",
+ ]
+-[[package]]
+-name = "http-auth"
+-version = "0.1.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850"
+-dependencies = [
+- "memchr",
+-]
+-
+ [[package]]
+ name = "humantime"
+ version = "1.3.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+ dependencies = [
+  "quick-error",
+ ]
+@@ -2004,38 +1961,16 @@ dependencies = [
+ name = "intl_pluralrules"
+ version = "7.0.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
+ dependencies = [
+  "unic-langid",
+ ]
+-[[package]]
+-name = "io-lifetimes"
+-version = "1.0.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "e394faa0efb47f9f227f1cd89978f854542b318a6f64fa695489c9c993056656"
+-dependencies = [
+- "libc",
+- "windows-sys",
+-]
+-
+-[[package]]
+-name = "is-terminal"
+-version = "0.4.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "aae5bc6e2eb41c9def29a3e0f1306382807764b9b53112030eff57435667352d"
+-dependencies = [
+- "hermit-abi 0.2.6",
+- "io-lifetimes",
+- "rustix",
+- "windows-sys",
+-]
+-
+ [[package]]
+ name = "itertools"
+ version = "0.10.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+ dependencies = [
+  "either",
+ ]
+@@ -2235,22 +2170,16 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
+ name = "lint-docs"
+ version = "0.1.0"
+ dependencies = [
+  "serde_json",
+  "tempfile",
+  "walkdir",
+ ]
+-[[package]]
+-name = "linux-raw-sys"
+-version = "0.1.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
+-
+ [[package]]
+ name = "litemap"
+ version = "0.6.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "f34a3f4798fac63fb48cf277eefa38f94d3443baff555bb98e4f56bc9092368e"
+ [[package]]
+ name = "lld-wrapper"
+@@ -2272,19 +2201,19 @@ version = "0.4.14"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+ dependencies = [
+  "cfg-if 1.0.0",
+ ]
+ [[package]]
+ name = "lzma-sys"
+-version = "0.1.16"
++version = "0.1.20"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99"
++checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
+ dependencies = [
+  "cc",
+  "libc",
+  "pkg-config",
+ ]
+ [[package]]
+ name = "mac"
+@@ -2434,25 +2363,16 @@ dependencies = [
+ name = "miow"
+ version = "0.3.7"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
+ dependencies = [
+  "winapi",
+ ]
+-[[package]]
+-name = "miow"
+-version = "0.5.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "52ffbca2f655e33c08be35d87278e5b18b89550a37dbd598c20db92f6a471123"
+-dependencies = [
+- "windows-sys",
+-]
+-
+ [[package]]
+ name = "miri"
+ version = "0.1.0"
+ dependencies = [
+  "colored",
+  "env_logger 0.9.0",
+  "getrandom 0.2.0",
+  "lazy_static",
+@@ -4637,30 +4557,16 @@ dependencies = [
+  "term",
+  "thiserror",
+  "toml",
+  "unicode-segmentation",
+  "unicode-width",
+  "unicode_categories",
+ ]
+-[[package]]
+-name = "rustix"
+-version = "0.36.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"
+-dependencies = [
+- "bitflags",
+- "errno",
+- "io-lifetimes",
+- "libc",
+- "linux-raw-sys",
+- "windows-sys",
+-]
+-
+ [[package]]
+ name = "rustversion"
+ version = "1.0.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
+ [[package]]
+ name = "ryu"
+@@ -4879,19 +4785,19 @@ checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
+ [[package]]
+ name = "snap"
+ version = "1.0.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e"
+ [[package]]
+ name = "snapbox"
+-version = "0.4.1"
++version = "0.3.3"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293"
++checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7"
+ dependencies = [
+  "concolor",
+  "content_inspector",
+  "dunce",
+  "filetime",
+  "normalize-line-endings",
+  "similar",
+  "snapbox-macros",
+@@ -5866,19 +5772,19 @@ version = "0.2.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
+ dependencies = [
+  "libc",
+ ]
+ [[package]]
+ name = "xz2"
+-version = "0.1.6"
++version = "0.1.7"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
++checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
+ dependencies = [
+  "lzma-sys",
+ ]
+ [[package]]
+ name = "yaml-merge-keys"
+ version = "0.4.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
+index efe8ae3169f..ad115c46110 100644
+--- a/src/bootstrap/Cargo.lock
++++ b/src/bootstrap/Cargo.lock
+@@ -346,19 +346,19 @@ version = "0.4.17"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+ dependencies = [
+  "cfg-if",
+ ]
+ [[package]]
+ name = "lzma-sys"
+-version = "0.1.17"
++version = "0.1.20"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "bdb4b7c3eddad11d3af9e86c487607d2d2442d185d848575365c4856ba96d619"
++checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
+ dependencies = [
+  "cc",
+  "libc",
+  "pkg-config",
+ ]
+ [[package]]
+ name = "memchr"
+@@ -780,19 +780,19 @@ version = "0.2.3"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
+ dependencies = [
+  "libc",
+ ]
+ [[package]]
+ name = "xz2"
+-version = "0.1.6"
++version = "0.1.7"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
++checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
+ dependencies = [
+  "lzma-sys",
+ ]
+ [[package]]
+ name = "yansi"
+ version = "0.5.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
+index ccc7ec1fce9..6d5838439db 100644
+--- a/src/bootstrap/Cargo.toml
++++ b/src/bootstrap/Cargo.toml
+@@ -46,17 +46,17 @@ object = { version = "0.29.0", default-features = false, features = ["archive",
+ serde = { version = "1.0.8", features = ["derive"] }
+ serde_json = "1.0.2"
+ sha2 = "0.10"
+ tar = "0.4"
+ toml = "0.5"
+ ignore = "0.4.10"
+ opener = "0.5"
+ once_cell = "1.7.2"
+-xz2 = "0.1"
++xz2 = { version = "0.1", features = ["static"] }
+ walkdir = "2"
+ # Dependencies needed by the build-metrics feature
+ sysinfo = { version = "0.26.0", optional = true }
+ [target.'cfg(windows)'.dependencies.winapi]
+ version = "0.3"
+ features = [
+-- 
+2.38.0
+
diff --git a/lang/rust/rust-host.mk b/lang/rust/rust-host.mk
new file mode 100644 (file)
index 0000000..acc93c5
--- /dev/null
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato and Donald Hoskins
+
+# Rust Environmental Vars
+CONFIG_HOST_SUFFIX:=$(word 4, $(subst -, ,$(GNU_HOST_NAME)))
+RUSTC_HOST_ARCH:=$(HOST_ARCH)-unknown-linux-$(CONFIG_HOST_SUFFIX)
+CARGO_HOME:=$(STAGING_DIR_HOST)/cargo
+
+# Support only a subset for now.
+RUST_ARCH_DEPENDS:=@(aarch64||arm||i386||i686||mips||mipsel||mips64||mips64el||mipsel||powerpc64||x86_64)
+
+# Common Build Flags
+RUST_BUILD_FLAGS = \
+  CARGO_HOME="$(CARGO_HOME)"
+
+# This adds the rust environmental variables to Make calls
+MAKE_FLAGS += $(RUST_BUILD_FLAGS)
+
+# Force linking of the SSP library
+ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR
+  ifeq ($(strip $(PKG_SSP)),1)
+    RUSTC_LDFLAGS += -lssp_nonshared
+  endif
+endif
+ifdef CONFIG_PKG_CC_STACKPROTECTOR_STRONG
+  ifeq ($(strip $(PKG_SSP)),1)
+    TARGET_CFLAGS += -lssp_nonshared
+  endif
+endif
+
+# mips64 openwrt has a specific targed in rustc
+ifeq ($(ARCH),mips64)
+  RUSTC_TARGET_ARCH:=$(REAL_GNU_TARGET_NAME)
+else
+  RUSTC_TARGET_ARCH:=$(subst openwrt,unknown,$(REAL_GNU_TARGET_NAME))
+endif
+
+RUSTC_TARGET_ARCH:=$(subst muslgnueabi,musleabi,$(RUSTC_TARGET_ARCH))
+
+ifeq ($(ARCH),i386)
+  RUSTC_TARGET_ARCH:=$(subst i486,i586,$(RUSTC_TARGET_ARCH))
+endif
+
+# ARM Logic
+ifeq ($(ARCH),arm)
+  ifeq ($(CONFIG_arm_v7),y)
+    RUSTC_TARGET_ARCH:=$(subst arm,armv7,$(RUSTC_TARGET_ARCH))
+  endif
+
+  ifeq ($(CONFIG_HAS_FPU),y)
+    RUSTC_TARGET_ARCH:=$(subst musleabi,musleabihf,$(RUSTC_TARGET_ARCH))
+  endif
+endif
+
+ifeq ($(ARCH),aarch64)
+    RUST_CFLAGS:=-mno-outline-atomics
+endif
diff --git a/lang/rust/rust-package.mk b/lang/rust/rust-package.mk
new file mode 100644 (file)
index 0000000..54c2aa8
--- /dev/null
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato and Donald Hoskins
+
+rust_mk_path:=$(dir $(lastword $(MAKEFILE_LIST)))
+include $(rust_mk_path)rust-host.mk
+
+# $(1) path to the package
+# $(2) additional arguments to cargo
+define Host/Compile/Cargo
+       ( \
+               cd $(HOST_BUILD_DIR) ; \
+               export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \
+               CARGO_HOME=$(CARGO_HOME) CC=$(HOSTCC) \
+                       cargo install -v --profile stripped --root $(HOST_INSTALL_DIR) --path "$(if $(strip $(1)),$(strip $(1)),.)" $(2) ; \
+       )
+endef
+
+# $(1) path to the package
+# $(2) additional arguments to cargo
+define Build/Compile/Cargo
+       ( \
+               cd $(PKG_BUILD_DIR) ; \
+               export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \
+               CARGO_HOME=$(CARGO_HOME) TARGET_CFLAGS="$(TARGET_CFLAGS) $(RUST_CFLAGS)" TARGET_CC=$(TARGET_CC_NOCACHE) CC=cc \
+                       cargo install -v --profile stripped --target $(RUSTC_TARGET_ARCH) --root $(PKG_INSTALL_DIR) --path "$(if $(strip $(1)),$(strip $(1)),.)" $(2) ; \
+       )
+endef
diff --git a/lang/rust/rust_config.mk b/lang/rust/rust_config.mk
new file mode 100644 (file)
index 0000000..75017f8
--- /dev/null
@@ -0,0 +1,119 @@
+ifeq ($(CONFIG_RUST_DEBUG),y)
+CONFIGURE_ARGS += --enable-debug
+endif
+
+ifeq ($(CONFIG_RUST_DOCS),y)
+CONFIGURE_ARGS += --enable-docs
+else
+CONFIGURE_ARGS += --disable-docs
+endif
+
+ifeq ($(CONFIG_RUST_COMPILER_DOCS),y)
+CONFIGURE_ARGS += --enable-compiler-docs
+else
+CONFIGURE_ARGS += --disable-compiler-docs
+endif
+
+ifeq ($(CONFIG_RUST_OPTIMIZE_TESTS),y)
+CONFIGURE_ARGS += --enable-optimize-tests
+endif
+
+ifeq ($(CONFIG_RUST_PARALLEL),y)
+CONFIGURE_ARGS += --enable-parallel-compiler
+endif
+
+ifeq ($(CONFIG_RUST_VERBOSE_TESTS),y)
+CONFIGURE_ARGS += --enable-verbose-tests
+endif
+
+ifeq ($(filter $(CONFIG_RUST_CCACHE) $(CCACHE),y),)
+CONFIGURE_ARGS += --enable-ccache
+endif
+
+ifeq ($(CONFIG_RUST_CCACHE),y)
+CONFIGURE_ARGS += --enable-ccache
+endif
+
+ifeq ($(CONFIG_RUST_LLVM_STATIC),y)
+CONFIGURE_ARGS += --enable-llvm-static-stdcpp
+endif
+
+ifeq ($(CONFIG_RUST_LLVM_SHARED),y)
+CONFIGURE_ARGS += --enable-llvm-link-shared
+endif
+
+ifeq ($(CONFIG_RUST_CODEGEN_TESTS),y)
+CONFIGURE_ARGS += --enable-codegen-tests
+endif
+
+ifeq ($(CONFIG_RUST_OPTION_CHECKING),y)
+CONFIGURE_ARGS += --enable-option-checking
+endif
+
+ifeq ($(CONFIG_RUST_ENABLE_NINJA),y)
+CONFIGURE_ARGS += --enable-ninja
+endif
+
+ifeq ($(CONFIG_RUST_LOCKED_DEPS),y)
+CONFIGURE_ARGS += --enable-locked-deps
+endif
+
+ifeq ($(CONFIG_RUST_VENDOR),y)
+CONFIGURE_ARGS += --enable-vendor
+endif
+
+ifeq ($(CONFIG_RUST_SANITIZERS),y)
+CONFIGURE_ARGS += --enable-sanitizers
+endif
+
+ifeq ($(CONFIG_RUST_DIST_SRC),y)
+CONFIGURE_ARGS += --enable-dist-src
+endif
+
+ifeq ($(CONFIG_RUST_CARGO_NATIVE_STATIC),y)
+CONFIGURE_ARGS += --enable-cargo-native-static
+endif
+
+ifeq ($(CONFIG_RUST_PROFILER),y)
+CONFIGURE_ARGS += --enable-profiler
+endif
+
+ifeq ($(CONFIG_RUST_FULL_TOOLS),y)
+CONFIGURE_ARGS += --enable-full-tools
+endif
+
+ifeq ($(CONFIG_RUST_MISSING_TOOLS),y)
+CONFIGURE_ARGS += --enable-missing-tools
+endif
+
+ifeq ($(CONFIG_RUST_USE_LIBCXX),y)
+CONFIGURE_ARGS += --enable-use-libcxx
+endif
+
+ifeq ($(CONFIG_RUST_CONTROL_FLOW_GUARD),y)
+CONFIGURE_ARGS += --enable-control-flow-guard
+endif
+
+ifeq ($(CONFIG_RUST_OPTIMIZE_LLVM),y)
+CONFIGURE_ARGS += --enable-optimize-llvm
+endif
+
+ifeq ($(CONFIG_RUST_LLVM_ASSERTIONS),y)
+CONFIGURE_ARGS += --enable-llvm-assertions
+endif
+
+ifeq ($(CONFIG_RUST_DEBUG_ASSERTIONS),y)
+CONFIGURE_ARGS += --enable-debug-assertions
+endif
+
+ifeq ($(CONFIG_RUST_LLVM_RELEASE_DEBUGINFO),y)
+CONFIGURE_ARGS += --enable-llvm-release-debuginfo
+endif
+
+ifeq ($(CONFIG_RUST_MANAGE_SUBMODULES),y)
+CONFIGURE_ARGS += --enable-manage-submodules
+endif
+
+ifeq ($(CONFIG_RUST_FULL_BOOTSTRAP),y)
+CONFIGURE_ARGS += --enable-full-bootstrap
+endif
index 3534d5d806c45bcd8c482d9f38660748ae2a3144..b34c226f4e0a72763023e597fa405b3dd89ace76 100644 (file)
@@ -11,7 +11,7 @@ PKG_NAME:=icu4c
 MAJOR_VERSION:=72
 MINOR_VERSION:=1
 PKG_VERSION:=$(MAJOR_VERSION).$(MINOR_VERSION)
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(MAJOR_VERSION)_$(MINOR_VERSION)-src.tgz
 PKG_SOURCE_URL:=https://github.com/unicode-org/icu/releases/download/release-$(MAJOR_VERSION)-$(MINOR_VERSION)
@@ -79,8 +79,8 @@ endef
 CONFIGURE_CMD:= ./runConfigureICU
 CONFIGURE_ARGS:= \
        Linux/gcc \
-       CC="$(TARGET_CC)" \
-       CXX="$(TARGET_CXX)" \
+       CC="$(TARGET_CC_NOCACHE)" \
+       CXX="$(TARGET_CXX_NOCACHE)" \
        --target=$(GNU_TARGET_NAME) \
        --host=$(GNU_TARGET_NAME) \
        --build=$(GNU_HOST_NAME) \
diff --git a/libs/libb64/Makefile b/libs/libb64/Makefile
new file mode 100644 (file)
index 0000000..8223975
--- /dev/null
@@ -0,0 +1,34 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libb64
+PKG_VERSION:=2.0.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/libb64/libb64/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=28c43c47674409fc50e7145d4c2d26dc1f3d200889c41205e7812c2b67f26382
+
+PKG_LICENSE:=PublicDomain
+PKG_LICENSE_FILES:=LICENSE.md
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+MAKE_FLAGS+=all_src
+
+define Package/libb64
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Base64 Encoding/Decoding Routines
+  URL:=https://github.com/libb64/libb64
+  BUILDONLY:=1
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/b64 $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/include/b64/*.h $(1)/usr/include/b64
+       $(CP) $(PKG_BUILD_DIR)/src/*.a $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libb64))
diff --git a/libs/libb64/patches/100-no-Werror.patch b/libs/libb64/patches/100-no-Werror.patch
new file mode 100644 (file)
index 0000000..5485999
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -15,7 +15,7 @@ TARGETS = $(LIBRARIES)
+ LINK.o = gcc
+-CFLAGS += -Werror -pedantic
++CFLAGS += -pedantic
+ CFLAGS += -I../include
+ vpath %.h ../include/b64
index 7d386a1dec338a480685ae7e4478713dbf246e98..a97eb77552b0e780c3c31b62651eb3ed9b436c3f 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libdaq3
-PKG_VERSION:=3.0.10
+PKG_VERSION:=3.0.11
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
@@ -17,7 +17,7 @@ PKG_LICENSE:=GPL-2.0-only
 
 PKG_SOURCE:=libdaq-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/snort3/libdaq/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=a540b8657dbacab61e23ead203564f351ee30af85f0261979f14f2b7159f701f
+PKG_HASH:=c9b691e113960cc19c4df6e93eacbdb45c96491da9c81471f3e419b91c04579a
 PKG_BUILD_DIR:=$(BUILD_DIR)/libdaq-$(PKG_VERSION)
 
 PKG_FIXUP:=autoreconf
diff --git a/libs/libdeflate/Makefile b/libs/libdeflate/Makefile
new file mode 100644 (file)
index 0000000..1eb16c7
--- /dev/null
@@ -0,0 +1,38 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdeflate
+PKG_VERSION:=1.17
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ebiggers/libdeflate/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=fa4615af671513fa2a53dc2e7a89ff502792e2bdfc046869ef35160fcc373763
+
+PKG_LICENSE:=COPYING
+PKG_LICENSE_FILES:=MIT
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libdeflate
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=library for fast, whole-buffer DEFLATE-based compression and decompression
+  URL:=https://github.com/ebiggers/libdeflate
+endef
+
+define Package/libdeflate/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdeflate.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libdeflate.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libdeflate))
diff --git a/libs/libdht/Makefile b/libs/libdht/Makefile
new file mode 100644 (file)
index 0000000..f81847a
--- /dev/null
@@ -0,0 +1,41 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdht
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/jech/dht
+PKG_SOURCE_DATE:=2022-04-27
+PKG_SOURCE_VERSION:=111230894416d400c9a1e038a033586bfeaafc93
+PKG_MIRROR_HASH:=71decd82023e0d3ec872604e9f0d709003906b38266990a8b1bb540907d1d3f0
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdht
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Kademlia Distributed Hash Table (DHT) library
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/dht $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/dht.h $(1)/usr/include/dht
+       $(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/
+endef
+
+define Package/libdht/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/
+endef
+
+define Build/Compile
+       $(TARGET_CC) $(FPIC) -Wall -c -o $(PKG_BUILD_DIR)/dht.o $(PKG_BUILD_DIR)/dht.c
+       $(TARGET_CC) -shared -lcrypt -o $(PKG_BUILD_DIR)/libdht.so $(PKG_BUILD_DIR)/dht.o
+endef
+
+$(eval $(call BuildPackage,libdht))
index abd94d617aea056607f48b72ee5b73153cb466b0..8591b4337f7a329c58d8f6a640b39d2f3023f94f 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libmbim
-PKG_SOURCE_VERSION:=1.28.2
+PKG_SOURCE_VERSION:=1.28.4
 PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
-PKG_MIRROR_HASH:=0b0b46016738fc22355d5a58c8a2d1b2f04906c49c51a50b57a09640d13b00b7
+PKG_MIRROR_HASH:=7ecc6d1e565392817311254045337907bbad015b46ec88542ea63594f47778be
 
 PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
 
index bfa3bab7c9c54a154f04493a1d14d6773f5ee6d5..8dac951552d2d0b6a71032d2437faa458274b364 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libqmi
-PKG_SOURCE_VERSION:=1.32.2
+PKG_SOURCE_VERSION:=1.32.4
 PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
-PKG_MIRROR_HASH:=711d16d75a6a9afaefcf2be1bc845a4a6181dff786dfbd079e41e91279a0be91
+PKG_MIRROR_HASH:=674f5848c56c11cdc2fbc82c52e5bc2a3a0fddb56315dc4220544688a7b0e17a
 
 PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
 
diff --git a/libs/libutp/Makefile b/libs/libutp/Makefile
new file mode 100644 (file)
index 0000000..28c755d
--- /dev/null
@@ -0,0 +1,46 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libutp
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/transmission/libutp
+PKG_SOURCE_DATE:=2023-02-14
+PKG_SOURCE_VERSION:=c95738b1a6644b919e5b64d3ea9736cfc5894e0b
+PKG_MIRROR_HASH:=5e466da0cb45119d58e8dd847da13951c94bfe9f20936f96b43f350d1e49c625
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libutp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The uTorrent Transport Protocol library
+  DEPENDS:=+libstdcpp
+endef
+
+# MAKE_VARS+=OPT="-I$(PKG_BUILD_DIR)/include/libutp -I$(PKG_BUILD_DIR)/include"
+
+CMAKE_OPTIONS += \
+       -DLIBUTP_SHARED:BOOL=YES \
+       -DLIBUTP_ENABLE_INSTALL:BOOL=YES \
+       -DLIBUTP_ENABLE_WERROR:BOOL=YES \
+       -DLIBUTP_BUILD_PROGRAMS:BOOL=NO
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/libutp $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/libutp/*.h $(1)/usr/include/libutp
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libutp.so $(1)/usr/lib/
+endef
+
+define Package/libutp/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libutp.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libutp))
index d2d20fe9eacb76d333e01d145abfdbe4a895f5ce..7cdaae73a0035ee490d432624ba34db89de3ebf8 100644 (file)
@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=msgpack-c
-PKG_VERSION:=5.0.0
+PKG_VERSION:=6.0.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/msgpack/msgpack-c/tar.gz/c-$(PKG_VERSION)?
-PKG_HASH:=a61288a9a46fd3b3b4cbd48a17736a9568b65419141cb536833f9adfe8fc97d7
+PKG_HASH:=af6f3cf25edb220aa2140b09bb5bdd73ddf00938194bd94ebe5c92090cccb466
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-c-$(PKG_VERSION)
 
 PKG_LICENSE:=BSL-1.0
@@ -46,7 +46,7 @@ endef
 
 define Package/msgpack-c/install
        $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmsgpackc.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmsgpack-c.so* $(1)/usr/lib/
 endef
 
 $(eval $(call BuildPackage,msgpack-c))
diff --git a/libs/msgpack-c/patches/010-no-gtest.patch b/libs/msgpack-c/patches/010-no-gtest.patch
deleted file mode 100644 (file)
index 7bb4dbe..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -74,7 +74,6 @@ IF (MSGPACK_CHAR_SIGN)
-    SET (CMAKE_C_FLAGS "-f${MSGPACK_CHAR_SIGN}-char ${CMAKE_C_FLAGS}")
- ENDIF ()
--FIND_PACKAGE (GTest)
- FIND_PACKAGE (ZLIB)
- FIND_PACKAGE (Threads)
- IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND)
index 7dd5ed9fa1802a6a7c9d48f69058c927fbb93058..83d7d7099d8399b8da99fc3cd99116b78f8d6271 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=OpenBLAS
 PKG_VERSION:=0.3.21
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=2
 
 PKG_SOURCE:=OpenBLAS-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/xianyi/OpenBLAS/releases/download/v$(PKG_VERSION)/
@@ -76,6 +76,8 @@ endif
 
 MAKE_FLAGS += \
        CROSS=1 \
+       CC=$(TARGET_CC_NOCACHE) \
+       CXX=$(TARGET_CXX_NOCACHE) \
        HOSTCC=$(HOSTCC_NOCACHE) \
        CROSS_SUFFIX=$(TARGET_CROSS) \
        BINARY=$(OPENBLAS_BINARY) \
index 8c79a8884e0ca974a35234f52815ce5eeda40f95..b1d167033004200063e4ae8be857b21dd46b49c3 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libprotobuf-c
-PKG_VERSION:=1.4.0
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_VERSION:=1.4.1
+PKG_RELEASE:=1
 
 PKG_SOURCE:=protobuf-c-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/protobuf-c/protobuf-c/releases/download/v$(PKG_VERSION)
-PKG_HASH:=26d98ee9bf18a6eba0d3f855ddec31dbe857667d269bc0b6017335572f85bbcb
+PKG_HASH:=4cc4facd508172f3e0a4d3a8736225d472418aee35b4ad053384b137b220339f
 PKG_BUILD_DIR:=$(BUILD_DIR)/protobuf-c-$(PKG_VERSION)
 HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/protobuf-c-$(PKG_VERSION)
 
index 3b65ca7c1b644e4010da83bd6a1b8b911afc6bcb..39d705232452a6114175d77970754376fec4cf9e 100644 (file)
@@ -64,7 +64,8 @@ CMAKE_OPTIONS += \
        -Dzstd=OFF \
        -Dwebp=OFF \
        -Djpeg12=OFF \
-       -Dcxx=OFF
+       -Dcxx=OFF \
+       -Dlibdeflate=OFF
 
 define Build/InstallDev
        $(call Build/InstallDev/cmake,$(1))
index ee8e7adc3db5c8501e31042929852d78d4fbf45a..1ec3ebaedd04d17123c7e1b7031502bc2156e159 100644 (file)
@@ -1,11 +1,11 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=yt-dlp
-PKG_VERSION:=2023.1.6
+PKG_VERSION:=2023.3.4
 PKG_RELEASE:=1
 
 PYPI_NAME:=yt-dlp
-PKG_HASH:=3a783a36751ced16368f40b3ba865ab39b30689ed8056f1ee2346aa3839a0b0f
+PKG_HASH:=265d5da97a76c15d7d9a4088a67b78acd5dcf6f8cfd8257c52f581ff996ff515
 
 PKG_MAINTAINER:=Michal Vasilek <michal.vasilek@nic.cz>
 PKG_LICENSE:=Unlicense
index 309ffec6c3bbdba79f8b8d9463b75cf7309f4343..328c1329eb3704a8a57eb8677b18d833edd94f20 100644 (file)
@@ -6,13 +6,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=adguardhome
-PKG_VERSION:=0.107.24
+PKG_VERSION:=0.107.25
 PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_VERSION:=v$(PKG_VERSION)
 PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome
-PKG_MIRROR_HASH:=ff5e38d977b8c8f5a546b745ab46894dd4b55f76b447b147287b47d03f6cd507
+PKG_MIRROR_HASH:=609e991f0d03c1541e02fc656f8abea686e64ed350729b85ea87fe25640dd03a
 
 PKG_LICENSE:=GPL-3.0-only
 PKG_LICENSE_FILES:=LICENSE.txt
@@ -56,7 +56,7 @@ endef
 define Build/Compile
        ( \
                pushd $(PKG_BUILD_DIR) ; \
-               make js-deps js-build ; \
+               NODE_OPTIONS=--openssl-legacy-provider make js-deps js-build ; \
                popd ; \
                $(call GoPackage/Build/Compile) ; \
        )
index a75867df3ce0a8b24e5c44d71dbc8d3b34080a40..7e1d5265a700a5bfa39e1d024c120b6c753edd30 100644 (file)
@@ -1,5 +1,5 @@
 #
-# banIP - ban incoming and outgoing ip adresses/subnets via sets in nftables
+# banIP - ban incoming and outgoing ip addresses/subnets via sets in nftables
 # Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org)
 # This is free software, licensed under the GNU General Public License v3.
 #
@@ -7,7 +7,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=banip
-PKG_VERSION:=0.8.1
+PKG_VERSION:=0.8.2
 PKG_RELEASE:=2
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
index f936a8e5b77a179d2a7b08f2c7b28695cf52e7ea..8e7afa35d5717ea9b3f56de47e1b33c396c1c2b6 100644 (file)
@@ -31,72 +31,74 @@ IP address blocking is commonly used to protect against brute force attacks, pre
 | firehol2            | firehol level 2 compilation    |    x    |    x    |         | [Link](https://iplists.firehol.org/?ipset=firehol_level2)     |
 | firehol3            | firehol level 3 compilation    |    x    |    x    |         | [Link](https://iplists.firehol.org/?ipset=firehol_level3)     |
 | firehol4            | firehol level 4 compilation    |    x    |    x    |         | [Link](https://iplists.firehol.org/?ipset=firehol_level4)     |
-| greensnow           | suspicious server IPs          |    x    |    x    |    x    | [Link](https://greensnow.co)                                  |
+| greensnow           | suspicious server IPs          |    x    |    x    |         | [Link](https://greensnow.co)                                  |
 | iblockads           | Advertising IPs                |         |         |    x    | [Link](https://www.iblocklist.com)                            |
-| iblockspy           | Malicious spyware IPs          |    x    |    x    |    x    | [Link](https://www.iblocklist.com)                            |
+| iblockspy           | Malicious spyware IPs          |    x    |    x    |         | [Link](https://www.iblocklist.com)                            |
 | myip                | real-time IP blocklist         |    x    |    x    |         | [Link](https://myip.ms)                                       |
 | nixspam             | iX spam protection             |    x    |    x    |         | [Link](http://www.nixspam.org)                                |
 | oisdbig             | OISD-big IPs                   |         |         |    x    | [Link](https://github.com/dibdot/banIP-IP-blocklists)         |
 | oisdnsfw            | OISD-nsfw IPs                  |         |         |    x    | [Link](https://github.com/dibdot/banIP-IP-blocklists)         |
 | oisdsmall           | OISD-small IPs                 |         |         |    x    | [Link](https://github.com/dibdot/banIP-IP-blocklists)         |
 | proxy               | open proxies                   |    x    |         |         | [Link](https://iplists.firehol.org/?ipset=proxylists)         |
-| ssbl                | SSL botnet IPs                 |    x    |    x    |    x    | [Link](https://sslbl.abuse.ch)                                |
+| ssbl                | SSL botnet IPs                 |    x    |    x    |         | [Link](https://sslbl.abuse.ch)                                |
 | stevenblack         | stevenblack IPs                |         |         |    x    | [Link](https://github.com/dibdot/banIP-IP-blocklists)         |
 | talos               | talos IPs                      |    x    |    x    |         | [Link](https://talosintelligence.com/reputation_center)       |
-| threat              | emerging threats               |    x    |    x    |    x    | [Link](https://rules.emergingthreats.net)                     |
-| threatview          | malicious IPs                  |    x    |    x    |    x    | [Link](https://threatview.io)                                 |
-| tor                 | tor exit nodes                 |    x    |    x    |    x    | [Link](https://github.com/SecOps-Institute/Tor-IP-Addresses)  |
+| threat              | emerging threats               |    x    |    x    |         | [Link](https://rules.emergingthreats.net)                     |
+| threatview          | malicious IPs                  |    x    |    x    |         | [Link](https://threatview.io)                                 |
+| tor                 | tor exit nodes                 |    x    |    x    |         | [Link](https://github.com/SecOps-Institute/Tor-IP-Addresses)  |
 | uceprotect1         | spam protection level 1        |    x    |    x    |         | [Link](http://www.uceprotect.net/en/index.php)                |
 | uceprotect2         | spam protection level 2        |    x    |    x    |         | [Link](http://www.uceprotect.net/en/index.php)                |
 | uceprotect3         | spam protection level 3        |    x    |    x    |         | [Link](http://www.uceprotect.net/en/index.php)                |
 | urlhaus             | urlhaus IDS IPs                |    x    |    x    |         | [Link](https://urlhaus.abuse.ch)                              |
-| urlvir              | malware related IPs            |    x    |    x    |    x    | [Link](https://iplists.firehol.org/?ipset=urlvir)             |
-| webclient           | malware related IPs            |    x    |    x    |    x    | [Link](https://iplists.firehol.org/?ipset=firehol_webclient)  |
+| urlvir              | malware related IPs            |    x    |    x    |         | [Link](https://iplists.firehol.org/?ipset=urlvir)             |
+| webclient           | malware related IPs            |    x    |    x    |         | [Link](https://iplists.firehol.org/?ipset=firehol_webclient)  |
 | voip                | VoIP fraud blocklist           |    x    |    x    |         | [Link](https://voipbl.org)                                    |
 | yoyo                | yoyo IPs                       |         |         |    x    | [Link](https://github.com/dibdot/banIP-IP-blocklists)         |
 
-* zero-conf like automatic installation & setup, usually no manual changes needed
-* all sets are handled in a separate nft table/namespace 'banIP'
-* full IPv4 and IPv6 support
-* supports nft atomic set loading
-* supports blocking by ASN numbers and by iso country codes
-* supports local allow- and blocklist (IPv4, IPv6, CIDR notation or domain names)
-* auto-add the uplink subnet to the local allowlist
-* provides a small background log monitor to ban unsuccessful login attempts in real-time
-* auto-add unsuccessful LuCI, nginx, Asterisk or ssh login attempts to the local blocklist
-* fast feed processing as they are handled in parallel as background jobs
-* per feed it can be defined whether the wan-input chain, the wan-forward chain or the lan-forward chain should be blocked (default: all chains)
-* automatic blocklist backup & restore, the backups will be used in case of download errors or during startup
-* automatically selects one of the following download utilities with ssl support: aria2c, curl, uclient-fetch or wget
-* supports an 'allowlist only' mode, this option restricts internet access from/to a small number of secure websites/IPs
-* deduplicate IPs accross all sets (single IPs only, no intervals)
-* provides comprehensive runtime information
-* provides a detailed set report
-* provides a set search engine for certain IPs
-* feed parsing by fast & flexible regex rulesets
-* minimal status & error logging to syslog, enable debug logging to receive more output
-* procd based init system support (start/stop/restart/reload/status/report/search)
-* procd network interface trigger support
-* ability to add new banIP feeds on your own
+* Zero-conf like automatic installation & setup, usually no manual changes needed
+* All sets are handled in a separate nft table/namespace 'banIP'
+* Full IPv4 and IPv6 support
+* Supports nft atomic set loading
+* Supports blocking by ASN numbers and by iso country codes
+* Supports local allow- and blocklist (IPv4, IPv6, CIDR notation or domain names)
+* Auto-add the uplink subnet to the local allowlist
+* Provides a small background log monitor to ban unsuccessful login attempts in real-time
+* Auto-add unsuccessful LuCI, nginx, Asterisk or ssh login attempts to the local blocklist
+* Fast feed processing as they are handled in parallel as background jobs
+* Per feed it can be defined whether the wan-input chain, the wan-forward chain or the lan-forward chain should be blocked (default: all chains)
+* Automatic blocklist backup & restore, the backups will be used in case of download errors or during startup
+* Automatically selects one of the following download utilities with ssl support: aria2c, curl, uclient-fetch or wget
+* Supports an 'allowlist only' mode, this option restricts internet access from/to a small number of secure websites/IPs
+* Deduplicate IPs accross all sets (single IPs only, no intervals)
+* Provides comprehensive runtime information
+* Provides a detailed set report
+* Provides a set search engine for certain IPs
+* Feed parsing by fast & flexible regex rulesets
+* Minimal status & error logging to syslog, enable debug logging to receive more output
+* Procd based init system support (start/stop/restart/reload/status/report/search/survey)
+* Procd network interface trigger support
+* Ability to add new banIP feeds on your own
 
 ## Prerequisites
-* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 support  
-* a download utility with SSL support: 'wget', 'uclient-fetch' with one of the 'libustream-*' SSL libraries, 'aria2c' or 'curl' is required
-* a certificate store like 'ca-bundle', as banIP checks the validity of the SSL certificates of all download sites by default
-* for E-Mail notifications you need to install and setup the additional 'msmtp' package
+* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 support
+* A download utility with SSL support: 'wget', 'uclient-fetch' with one of the 'libustream-*' SSL libraries, 'aria2c' or 'curl' is required
+* A certificate store like 'ca-bundle', as banIP checks the validity of the SSL certificates of all download sites by default
+* For E-Mail notifications you need to install and setup the additional 'msmtp' package
 
 **Please note the following:**
 * Devices with less than 256Mb of RAM are **_not_** supported
 * Any previous installation of ancient banIP 0.7.x must be uninstalled, and the /etc/banip folder and the /etc/config/banip configuration file must be deleted (they are recreated when this version is installed)
 
 ## Installation & Usage
-* update your local opkg repository (_opkg update_)
-* install banIP (_opkg install banip_) - the banIP service is disabled by default
-* edit the config file '/etc/config/banip' and enable the service (set ban\_enabled to '1'), then add pre-configured feeds via 'ban\_feed' (see the feed list above) and add/change other options to your needs (see the options reference below)
-* start the service with '/etc/init.d/banip start' and check check everything is working by running '/etc/init.d/banip status'
+* Update your local opkg repository (_opkg update_)
+* Install banIP (_opkg install banip_) - the banIP service is disabled by default
+* Install the LuCI companion package 'luci-app-banip' (opkg install luci-app-banip)
+* It's strongly recommended to use the LuCI frontend to easily configure all aspects of banIP, the application is located in LuCI under the 'Services' menu
+* If you're going to configure banIP via CLI, edit the config file '/etc/config/banip' and enable the service (set ban\_enabled to '1'), then add pre-configured feeds via 'ban\_feed' (see the feed list above) and add/change other options to your needs (see the options reference below)
+* Start the service with '/etc/init.d/banip start' and check check everything is working by running '/etc/init.d/banip status'
 
 ## banIP CLI interface
-* All important banIP functions are accessible via CLI. A LuCI frontend will be available in due course.
+* All important banIP functions are accessible via CLI.
 ```
 ~# /etc/init.d/banip
 Syntax: /etc/init.d/banip [command]
@@ -110,7 +112,8 @@ Available commands:
        disable         Disable service autostart
        enabled         Check if service is started on boot
        report          [text|json|mail] Print banIP related set statistics
-       search          [<IPv4 address>|<IPv6 address>] Check if an element exists in the banIP sets
+       search          [<IPv4 address>|<IPv6 address>] Check if an element exists in a banIP set
+       survey          [<set name>] List all elements of a given banIP set
        running         Check if service is running
        status          Service status
        trace           Start with syscall trace
@@ -135,6 +138,7 @@ Available commands:
 | ban_autoallowlist       | option | 1                             | add wan IPs/subnets automatically to the local allowlist                              |
 | ban_autoblocklist       | option | 1                             | add suspicious attacker IPs automatically to the local blocklist                      |
 | ban_allowlistonly       | option | 0                             | restrict the internet access from/to a small number of secure websites/IPs            |
+| ban_basedir             | option | /tmp                          | base working directory while banIP processing                                         |
 | ban_reportdir           | option | /tmp/banIP-report             | directory where banIP stores the report files                                         |
 | ban_backupdir           | option | /tmp/banIP-backup             | directory where banIP stores the compressed backup files                              |
 | ban_protov4             | option | - / autodetect                | enable IPv4 support                                                                   |
@@ -147,8 +151,10 @@ Available commands:
 | ban_deduplicate         | option | 1                             | deduplicate IP addresses across all active sets                                       |
 | ban_splitsize           | option | 0                             | split ext. sets after every n lines/members (saves RAM)                               |
 | ban_cores               | option | - / autodetect                | limit the cpu cores used by banIP (saves RAM)                                         |
+| ban_nftloglevel         | option | warn                          | nft loglevel, values: emerg, alert, crit, err, warn, notice, info, debug, audit       |
+| ban_nftpriority         | option | -200                          | nft priority for the banIP table (default is the prerouting table priority)           |
+| ban_nftpolicy           | option | memory                        | nft policy for banIP-related sets, values: memory, performance                        |
 | ban_nftexpiry           | option | -                             | expiry time for auto added blocklist members, e.g. '5m', '2h' or '1d'                 |
-| ban_nftpriority         | option | -200                          | nft banIP table priority (default is the prerouting table priority)                   |
 | ban_feed                | list   | -                             | external download feeds, e.g. 'yoyo', 'doh', 'country' or 'talos' (see feed table)    |
 | ban_asn                 | list   | -                             | ASNs for the 'asn' feed, e.g.'32934'                                                  |
 | ban_country             | list   | -                             | country iso codes for the 'country' feed, e.g. 'ru'                                   |
@@ -162,6 +168,7 @@ Available commands:
 | ban_mailsender          | option | no-reply@banIP                | sender address for banIP related notification E-Mails                                 |
 | ban_mailtopic           | option | banIP notification            | topic for banIP related notification E-Mails                                          |
 | ban_mailprofile         | option | ban_notify                    | mail profile used in 'msmtp' for banIP related notification E-Mails                   |
+| ban_reportelements      | option | 1                             | list set elements in the report, disable this to speed up the report significantly    |
 | ban_resolver            | option | -                             | external resolver used for DNS lookups                                                |
 
 ## Examples
@@ -216,19 +223,19 @@ Available commands:
 ```
 ~# /etc/init.d/banip status
 ::: banIP runtime information
-  + status            : active
-  + version           : 0.8.1-2
-  + element_count     : 206644
-  + active_feeds      : allowlistvMAC, allowlistv4, allowlistv6, torv4, torv6, countryv6, countryv4, dohv4, dohv6, firehol1v4, deblv4, deblv6,
-                         adguardv6, adguardv4, adguardtrackersv6, adguardtrackersv4, adawayv6, adawayv4, oisdsmallv6, oisdsmallv4, stevenblack
-                        v6, stevenblackv4, yoyov6, yoyov4, antipopadsv4, urlhausv4, antipopadsv6, blocklistvMAC, blocklistv4, blocklistv6
-  + active_devices    : eth2
-  + active_interfaces : wan, wan6
-  + active_subnets    : 91.61.199.218/24, 2a02:910c:0:80:e542:4b0c:846d:1d33/128
-  + run_info          : base_dir: /tmp, backup_dir: /mnt/data/banIP-backup, report_dir: /mnt/data/banIP-report, feed_file: /etc/banip/banip.feeds
-  + run_flags         : proto (4/6): âœ”/✔, log (wan-inp/wan-fwd/lan-fwd): âœ”/✔/✔, deduplicate: âœ”, split: âœ˜, allowed only: âœ˜
-  + last_run          : action: restart, duration: 1m 6s, date: 2023-02-25 08:55:55
-  + system_info       : cores: 2, memory: 1826, device: Turris Omnia, OpenWrt SNAPSHOT r22125-52ddb38469
+  + status            : active (nft: âœ”, monitor: âœ”)
+  + version           : 0.8.2-2
+  + element_count     : 211397
+  + active_feeds      : allowlistvMAC, allowlistv4, allowlistv6, adawayv4, adawayv6, adguardv4, adguardtrackersv4, adguardv6, adguardtrackersv
+                        6, antipopadsv4, antipopadsv6, cinsscorev4, countryv6, countryv4, deblv4, deblv6, dohv4, dohv6, firehol1v4, oisdsmallv
+                        6, oisdsmallv4, stevenblackv6, stevenblackv4, webclientv4, blocklistvMAC, blocklistv4, blocklistv6
+  + active_devices    : eth2 ::: wan, wan6
+  + active_subnets    : 91.64.148.211/24, 2b02:710c:0:80:e442:4b0c:637d:1d33/128
+  + nft_info          : priority: -200, policy: memory, loglevel: warn, expiry: -
+  + run_info          : base: /mnt/data/banIP, backup: /mnt/data/banIP/backup, report: /mnt/data/banIP/report, feed: /etc/banip/banip.feeds
+  + run_flags         : auto: âœ”, proto (4/6): âœ”/✔, log (wan-inp/wan-fwd/lan-fwd): âœ”/✔/✔, dedup: âœ”, split: âœ˜, allowed only: âœ˜
+  + last_run          : action: restart, duration: 0m 55s, date: 2023-03-10 19:33:08
+  + system_info       : cores: 2, memory: 1830, device: Turris Omnia, OpenWrt SNAPSHOT r22248-bf055fcdca
 ```
 
 **banIP search information**  
@@ -237,9 +244,43 @@ Available commands:
 :::
 ::: banIP Search
 :::
-    Looking for IP 221.228.105.173 on 2023-02-08 22:12:48
+    Looking for IP '221.228.105.173' on 2023-02-08 22:12:48
     ---
-    IP found in set oisdbasicv4
+    IP found in Set 'oisdbasicv4'
+```
+
+**banIP survey information**  
+```
+~# /etc/init.d/banip survey cinsscorev4
+:::
+::: banIP Survey
+:::
+    List the elements of Set 'cinsscorev4' on 2023-03-06 14:07:58
+    ---
+1.10.187.179
+1.10.203.30
+1.10.255.58
+1.11.67.53
+1.11.114.211
+1.11.208.29
+1.12.75.87
+1.12.231.227
+1.12.247.134
+1.12.251.141
+1.14.96.156
+1.14.250.37
+1.15.40.79
+1.15.71.140
+1.15.77.237
+[...]
+```
+**default regex for logfile parsing**  
+```
+list ban_logterm 'Exit before auth from'
+list ban_logterm 'luci: failed login'
+list ban_logterm 'error: maximum authentication attempts exceeded'
+list ban_logterm 'sshd.*Connection closed by.*\[preauth\]'
+list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress='
 ```
 
 **allow-/blocklist handling**  
@@ -257,15 +298,16 @@ banIP only supports logfile scanning via logread, so to monitor attacks on Aster
 **tweaks for low memory systems**  
 nftables supports the atomic loading of rules/sets/members, which is cool but unfortunately is also very memory intensive. To reduce the memory pressure on low memory systems (i.e. those with 256-512Mb RAM), you should optimize your configuration with the following options:  
 
-    * point 'ban_reportdir' and 'ban_backupdir' to an external usb drive
+    * point 'ban_basedir', 'ban_reportdir' and 'ban_backupdir' to an external usb drive
     * set 'ban_cores' to '1' (only useful on a multicore system) to force sequential feed processing
     * set 'ban_splitsize' e.g. to '1000' to split the load of an external set after every 1000 lines/members
+    * set 'ban_reportelements' to '0' to disable the CPU intensive counting of set elements
 
 **tweak the download options**  
 By default banIP uses the following pre-configured download options:
 ```
     * aria2c: --timeout=20 --allow-overwrite=true --auto-file-renaming=false --log-level=warn --dir=/ -o
-    * curl: --connect-timeout 20 --silent --show-error --location -o
+    * curl: --connect-timeout 20 --fail --silent --show-error --location -o
     * uclient-fetch: --timeout=20 -O
     * wget: --no-cache --no-cookies --max-redirect=0 --timeout=20 -O
 ```
index 179d5678a217ee5f8b348f4008d57b4b949230f6..6e231a65245c4cf526fdded3508501cc7610fdf2 100644 (file)
@@ -11,13 +11,15 @@ export LC_ALL=C
 export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
 
 ban_basedir="/tmp"
-ban_backupdir="${ban_basedir}/banIP-backup"
-ban_reportdir="${ban_basedir}/banIP-report"
+ban_backupdir="/tmp/banIP-backup"
+ban_reportdir="/tmp/banIP-report"
 ban_feedfile="/etc/banip/banip.feeds"
+ban_allowlist="/etc/banip/banip.allowlist"
+ban_blocklist="/etc/banip/banip.blocklist"
+ban_mailtemplate="/etc/banip/banip.tpl"
 ban_pidfile="/var/run/banip.pid"
+ban_rtfile="/var/run/banip_runtime.json"
 ban_lock="/var/run/banip.lock"
-ban_blocklist="/etc/banip/banip.blocklist"
-ban_allowlist="/etc/banip/banip.allowlist"
 ban_fetchcmd=""
 ban_logreadcmd="$(command -v logread)"
 ban_logcmd="$(command -v logger)"
@@ -32,10 +34,11 @@ ban_mailsender="no-reply@banIP"
 ban_mailreceiver=""
 ban_mailtopic="banIP notification"
 ban_mailprofile="ban_notify"
-ban_mailtemplate="/etc/banip/banip.tpl"
+ban_reportelements="1"
+ban_nftloglevel="warn"
 ban_nftpriority="-200"
+ban_nftpolicy="memory"
 ban_nftexpiry=""
-ban_loglevel="warn"
 ban_loglimit="100"
 ban_logcount="1"
 ban_logterm=""
@@ -49,7 +52,7 @@ ban_autoallowlist="1"
 ban_autoblocklist="1"
 ban_deduplicate="1"
 ban_splitsize="0"
-ban_autodetect=""
+ban_autodetect="1"
 ban_feed=""
 ban_blockinput=""
 ban_blockforwardwan=""
@@ -281,93 +284,133 @@ f_rmpid() {
        : >"${ban_pidfile}"
 }
 
+# get nft/monitor actuals
+#
+f_actual() {
+       local nft monitor
+
+       if "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then
+               nft="$(f_char "1")"
+       else
+               nft="$(f_char "0")"
+       fi
+       if pgrep -f "logread" -P "$(cat "${ban_pidfile}" 2>/dev/null)" >/dev/null 2>&1; then
+               monitor="$(f_char "1")"
+       else
+               monitor="$(f_char "0")"
+       fi
+       printf "%s" "nft: ${nft}, monitor: ${monitor}"
+}
+
 # get wan interfaces
 #
 f_getif() {
-       local iface
+       local iface update="0"
 
-       "${ban_ubuscmd}" -t 5 wait_for network.device network.interface 2>/dev/null
        if [ "${ban_autodetect}" = "1" ]; then
                if [ -z "${ban_ifv4}" ]; then
+                       network_flush_cache
                        network_find_wan iface
-                       if [ -n "${iface}" ] && ! printf "%s" "${ban_ifv4}" | "${ban_grepcmd}" -q "${iface}"; then
+                       if [ -n "${iface}" ] && "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then
                                ban_protov4="1"
-                               ban_ifv4="${ban_ifv4}${iface} "
+                               ban_ifv4="${iface}"
                                uci_set banip global ban_protov4 "1"
                                uci_add_list banip global ban_ifv4 "${iface}"
+                               f_log "info" "added IPv4 interface '${iface}' to config"
                        fi
                fi
                if [ -z "${ban_ifv6}" ]; then
+                       network_flush_cache
                        network_find_wan6 iface
-                       if [ -n "${iface}" ] && ! printf "%s" "${ban_ifv6}" | "${ban_grepcmd}" -q "${iface}"; then
+                       if [ -n "${iface}" ] && "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then
                                ban_protov6="1"
-                               ban_ifv6="${ban_ifv6}${iface} "
+                               ban_ifv6="${iface}"
                                uci_set banip global ban_protov6 "1"
                                uci_add_list banip global ban_ifv6 "${iface}"
+                               f_log "info" "added IPv6 interface '${iface}' to config"
                        fi
                fi
+       fi
+       if [ -n "$(uci -q changes "banip")" ]; then
+               update="1"
+               uci_commit "banip"
+       else
                ban_ifv4="${ban_ifv4%%?}"
                ban_ifv6="${ban_ifv6%%?}"
-               [ -n "$(uci -q changes "banip")" ] && uci_commit "banip"
+               for iface in ${ban_ifv4} ${ban_ifv6}; do
+                       if ! "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then
+                               f_log "err" "wan interface '${iface}' is not available, please check your configuration"
+                       fi
+               done
        fi
        [ -z "${ban_ifv4}" ] && [ -z "${ban_ifv6}" ] && f_log "err" "wan interfaces not found, please check your configuration"
 
-       f_log "debug" "f_getif   ::: auto_detect: ${ban_autodetect}, interfaces (4/6): ${ban_ifv4}/${ban_ifv6}, protocols (4/6): ${ban_protov4}/${ban_protov6}"
+       f_log "debug" "f_getif   ::: auto/update: ${ban_autodetect}/${update}, interfaces (4/6): ${ban_ifv4}/${ban_ifv6}, protocols (4/6): ${ban_protov4}/${ban_protov6}"
 }
 
 # get wan devices
 #
 f_getdev() {
-       local dev iface
+       local dev iface update="0" cnt="0" cnt_max="10"
 
-       if [ "${ban_autodetect}" = "1" ] && [ -z "${ban_dev}" ]; then
-               for iface in ${ban_ifv4} ${ban_ifv6}; do
-                       network_get_device dev "${iface}"
-                       if [ -n "${dev}" ] && ! printf "%s" "${ban_dev}" | "${ban_grepcmd}" -q "${dev}"; then
-                               ban_dev="${ban_dev}${dev} "
-                               uci_add_list banip global ban_dev "${dev}"
-                       else
-                               network_get_physdev dev "${iface}"
-                               if [ -n "${dev}" ] && ! printf "%s" "${ban_dev}" | "${ban_grepcmd}" -q "${dev}"; then
-                                       ban_dev="${ban_dev}${dev} "
-                                       uci_add_list banip global ban_dev "${dev}"
+       if [ "${ban_autodetect}" = "1" ]; then
+               while [ -z "${ban_dev}" ] && [ "${cnt}" -le "${cnt_max}" ]; do
+                       network_flush_cache
+                       for iface in ${ban_ifv4} ${ban_ifv6}; do
+                               network_get_device dev "${iface}"
+                               if [ -n "${dev}" ]; then
+                                       if printf "%s" "${dev}" | "${ban_grepcmd}" -qE "pppoe|6in4"; then
+                                               dev="${iface}"
+                                       fi
+                                       if ! printf " %s " "${ban_dev}" | "${ban_grepcmd}" -q " ${dev} "; then
+                                               ban_dev="${ban_dev}${dev} "
+                                               uci_add_list banip global ban_dev "${dev}"
+                                               f_log "info" "added device '${dev}' to config"
+                                       fi
                                fi
-                       fi
+                       done
+                       cnt="$((cnt + 1))"
+                       sleep 1
                done
-               ban_dev="${ban_dev%%?}"
-               [ -n "$(uci -q changes "banip")" ] && uci_commit "banip"
        fi
+       if [ -n "$(uci -q changes "banip")" ]; then
+               update="1"
+               uci_commit "banip"
+       fi
+       ban_dev="${ban_dev%%?}"
        [ -z "${ban_dev}" ] && f_log "err" "wan devices not found, please check your configuration"
 
-       f_log "debug" "f_getdev  ::: auto_detect: ${ban_autodetect}, devices: ${ban_dev}"
+       f_log "debug" "f_getdev  ::: auto/update: ${ban_autodetect}/${update}, devices: ${ban_dev}, cnt: ${cnt}"
 }
 
 # get local subnets
 #
 f_getsub() {
-       local sub iface ip
+       local sub iface ip update="0"
 
-       for iface in ${ban_ifv4} ${ban_ifv6}; do
-               network_get_subnet sub "${iface}"
-               if [ -n "${sub}" ] && ! printf "%s" "${ban_sub}" | "${ban_grepcmd}" -q "${sub}"; then
-                       ban_sub="${ban_sub} ${sub}"
-               fi
-               network_get_subnet6 sub "${iface}"
-               if [ -n "${sub}" ] && ! printf "%s" "${ban_sub}" | "${ban_grepcmd}" -q "${sub}"; then
-                       ban_sub="${ban_sub} ${sub}"
-               fi
-       done
        if [ "${ban_autoallowlist}" = "1" ]; then
+               for iface in ${ban_ifv4} ${ban_ifv6}; do
+                       network_flush_cache
+                       network_get_subnet sub "${iface}"
+                       if [ -n "${sub}" ] && ! printf " %s " "${ban_sub}" | "${ban_grepcmd}" -q " ${sub} "; then
+                               ban_sub="${ban_sub}${sub} "
+                       fi
+                       network_get_subnet6 sub "${iface}"
+                       if [ -n "${sub}" ] && ! printf " %s " "${ban_sub}" | "${ban_grepcmd}" -q " ${sub} "; then
+                               ban_sub="${ban_sub}${sub} "
+                       fi
+               done
                for ip in ${ban_sub}; do
                        if ! "${ban_grepcmd}" -q "${ip}" "${ban_allowlist}"; then
-                               printf "%-42s%s\n" "${ip}" "added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}"
-                               f_log "info" "add subnet '${ip}' to local allowlist"
+                               update="1"
+                               printf "%-42s%s\n" "${ip}" "# subnet added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}"
+                               f_log "info" "added subnet '${ip}' to local allowlist"
                        fi
                done
+               ban_sub="${ban_sub%%?}"
        fi
-       [ -z "${ban_sub}" ] && f_log "err" "wan subnet(s) not found, please check your configuration"
 
-       f_log "debug" "f_getsub  ::: auto_allowlist: ${ban_autoallowlist}, subnet(s): ${ban_sub:-"-"}"
+       f_log "debug" "f_getsub  ::: auto/update: ${ban_autoallowlist}/${update}, subnet(s): ${ban_sub:-"-"}"
 }
 
 # get set elements
@@ -387,7 +430,7 @@ f_nftinit() {
                # nft header (tables and chains)
                #
                printf "%s\n\n" "#!/usr/sbin/nft -f"
-               if "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then
+               if "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then
                        printf "%s\n" "delete table inet banIP"
                fi
                printf "%s\n" "add table inet banIP"
@@ -422,12 +465,14 @@ f_nftinit() {
        feed_log="$("${ban_nftcmd}" -f "${file}" 2>&1)"
        feed_rc="${?}"
 
-       f_log "debug" "f_nftinit ::: devices: ${ban_dev}, priority: ${ban_nftpriority}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}"
+       f_log "debug" "f_nftinit ::: devices: ${ban_dev}, priority: ${ban_nftpriority}, policy: ${ban_nftpolicy}, loglevel: ${ban_nftloglevel}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}"
        return ${feed_rc}
 }
 
+# handle downloads
+#
 f_down() {
-       local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file input_handles forwardwan_handles forwardlan_handles handle
+       local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file ruleset_raw handle
        local cnt_set cnt_dl restore_rc feed_direction feed_rc feed_log feed="${1}" proto="${2}" feed_url="${3}" feed_rule="${4}" feed_flag="${5}"
 
        start_ts="$(date +%s)"
@@ -439,9 +484,9 @@ f_down() {
        tmp_flush="${ban_tmpfile}.${feed}.flush"
        tmp_nft="${ban_tmpfile}.${feed}.nft"
 
-       [ "${ban_loginput}" = "1" ] && log_input="log level ${ban_loglevel} prefix \"banIP/inp-wan/drp/${feed}: \""
-       [ "${ban_logforwardwan}" = "1" ] && log_forwardwan="log level ${ban_loglevel} prefix \"banIP/fwd-wan/drp/${feed}: \""
-       [ "${ban_logforwardlan}" = "1" ] && log_forwardlan="log level ${ban_loglevel} prefix \"banIP/fwd-lan/rej/${feed}: \""
+       [ "${ban_loginput}" = "1" ] && log_input="log level ${ban_nftloglevel} prefix \"banIP/inp-wan/drp/${feed}: \""
+       [ "${ban_logforwardwan}" = "1" ] && log_forwardwan="log level ${ban_nftloglevel} prefix \"banIP/fwd-wan/drp/${feed}: \""
+       [ "${ban_logforwardlan}" = "1" ] && log_forwardlan="log level ${ban_nftloglevel} prefix \"banIP/fwd-lan/rej/${feed}: \""
 
        # set source block direction
        #
@@ -458,16 +503,14 @@ f_down() {
        # chain/rule maintenance
        #
        if [ "${ban_action}" = "reload" ] && "${ban_nftcmd}" -t list set inet banIP "${feed}" >/dev/null 2>&1; then
-               input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)"
-               forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)"
-               forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)"
+               ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)"
                {
                        printf "%s\n" "flush set inet banIP ${feed}"
-                       handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")"
+                       handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${feed}\"].handle")"
                        [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}"
-                       handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")"
+                       handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")"
                        [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}"
-                       handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")"
+                       handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")"
                        [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}"
                } >"${tmp_flush}"
        fi
@@ -488,11 +531,11 @@ f_down() {
                        [ -s "${tmp_flush}" ] && cat "${tmp_flush}"
                        if [ "${proto}" = "MAC" ]; then
                                "${ban_awkcmd}" '/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s, ",tolower($1)}' "${ban_allowlist}" >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ether saddr @${feed} counter accept"
                        elif [ "${proto}" = "4" ]; then
                                "${ban_awkcmd}" '/^(([0-9]{1,3}\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{printf "%s, ",$1}' "${ban_allowlist}" >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                if [ -z "${feed_direction##*input*}" ]; then
                                        if [ "${ban_allowlistonly}" = "1" ]; then
                                                printf "%s\n" "add rule inet banIP wan-input ip saddr != @${feed} ${log_input} counter drop"
@@ -517,7 +560,7 @@ f_down() {
                        elif [ "${proto}" = "6" ]; then
                                "${ban_awkcmd}" '!/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s\n",$1}' "${ban_allowlist}" |
                                        "${ban_awkcmd}" '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{printf "%s, ",tolower($1)}' >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                if [ -z "${feed_direction##*input*}" ]; then
                                        if [ "${ban_allowlistonly}" = "1" ]; then
                                                printf "%s\n" "add rule inet banIP wan-input ip6 saddr != @${feed} ${log_input} counter drop"
@@ -548,7 +591,7 @@ f_down() {
                        [ -s "${tmp_flush}" ] && cat "${tmp_flush}"
                        if [ "${proto}" = "MAC" ]; then
                                "${ban_awkcmd}" '/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s, ",tolower($1)}' "${ban_blocklist}" >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ether saddr @${feed} ${log_forwardlan} counter reject"
                        elif [ "${proto}" = "4" ]; then
                                if [ "${ban_deduplicate}" = "1" ]; then
@@ -560,7 +603,7 @@ f_down() {
                                        "${ban_awkcmd}" '/^(([0-9]{1,3}\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{printf "%s,\n",$1}' "${ban_blocklist}" >"${tmp_split}"
                                fi
                                "${ban_awkcmd}" '{ORS=" ";print}' "${tmp_split}" 2>/dev/null >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval, timeout; auto-merge; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval, timeout; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                [ -z "${feed_direction##*input*}" ] && printf "%s\n" "add rule inet banIP wan-input ip saddr @${feed} ${log_input} counter drop"
                                [ -z "${feed_direction##*forwardwan*}" ] && printf "%s\n" "add rule inet banIP wan-forward ip saddr @${feed} ${log_forwardwan} counter drop"
                                [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ip daddr @${feed} ${log_forwardlan} counter reject with icmp type admin-prohibited"
@@ -576,7 +619,7 @@ f_down() {
                                                "${ban_awkcmd}" '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{printf "%s,\n",tolower($1)}' >"${tmp_split}"
                                fi
                                "${ban_awkcmd}" '{ORS=" ";print}' "${tmp_split}" 2>/dev/null >"${tmp_file}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval, timeout; auto-merge; policy memory; $(f_getelements "${tmp_file}") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval, timeout; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }"
                                [ -z "${feed_direction##*input*}" ] && printf "%s\n" "add rule inet banIP wan-input ip6 saddr @${feed} ${log_input} counter drop"
                                [ -z "${feed_direction##*forwardwan*}" ] && printf "%s\n" "add rule inet banIP wan-forward ip6 saddr @${feed} ${log_forwardwan} counter drop"
                                [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ip6 daddr @${feed} ${log_forwardlan} counter reject with icmpv6 type admin-prohibited"
@@ -671,7 +714,7 @@ f_down() {
                                #
                                printf "%s\n\n" "#!/usr/sbin/nft -f"
                                [ -s "${tmp_flush}" ] && cat "${tmp_flush}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}.1") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}.1") }"
 
                                # input and forward rules
                                #
@@ -685,7 +728,7 @@ f_down() {
                                #
                                printf "%s\n\n" "#!/usr/sbin/nft -f"
                                [ -s "${tmp_flush}" ] && cat "${tmp_flush}"
-                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}.1") }"
+                               printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}.1") }"
 
                                # input and forward rules
                                #
@@ -717,7 +760,9 @@ f_down() {
                                        fi
                                        rm -f "${split_file}"
                                done
-                               cnt_set="$("${ban_nftcmd}" -j list set inet banIP "${feed}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)"
+                               if [ "${ban_debug}" = "1" ] && [ "${ban_reportelements}" = "1" ]; then
+                                       cnt_set="$("${ban_nftcmd}" -j list set inet banIP "${feed}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)"
+                               fi
                        fi
                else
                        f_log "info" "empty feed ${feed} will be skipped"
@@ -760,44 +805,43 @@ f_restore() {
 # remove disabled feeds
 #
 f_rmset() {
-       local tmp_del table_sets input_handles forwardwan_handles forwardlan_handles handle sets feed feed_log feed_rc
+       local tmp_del ruleset_raw table_sets handle set del_set feed_log feed_rc
 
        tmp_del="${ban_tmpfile}.final.delete"
-       table_sets="$("${ban_nftcmd}" -t list table inet banIP 2>/dev/null | "${ban_awkcmd}" '/^[[:space:]]+set [[:alnum:]]+ /{printf "%s ",$2}' 2>/dev/null)"
-       input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)"
-       forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)"
-       forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)"
+       ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)"
+       table_sets="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')"
        {
                printf "%s\n\n" "#!/usr/sbin/nft -f"
-               for feed in ${table_sets}; do
-                       if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${feed%v*}"; then
-                               sets="${sets}${feed}/"
-                               rm -f "${ban_backupdir}/banIP.${feed}.gz"
-                               printf "%s\n" "flush set inet banIP ${feed}"
-                               handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)"
+               for set in ${table_sets}; do
+                       if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${set%v*}"; then
+                               del_set="${del_set}${set}, "
+                               rm -f "${ban_backupdir}/banIP.${set}.gz"
+                               printf "%s\n" "flush set inet banIP ${set}"
+                               handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].handle")"
                                [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}"
-                               handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)"
+                               handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")"
                                [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}"
-                               handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)"
+                               handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")"
                                [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}"
-                               printf "%s\n\n" "delete set inet banIP ${feed}"
+                               printf "%s\n\n" "delete set inet banIP ${set}"
                        fi
                done
        } >"${tmp_del}"
 
-       if [ -n "${sets}" ]; then
+       if [ -n "${del_set}" ]; then
+               del_set="${del_set%%??}"
                feed_log="$("${ban_nftcmd}" -f "${tmp_del}" 2>&1)"
                feed_rc="${?}"
        fi
        rm -f "${tmp_del}"
 
-       f_log "debug" "f_rmset   ::: sets: ${sets:-"-"}, tmp: ${tmp_del}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}"
+       f_log "debug" "f_rmset   ::: sets: ${del_set:-"-"}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}"
 }
 
 # generate status information
 #
 f_genstatus() {
-       local object duration nft_table nft_feeds cnt_elements="0" split="0" status="${1}"
+       local object duration set table_sets cnt_elements="0" split="0" status="${1}"
 
        [ -z "${ban_dev}" ] && f_conf
        if [ "${status}" = "active" ]; then
@@ -805,19 +849,20 @@ f_genstatus() {
                        ban_endtime="$(date "+%s")"
                        duration="$(((ban_endtime - ban_starttime) / 60))m $(((ban_endtime - ban_starttime) % 60))s"
                fi
-               nft_table="$("${ban_nftcmd}" -t list table inet banIP 2>/dev/null)"
-               nft_feeds="$(f_trim "$(printf "%s\n" "${nft_table}" | "${ban_awkcmd}" '/^[[:space:]]+set [[:alnum:]]+ /{printf "%s ",$2}')")"
-               for object in ${nft_feeds}; do
-                       cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${object}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))"
-               done
+               table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')"
+               if [ "${ban_reportelements}" = "1" ]; then
+                       for set in ${table_sets}; do
+                               cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))"
+                       done
+               fi
                runtime="action: ${ban_action:-"-"}, duration: ${duration:-"-"}, date: $(date "+%Y-%m-%d %H:%M:%S")"
        fi
        f_system
        [ ${ban_splitsize:-"0"} -gt "0" ] && split="1"
 
-       : >"${ban_basedir}/ban_runtime.json"
+       : >"${ban_rtfile}"
        json_init
-       json_load_file "${ban_basedir}/ban_runtime.json" >/dev/null 2>&1
+       json_load_file "${ban_rtfile}" >/dev/null 2>&1
        json_add_string "status" "${status}"
        json_add_string "version" "${ban_ver}"
        json_add_string "element_count" "${cnt_elements}"
@@ -827,7 +872,7 @@ f_genstatus() {
                json_add_string "feed" "-"
                json_close_object
        else
-               for object in ${nft_feeds}; do
+               for object in ${table_sets}; do
                        json_add_object
                        json_add_string "feed" "${object}"
                        json_close_object
@@ -845,14 +890,6 @@ f_genstatus() {
                        json_add_string "device" "${object}"
                        json_close_object
                done
-       fi
-       json_close_array
-       json_add_array "active_interfaces"
-       if [ "${status}" != "active" ]; then
-               json_add_object
-               json_add_string "interface" "-"
-               json_close_object
-       else
                for object in ${ban_ifv4} ${ban_ifv6}; do
                        json_add_object
                        json_add_string "interface" "${object}"
@@ -873,42 +910,66 @@ f_genstatus() {
                done
        fi
        json_close_array
+       json_add_string "nft_info" "priority: ${ban_nftpriority}, policy: ${ban_nftpolicy}, loglevel: ${ban_nftloglevel}, expiry: ${ban_nftexpiry:-"-"}"
        json_add_string "run_info" "base: ${ban_basedir}, backup: ${ban_backupdir}, report: ${ban_reportdir}, feed: ${ban_feedfile}"
-       json_add_string "run_flags" "protocol (4/6): $(f_char ${ban_protov4})/$(f_char ${ban_protov6}), log (wan-inp/wan-fwd/lan-fwd): $(f_char ${ban_loginput})/$(f_char ${ban_logforwardwan})/$(f_char ${ban_logforwardlan}), deduplicate: $(f_char ${ban_deduplicate}), split: $(f_char ${split}), allowed only: $(f_char ${ban_allowlistonly})"
+       json_add_string "run_flags" "auto: $(f_char ${ban_autodetect}), proto (4/6): $(f_char ${ban_protov4})/$(f_char ${ban_protov6}), log (wan-inp/wan-fwd/lan-fwd): $(f_char ${ban_loginput})/$(f_char ${ban_logforwardwan})/$(f_char ${ban_logforwardlan}), dedup: $(f_char ${ban_deduplicate}), split: $(f_char ${split}), allowed only: $(f_char ${ban_allowlistonly})"
        json_add_string "last_run" "${runtime:-"-"}"
        json_add_string "system_info" "cores: ${ban_cores}, memory: ${ban_memory}, device: ${ban_sysver}"
-       json_dump >"${ban_basedir}/ban_runtime.json"
+       json_dump >"${ban_rtfile}"
 }
 
 # get status information
 #
 f_getstatus() {
-       local key keylist type value index_value
+       local key keylist type value index_key1 index_key2 index_value1 index_value2 actual="${1}"
 
        [ -z "${ban_dev}" ] && f_conf
-       json_load_file "${ban_basedir}/ban_runtime.json" >/dev/null 2>&1
+       json_load_file "${ban_rtfile}" >/dev/null 2>&1
        if json_get_keys keylist; then
                printf "%s\n" "::: banIP runtime information"
                for key in ${keylist}; do
                        json_get_var value "${key}" >/dev/null 2>&1
-                       if [ "${key%_*}" = "active" ]; then
+                       if [ "${key}" = "status" ]; then
+                               value="${value} ($(f_actual))"
+                       elif [ "${key}" = "active_devices" ]; then
+                               json_select "${key}" >/dev/null 2>&1
+                               index=1
+                               while json_get_type type "${index}" && [ "${type}" = "object" ]; do
+                                       json_get_keys index_key1 "${index}" >/dev/null 2>&1
+                                       json_get_keys index_key2 "$((index + 1))" >/dev/null 2>&1
+                                       json_get_values index_value1 "${index}" >/dev/null 2>&1
+                                       if [ "${index}" = "1" ] && [ "${index_key1// /}" = "device" ] && [ "${index_key2// /}" = "interface" ]; then
+                                               json_get_values index_value2 "$((index + 1))" >/dev/null 2>&1
+                                               value="${index_value1} ::: ${index_value2}"
+                                               index="$((index + 1))"
+                                       elif [ "${index}" = "1" ]; then
+                                               value="${index_value1}"
+                                       elif [ "${index}" != "1" ] && [ "${index_key1// /}" = "device" ] && [ "${index_key2// /}" = "interface" ]; then
+                                               json_get_values index_value2 "$((index + 1))" >/dev/null 2>&1
+                                               value="${value}, ${index_value1} ::: ${index_value2}"
+                                               index="$((index + 1))"
+                                       elif [ "${index}" != "1" ]; then
+                                               value="${value}, ${index_value1}"
+                                       fi
+                                       index="$((index + 1))"
+                               done
+                               json_select ".."
+                       elif [ "${key%_*}" = "active" ]; then
                                json_select "${key}" >/dev/null 2>&1
                                index=1
                                while json_get_type type "${index}" && [ "${type}" = "object" ]; do
-                                       json_get_values index_value "${index}" >/dev/null 2>&1
+                                       json_get_values index_value1 "${index}" >/dev/null 2>&1
                                        if [ "${index}" = "1" ]; then
-                                               value="${index_value}"
+                                               value="${index_value1}"
                                        else
-                                               value="${value}, ${index_value}"
+                                               value="${value}, ${index_value1}"
                                        fi
-                                       index=$((index + 1))
+                                       index="$((index + 1))"
                                done
                                json_select ".."
                        fi
-                       value="$(
-                               printf "%s" "${value}" |
-                                       awk '{NR=1;max=118;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-24s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}'
-                       )"
+                       value="$(printf "%s" "${value}" |
+                               awk '{NR=1;max=118;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-24s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')"
                        printf "  + %-17s : %s\n" "${key}" "${value:-"-"}"
                done
        else
@@ -949,9 +1010,9 @@ f_lookup() {
                                                fi
                                        fi
                                        if [ "${feed}" = "allowlist" ] && [ "${ban_autoallowlist}" = "1" ]; then
-                                               printf "%-42s%s\n" "${ip}" "# ip of '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}"
+                                               printf "%-42s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}"
                                        elif [ "${feed}" = "blocklist" ] && [ "${ban_autoblocklist}" = "1" ]; then
-                                               printf "%-42s%s\n" "${ip}" "# ip of '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}"
+                                               printf "%-42s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}"
                                        fi
                                fi
                        fi
@@ -964,10 +1025,10 @@ f_lookup() {
        f_log "debug" "f_lookup  ::: name: ${feed}, cnt_domain: ${cnt_domain}, cnt_ip: ${cnt_ip}, duration: ${duration}"
 }
 
-# banIP table statistics
+# table statistics
 #
 f_report() {
-       local report_jsn report_txt set tmp_val nft_raw nft_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}"
+       local report_jsn report_txt set tmp_val ruleset_raw table_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}"
        local detail set_details jsnval timestamp autoadd_allow autoadd_block sum_sets sum_setinput sum_setforwardwan sum_setforwardlan sum_setelements sum_cntinput sum_cntforwardwan sum_cntforwardlan
 
        [ -z "${ban_dev}" ] && f_conf
@@ -977,8 +1038,8 @@ f_report() {
 
        # json output preparation
        #
-       nft_raw="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null)"
-       nft_sets="$(printf "%s" "${nft_raw}" | jsonfilter -qe '@.nftables[*].set.name')"
+       ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)"
+       table_sets="$(printf "%s" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')"
        sum_sets="0"
        sum_setinput="0"
        sum_setforwardwan="0"
@@ -992,12 +1053,17 @@ f_report() {
        {
                printf "%s\n" "{"
                printf "\t%s\n" '"sets": {'
-               for set in ${nft_sets}; do
-                       set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)"
-                       sum_setelements="$((sum_setelements + set_cnt))"
-                       set_cntinput="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-input\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")"
-                       set_cntforwardwan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")"
-                       set_cntforwardlan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"lan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")"
+               for set in ${table_sets}; do
+                       set_cntinput="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")"
+                       set_cntforwardwan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")"
+                       set_cntforwardlan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")"
+                       if [ "${ban_reportelements}" = "1" ]; then
+                               set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)"
+                               sum_setelements="$((sum_setelements + set_cnt))"
+                       else
+                               set_cnt=""
+                               sum_setelements="n/a"
+                       fi
                        if [ -n "${set_cntinput}" ]; then
                                set_input="OK"
                                sum_setinput="$((sum_setinput + 1))"
@@ -1070,14 +1136,14 @@ f_report() {
                                printf "%s\n%s\n%s\n" ":::" "::: banIP Set Statistics" ":::"
                                printf "%s\n" "    Timestamp: ${timestamp}"
                                printf "%s\n" "    ------------------------------"
-                               printf "%s\n" "    auto-added to allowlist: ${autoadd_allow}"
-                               printf "%s\n\n" "    auto-added to blocklist: ${autoadd_block}"
+                               printf "%s\n" "    auto-added to allowlist today: ${autoadd_allow}"
+                               printf "%s\n\n" "    auto-added to blocklist today: ${autoadd_block}"
                                json_select "sets" >/dev/null 2>&1
-                               json_get_keys nft_sets >/dev/null 2>&1
-                               if [ -n "${nft_sets}" ]; then
+                               json_get_keys table_sets >/dev/null 2>&1
+                               if [ -n "${table_sets}" ]; then
                                        printf "%-25s%-15s%-24s%-24s%s\n" "    Set" "| Elements" "| WAN-Input (packets)" "| WAN-Forward (packets)" "| LAN-Forward (packets)"
                                        printf "%s\n" "    ---------------------+--------------+-----------------------+-----------------------+------------------------"
-                                       for set in ${nft_sets}; do
+                                       for set in ${table_sets}; do
                                                printf "    %-21s" "${set}"
                                                json_select "${set}"
                                                json_get_keys set_details
@@ -1121,10 +1187,10 @@ f_report() {
        esac
 }
 
-# banIP set search
+# set search
 #
 f_search() {
-       local nft_sets ip proto run_search search="${1}"
+       local table_sets ip proto run_search search="${1}"
 
        f_system
        run_search="/var/run/banIP.search"
@@ -1136,24 +1202,21 @@ f_search() {
                        ip="$(printf "%s" "${search}" | "${ban_awkcmd}" 'BEGIN{RS="([A-Fa-f0-9]{1,4}::?){3,7}[A-Fa-f0-9]{1,4}"}{printf "%s",RT}')"
                        [ -n "${ip}" ] && proto="v6"
                fi
-               if [ -n "${proto}" ]; then
-                       nft_sets="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null | jsonfilter -qe "@.nftables[@.set.type=\"ip${proto}_addr\"].set.name")"
-               else
-                       printf "%s\n%s\n%s\n" ":::" "::: no valid search input (single IPv4/IPv6 address)" ":::"
-                       return
-               fi
+       fi
+       if [ -n "${proto}" ]; then
+               table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe "@.nftables[@.set.table=\"banIP\"&&@.set.type=\"ip${proto}_addr\"].set.name")"
        else
-               printf "%s\n%s\n%s\n" ":::" "::: no valid search input (single IPv4/IPv6 address)" ":::"
+               printf "%s\n%s\n%s\n" ":::" "::: no valid search input" ":::"
                return
        fi
        printf "%s\n%s\n%s\n" ":::" "::: banIP Search" ":::"
-       printf "%s\n" "    Looking for IP ${ip} on $(date "+%Y-%m-%d %H:%M:%S")"
+       printf "%s\n" "    Looking for IP '${ip}' on $(date "+%Y-%m-%d %H:%M:%S")"
        printf "%s\n" "    ---"
        cnt=1
-       for set in ${nft_sets}; do
+       for set in ${table_sets}; do
                (
                        if "${ban_nftcmd}" get element inet banIP "${set}" "{ ${ip} }" >/dev/null 2>&1; then
-                               printf "%s\n" "    IP found in set ${set}"
+                               printf "%s\n" "    IP found in Set '${set}'"
                                : >"${run_search}"
                        fi
                ) &
@@ -1162,8 +1225,29 @@ f_search() {
                cnt="$((cnt + 1))"
        done
        wait
-       [ ! -f "${run_search}" ] && printf "%s\n" "    IP not found"
-       rm -f "${run_search}"
+       if [ ! -f "${run_search}" ]; then
+               printf "%s\n" "    IP not found"
+       else
+               rm -f "${run_search}"
+       fi
+}
+
+# set survey
+#
+f_survey() {
+       local set_elements set="${1}"
+
+       f_system
+       [ -n "${set}" ] && set_elements="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]')"
+
+       if [ -z "${set}" ] || [ -z "${set_elements}" ]; then
+               printf "%s\n%s\n%s\n" ":::" "::: no valid survey input" ":::"
+               return
+       fi
+       printf "%s\n%s\n%s\n" ":::" "::: banIP Survey" ":::"
+       printf "%s\n" "    List the elements of Set '${set}' on $(date "+%Y-%m-%d %H:%M:%S")"
+       printf "%s\n" "    ---"
+       printf "%s\n" "${set_elements}"
 }
 
 # send status mails
index 33ac81b1e76cfdc105e2db7a3cea627ec3335c06..94c1d47edd70f3d3c3fe7ca737c1e00b3339515b 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# banIP main service script - ban incoming and outgoing ip adresses/subnets via sets in nftables
+# banIP main service script - ban incoming and outgoing ip addresses/subnets via sets in nftables
 # Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org)
 # This is free software, licensed under the GNU General Public License v3.
 
@@ -44,7 +44,7 @@ fi
 
 # init nft namespace
 #
-if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then
+if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then
        if f_nftinit "${ban_tmpfile}".init.nft; then
                f_log "info" "nft namespace initialized"
        else
@@ -174,7 +174,7 @@ if [ -x "${ban_logreadcmd}" ] && [ -n "${ban_logterm%%??}" ]; then
                                log_count="$(printf "%s\n" "${log_raw}" | grep -c "found '${ip}'")"
                                if [ "${log_count}" -ge "${ban_logcount}" ]; then
                                        if "${ban_nftcmd}" add element inet banIP "blocklist${proto}" "{ ${ip} ${nft_expiry} }" >/dev/null 2>&1; then
-                                               f_log "info" "added IP${proto} '${ip}' (${nft_expiry:-"-"}) to blocklist${proto} set"
+                                               f_log "info" "added IP${proto} '${ip}' (expiry: ${nft_expiry:-"-"}) to blocklist${proto} set"
                                                if [ "${ban_autoblocklist}" = "1" ] && ! grep -q "^${ip}" "${ban_blocklist}"; then
                                                        printf "%-42s%s\n" "${ip}" "# added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}"
                                                        f_log "info" "added IP${proto} '${ip}' to local blocklist"
index ce0a9cac1448b0dd8b91a6b14be43c6f32011790..eaa30989eaa38a6ef47d968bc9ab4dc4823c0c5c 100644 (file)
@@ -6,4 +6,4 @@ config banip 'global'
        list ban_logterm 'luci: failed login'
        list ban_logterm 'error: maximum authentication attempts exceeded'
        list ban_logterm 'sshd.*Connection closed by.*\[preauth\]'
-       list ban_logterm 'SecurityEvent=\"ChallengeResponseFailed\".*RemoteAddress='
+       list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress='
index 61639acfbd06fb6c6fbce9dc8e88c89bb84fd411..c56004279cfd5dc5656131858d92a55df9d33192 100755 (executable)
@@ -10,7 +10,8 @@ START=30
 USE_PROCD=1
 
 extra_command "report" "[text|json|mail] Print banIP related set statistics"
-extra_command "search" "[<IPv4 address>|<IPv6 address>] Check if an element exists in the banIP sets"
+extra_command "search" "[<IPv4 address>|<IPv6 address>] Check if an element exists in a banIP set"
+extra_command "survey" "[<set name>] List all elements of a given banIP set"
 
 ban_init="/etc/init.d/banip"
 ban_service="/usr/bin/banip-service.sh"
@@ -19,7 +20,7 @@ ban_pidfile="/var/run/banip.pid"
 ban_lock="/var/run/banip.lock"
 
 [ "${action}" = "stop" ] && ! /etc/init.d/banip running && exit 0
-[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "status" ]; } && exit 1
+[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "survey" ] || [ "${action}" = "status" ]; } && exit 1
 [ -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && exit 1
 [ ! -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && mkdir -p "${ban_lock}"
 
@@ -71,8 +72,10 @@ status() {
 }
 
 status_service() {
+       local actual="${1}"
+
        [ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
-       f_getstatus
+       [ -n "${actual}" ] && f_actual || f_getstatus
 }
 
 report() {
@@ -85,11 +88,16 @@ search() {
        f_search "${1}"
 }
 
+survey() {
+       [ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
+       f_survey "${1}"
+}
+
 service_triggers() {
        local iface trigger delay
 
        trigger="$(uci_get banip global ban_trigger)"
-       delay="$(uci_get banip global ban_triggerdelay "5")"
+       delay="$(uci_get banip global ban_triggerdelay "10")"
        PROCD_RELOAD_DELAY=$((delay * 1000))
 
        for iface in ${trigger}; do
diff --git a/net/cni-protocol/Makefile b/net/cni-protocol/Makefile
new file mode 100644 (file)
index 0000000..dbe1498
--- /dev/null
@@ -0,0 +1,51 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cni-protocol
+PKG_VERSION:=20230217
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/cni-protocol
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=cni netifd protocol
+  PKGARCH:=all
+endef
+
+define Package/cni-protocol/description
+  protocol support for cni networks for netifd
+  makes defining network for podman and other similar
+  systems using cni networking much easier and simpler.
+
+  with cni protocol support, on a network, where firewall
+  and portmapper management is disabled, you may control
+  firewalling with openwrt's default firewall configuration.
+
+  for example, create a container that hosts web content on
+  port 80 with static ip on your cni network, if your
+  network is 10.88.0.0/16, use for eg. 10.88.0.101 as
+  your containers static ip address. Create a zone, cni
+  to your firewall and add your interface to it.
+
+  Now you can easily set up redirectiong to 10.88.0.101:80
+  to expose it's port 80 to wan for serving your website.
+
+  Protocol has one setting: device, on podman this often
+  is cni-podman0.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/cni-protocol/install
+       $(INSTALL_DIR) $(1)/lib/netifd/proto
+       $(INSTALL_BIN) ./files/cni.sh $(1)/lib/netifd/proto/cni.sh
+endef
+
+$(eval $(call BuildPackage,cni-protocol))
diff --git a/net/cni-protocol/files/cni.sh b/net/cni-protocol/files/cni.sh
new file mode 100755 (executable)
index 0000000..c0cbc3b
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+       . /lib/functions.sh
+       . ../netifd-proto.sh
+       init_proto "$@"
+}
+
+proto_cni_init_config() {
+       no_device=0
+       available=0
+       no_proto_task=1
+       teardown_on_l3_link_down=1
+
+       proto_config_add_string "device:device"
+}
+
+proto_cni_setup() {
+
+       local cfg="$1"
+       local device ipaddr netmask broadcast route routemask routesrc
+
+       json_get_var device device
+
+       ipaddr=$(ip -4 -o a show "$device" | awk '{ print $4 }' | cut -d '/' -f1)
+       netmask=$(ip -4 -o a show "$device" | awk '{ print $4 }' | cut -d '/' -f2)
+       broadcast=$(ip -4 -o a show "$device" | awk '{ print $6 }')
+       route=$(ip -4 -o r show dev "$device" | awk '{ print $1 }' | cut -d '/' -f1)
+       routemask=$(ip -4 -o r show dev "$device" | awk '{ print $1 }' | cut -d '/' -f2)
+       routesrc=$(ip -4 -o r show dev "$device" | awk '{ print $7 }')
+
+       [ -z "$ipaddr" ] && {
+               echo "cni network $cfg does not have ip address"
+               proto_notify_error "$cfg" NO_IPADDRESS
+               return 1
+       }
+
+       proto_init_update "$device" 1
+       [ -n "$ipaddr" ] && proto_add_ipv4_address "$ipaddr" "$netmask" "$broadcast" ""
+       [ -n "$route" ] && proto_add_ipv4_route "$route" "$routemask" "" "$routesrc" ""
+       proto_send_update "$cfg"
+}
+
+proto_cni_teardown() {
+       local cfg="$1"
+       #proto_set_available "$cfg" 0
+       return 0
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+       add_protocol cni
+}
index d77066e9becb8d85a43773ddfa2828752a9d6e87..7adbac02c924a4df0a0b46e0e67187111613533c 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=frp
-PKG_VERSION:=0.46.1
+PKG_VERSION:=0.48.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/fatedier/frp/tar.gz/v${PKG_VERSION}?
-PKG_HASH:=af3e8d9d4144cf520cee2609cd45fb575afe711c03cc7441dc89d0402628a869
+PKG_HASH:=efba8ec9fad3369ce62631369f52b78a7248df426b5b54311e96231adac5cc76
 
 PKG_MAINTAINER:=Richard Yu <yurichard3839@gmail.com>
 PKG_LICENSE:=Apache-2.0
index e7f06edbd513d6b3573bd40d1eb01732abe6068c..68fe43c4e022a49e3e88203f888b05cd566469ee 100644 (file)
@@ -69,6 +69,7 @@ start_service() {
 
        procd_open_instance
        procd_set_param command "$PROG" -c "$conf_file"
+       procd_set_param file $conf_file
        procd_set_param stdout $stdout
        procd_set_param stderr $stderr
        [ -n "$user" ] && procd_set_param user "$user"
@@ -77,8 +78,3 @@ start_service() {
        [ -n "$env" ] && config_list_foreach "$init_cfg" env "procd_append_param env"
        procd_close_instance
 }
-
-reload_service() {
-       stop
-       start
-}
index b87525cd2a3a107331590d5da797a7907a0e1f6f..38f714fb1bed6a69cac1a389f3a70d032a8a9c21 100644 (file)
@@ -67,6 +67,7 @@ start_service() {
 
        procd_open_instance
        procd_set_param command "$PROG" -c "$conf_file"
+       procd_set_param file $conf_file
        procd_set_param stdout $stdout
        procd_set_param stderr $stderr
        [ -n "$user" ] && procd_set_param user "$user"
@@ -75,8 +76,3 @@ start_service() {
        [ -n "$env" ] && config_list_foreach "$init_cfg" env "procd_append_param env"
        procd_close_instance
 }
-
-reload_service() {
-       stop
-       start
-}
index 5c5189c48ecc3f89ae0e6f90aab7c71584ab2eec..bf84d48de5f77b2d29191498d18c7050beec6342 100644 (file)
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=haproxy
-PKG_VERSION:=2.6.8
+PKG_VERSION:=2.6.9
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.haproxy.org/download/2.6/src
-PKG_HASH:=a02ad64550dd30a94b25fd0e225ba699649d0c4037bca3b36b20e8e3235bb86f
+PKG_HASH:=f01a1c5f465dc1b5cd175d0b28b98beb4dfe82b5b5b63ddcc68d1df433641701
 
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
                Christian Lachner <gladiac@gmail.com>
index afd83a13adf7f5273445b860e3b28f30573a8e14..8c17d3e4f83fa1127d2c4ebeab6530133bd78e03 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 CLONEURL=https://git.haproxy.org/git/haproxy-2.6.git
-BASE_TAG=v2.6.8
+BASE_TAG=v2.6.9
 TMP_REPODIR=tmprepo
 PATCHESDIR=patches
 
index 734dcb5419b266b512ac6f9af5fe36e45497e933..1612bd0d2188788240e9f2c6f05a6c7eb6d75848 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ksmbd-tools
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/cifsd-team/ksmbd-tools
-PKG_SOURCE_VERSION:=3.4.6
-PKG_MIRROR_HASH:=c78dace3320cf8a273738b8f3e67bed24c812695f2fab2fbaeae06ec8a15cb77
+PKG_SOURCE_VERSION:=3.4.7
+PKG_MIRROR_HASH:=9128ecac1a2c463e689ed42fd71952a0eafe956f8bcd1b04af58c7bc66a8baee
 
 PKG_LICENSE:=GPL-2.0-or-later
 PKG_LICENSE_FILES:=COPYING
diff --git a/net/ksmbd-tools/patches/010-muon.patch b/net/ksmbd-tools/patches/010-muon.patch
deleted file mode 100644 (file)
index 967c927..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From 3281f325c820a72057ea639e0d11ad68d5703b43 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Thu, 6 Oct 2022 18:07:01 -0700
-Subject: [PATCH] ksmbd-tools: run meson through muon analyze
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Mostly unused variable removals. Removed pointless [] in
-include_directories.
-
-Signed-off-by: Rosen Penev <rosenp@gmail.com>
-Acked-by: Atte Heikkilä <atteh.mailbox@gmail.com>
-Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
----
- addshare/meson.build | 2 +-
- adduser/meson.build  | 2 +-
- control/meson.build  | 2 +-
- meson.build          | 4 ++--
- mountd/meson.build   | 2 +-
- 5 files changed, 6 insertions(+), 6 deletions(-)
-
---- a/addshare/meson.build
-+++ b/addshare/meson.build
-@@ -1,4 +1,4 @@
--addshare = executable(
-+executable(
-   'ksmbd.addshare',
-   'share_admin.c',
-   'addshare.c',
---- a/adduser/meson.build
-+++ b/adduser/meson.build
-@@ -1,4 +1,4 @@
--adduser = executable(
-+executable(
-   'ksmbd.adduser',
-   'md4_hash.c',
-   'user_admin.c',
---- a/control/meson.build
-+++ b/control/meson.build
-@@ -1,4 +1,4 @@
--control = executable(
-+executable(
-   'ksmbd.control',
-   'control.c',
-   dependencies: [
---- a/meson.build
-+++ b/meson.build
-@@ -13,10 +13,10 @@ exec awk '/define KSMBD_TOOLS_VERSION /
-   meson_version: '>= 0.51.0',
- )
--tools_incdir = include_directories([
-+tools_incdir = include_directories(
-   '.',
-   'include',
--])
-+)
- glib_dep = dependency(
-   'glib-2.0',
---- a/mountd/meson.build
-+++ b/mountd/meson.build
-@@ -1,4 +1,4 @@
--mountd = executable(
-+executable(
-   'ksmbd.mountd',
-   'worker.c',
-   'ipc.c',
diff --git a/net/ksmbd-tools/patches/020-meson.patch b/net/ksmbd-tools/patches/020-meson.patch
deleted file mode 100644 (file)
index adc01b6..0000000
+++ /dev/null
@@ -1,9190 +0,0 @@
-From 6b74583bd62e2b6ed6b76ff72d8fc7c2d8f26510 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Atte=20Heikkil=C3=A4?= <atteh.mailbox@gmail.com>
-Date: Thu, 13 Oct 2022 20:08:47 +0300
-Subject: [PATCH] ksmbd-tools: build utilities as a single binary
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rather than have four different binaries, i.e. ksmbd.addshare,
-ksmbd.adduser, ksmbd.control, and ksmbd.mountd, each one including
-its own libksmbdtools.a copy, build them instead as a single binary.
-This resulting ksmbd.tools acts like BusyBox in that its behavior
-depends on the name by which it is called. Then, each utility is made
-into a symlink to it, meaning that users keep using the utilities as
-usual. ksmbd.tools itself is installed to libexecdir as it is not
-something the user should run.
-
-Instead of libksmbdtools.a, each utility becomes its own static
-library, i.e. libaddshare.a, libadduser.a, libcontrol.a, libmountd.a,
-which are all linked to the single binary. Note that the single binary
-approach is also beneficial when statically linking to any of the
-external dependencies, e.g. GLib, as it greatly reduces the overall
-binary size when there is overlap in copies otherwise made separately
-for multiple utilities.
-
-Due to install_symlink(), minimum meson version is bumped to 0.62.1,
-meaning that it has to be installed using `pip' in Travis, since no
-Ubuntu release currently packages that version or newer. However, bump
-to Ubuntu Jammy anyways, just for the sake of building against newer
-versions of ksmbd-tools' dependencies.
-
-Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
----
- .travis.yml                             |  6 ++++--
- Makefile.am                             |  2 +-
- addshare/Makefile.am                    | 15 ++++++++-----
- addshare/addshare.c                     |  4 ++--
- addshare/meson.build                    | 22 ++++++++++---------
- addshare/share_admin.c                  |  2 +-
- adduser/Makefile.am                     | 16 ++++++++------
- adduser/adduser.c                       |  4 ++--
- adduser/meson.build                     | 22 ++++++++++---------
- adduser/user_admin.c                    |  2 +-
- configure.ac                            |  8 ++++---
- control/Makefile.am                     | 15 ++++++++-----
- control/control.c                       |  4 ++--
- control/meson.build                     | 22 ++++++++++---------
- include/{ksmbdtools.h => tools.h}       | 11 +++++++---
- ksmbd-tools.spec                        |  3 ++-
- meson.build                             |  6 +++---
- mountd/Makefile.am                      | 17 +++++++++------
- mountd/ipc.c                            |  2 +-
- mountd/meson.build                      | 23 +++++++++++---------
- mountd/mountd.c                         |  4 ++--
- mountd/rpc.c                            |  2 +-
- mountd/rpc_lsarpc.c                     |  2 +-
- mountd/rpc_samr.c                       |  2 +-
- mountd/rpc_srvsvc.c                     |  2 +-
- mountd/rpc_wkssvc.c                     |  2 +-
- mountd/smbacl.c                         |  2 +-
- mountd/worker.c                         |  2 +-
- {lib => tools}/Makefile.am              | 15 +++++++------
- {lib => tools}/asn1.c                   |  0
- {lib => tools}/config_parser.c          |  2 +-
- {lib => tools}/management/session.c     |  2 +-
- {lib => tools}/management/share.c       |  2 +-
- {lib => tools}/management/spnego.c      |  2 +-
- {lib => tools}/management/spnego_krb5.c |  2 +-
- {lib => tools}/management/spnego_mech.h |  0
- {lib => tools}/management/tree_conn.c   |  2 +-
- {lib => tools}/management/user.c        |  2 +-
- {lib => tools}/meson.build              | 28 ++++++++++++++++---------
- lib/ksmbdtools.c => tools/tools.c       | 27 +++++++++++++++++++++++-
- 40 files changed, 191 insertions(+), 117 deletions(-)
- rename include/{ksmbdtools.h => tools.h} (94%)
- rename {lib => tools}/Makefile.am (53%)
- rename {lib => tools}/asn1.c (100%)
- rename {lib => tools}/config_parser.c (99%)
- rename {lib => tools}/management/session.c (99%)
- rename {lib => tools}/management/share.c (99%)
- rename {lib => tools}/management/spnego.c (99%)
- rename {lib => tools}/management/spnego_krb5.c (99%)
- rename {lib => tools}/management/spnego_mech.h (100%)
- rename {lib => tools}/management/tree_conn.c (99%)
- rename {lib => tools}/management/user.c (99%)
- rename {lib => tools}/meson.build (60%)
- rename lib/ksmbdtools.c => tools/tools.c (89%)
-
---- a/.travis.yml
-+++ b/.travis.yml
-@@ -1,4 +1,4 @@
--dist: focal
-+dist: jammy
- language: c
-@@ -6,9 +6,11 @@ notifications:
-  - email: true
- before_install:
-- - sudo apt-get install libnl-3-dev libnl-genl-3-dev krb5-multidev heimdal-multidev meson
-+ - sudo apt-get install libnl-3-dev libnl-genl-3-dev krb5-multidev heimdal-multidev ninja-build
-  - gcc --version
-  - g++ --version
-+ - pip3 install --user meson
-+ - PATH=$HOME/.local/bin:$PATH
- jobs:
-  include:
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -1,6 +1,6 @@
- ACLOCAL_AMFLAGS = -I m4
--SUBDIRS = lib mountd adduser addshare control
-+SUBDIRS = addshare adduser control mountd tools
- EXTRA_DIST = include \
-              README.md \
---- a/addshare/Makefile.am
-+++ b/addshare/Makefile.am
-@@ -1,11 +1,8 @@
- AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
-             -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common
--LIBS = $(GLIB_LIBS)
--ksmbd_addshare_LDADD = $(top_builddir)/lib/libksmbdtools.a
--sbin_PROGRAMS = ksmbd.addshare
--
--ksmbd_addshare_SOURCES = share_admin.c addshare.c share_admin.h
-+noinst_LIBRARIES = libaddshare.a
-+libaddshare_a_SOURCES = share_admin.c addshare.c share_admin.h
- EXTRA_DIST = ksmbd.addshare.8.in
-@@ -13,3 +10,11 @@ man_MANS = ksmbd.addshare.8
- $(man_MANS): %: %.in; @$(in_script) $< >$@
- CLEANFILES = $(man_MANS)
-+
-+install-exec-hook: uninstall-hook
-+      $(MKDIR_P) $(DESTDIR)$(sbindir)
-+      ( cd $(DESTDIR)$(sbindir) && \
-+        $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.addshare )
-+
-+uninstall-hook:
-+      -rm $(DESTDIR)$(sbindir)/ksmbd.addshare
---- a/addshare/addshare.c
-+++ b/addshare/addshare.c
-@@ -18,7 +18,7 @@
- #include <ctype.h>
- #include "config_parser.h"
--#include "ksmbdtools.h"
-+#include "tools.h"
- #include "management/share.h"
- #include "linux/ksmbd_server.h"
- #include "share_admin.h"
-@@ -111,7 +111,7 @@ static int sanity_check_share_name_simpl
-       return 0;
- }
--int main(int argc, char *argv[])
-+int addshare_main(int argc, char **argv)
- {
-       int ret = -EINVAL;
-       char *share = NULL, *options = NULL, *smbconf = NULL;
---- a/addshare/meson.build
-+++ b/addshare/meson.build
-@@ -1,20 +1,16 @@
--executable(
--  'ksmbd.addshare',
-+addshare_lib = static_library(
-+  'addshare',
-   'share_admin.c',
-   'addshare.c',
-   'share_admin.h',
--  dependencies: [
--    glib_dep,
--    libnl_dep,
--  ],
--  include_directories: tools_incdir,
--  link_with: libksmbdtools,
--  install: true,
--  install_dir: get_option('sbindir'),
-+  include_directories: include_dirs,
-   c_args: [
-     '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
-     '-DRUNSTATEDIR="@0@"'.format(runstatedir),
-   ],
-+  dependencies: [
-+    glib_dep,
-+  ],
- )
- configure_file(
-@@ -23,3 +19,9 @@ configure_file(
-   install_dir: get_option('mandir') / 'man8',
-   configuration: in_data,
- )
-+
-+install_symlink(
-+  'ksmbd.addshare',
-+  install_dir: get_option('sbindir'),
-+  pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools',
-+)
---- a/addshare/share_admin.c
-+++ b/addshare/share_admin.c
-@@ -14,7 +14,7 @@
- #include <fcntl.h>
- #include <config_parser.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #include <management/share.h>
---- a/adduser/Makefile.am
-+++ b/adduser/Makefile.am
-@@ -1,12 +1,8 @@
- AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
-             -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common
--LIBS = $(GLIB_LIBS)
--ksmbd_adduser_LDADD = $(top_builddir)/lib/libksmbdtools.a
--sbin_PROGRAMS = ksmbd.adduser
--
--ksmbd_adduser_SOURCES = md4_hash.c user_admin.c adduser.c md4_hash.h \
--                        user_admin.h
-+noinst_LIBRARIES = libadduser.a
-+libadduser_a_SOURCES = md4_hash.c user_admin.c adduser.c md4_hash.h user_admin.h
- EXTRA_DIST = ksmbd.adduser.8.in
-@@ -14,3 +10,11 @@ man_MANS = ksmbd.adduser.8
- $(man_MANS): %: %.in; @$(in_script) $< >$@
- CLEANFILES = $(man_MANS)
-+
-+install-exec-hook: uninstall-hook
-+      $(MKDIR_P) $(DESTDIR)$(sbindir)
-+      ( cd $(DESTDIR)$(sbindir) && \
-+        $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.adduser )
-+
-+uninstall-hook:
-+      -rm $(DESTDIR)$(sbindir)/ksmbd.adduser
---- a/adduser/adduser.c
-+++ b/adduser/adduser.c
-@@ -18,7 +18,7 @@
- #include <ctype.h>
- #include "config_parser.h"
--#include "ksmbdtools.h"
-+#include "tools.h"
- #include "management/user.h"
- #include "management/share.h"
- #include "user_admin.h"
-@@ -121,7 +121,7 @@ static int sanity_check_user_name_simple
-       return 0;
- }
--int main(int argc, char *argv[])
-+int adduser_main(int argc, char **argv)
- {
-       int ret = -EINVAL;
-       char *account = NULL, *password = NULL, *pwddb = NULL, *smbconf = NULL;
---- a/adduser/meson.build
-+++ b/adduser/meson.build
-@@ -1,22 +1,18 @@
--executable(
--  'ksmbd.adduser',
-+adduser_lib = static_library(
-+  'adduser',
-   'md4_hash.c',
-   'user_admin.c',
-   'adduser.c',
-   'md4_hash.h',
-   'user_admin.h',
--  dependencies: [
--    glib_dep,
--    libnl_dep,
--  ],
--  include_directories: tools_incdir,
--  link_with: libksmbdtools,
--  install: true,
--  install_dir: get_option('sbindir'),
-+  include_directories: include_dirs,
-   c_args: [
-     '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
-     '-DRUNSTATEDIR="@0@"'.format(runstatedir),
-   ],
-+  dependencies: [
-+    glib_dep,
-+  ],
- )
- configure_file(
-@@ -25,3 +21,9 @@ configure_file(
-   install_dir: get_option('mandir') / 'man8',
-   configuration: in_data,
- )
-+
-+install_symlink(
-+  'ksmbd.adduser',
-+  install_dir: get_option('sbindir'),
-+  pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools',
-+)
---- a/adduser/user_admin.c
-+++ b/adduser/user_admin.c
-@@ -15,7 +15,7 @@
- #include <termios.h>
- #include <config_parser.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #include <md4_hash.h>
- #include <user_admin.h>
---- a/configure.ac
-+++ b/configure.ac
-@@ -24,6 +24,8 @@ AC_PROG_CC_STDC
- AM_SILENT_RULES([yes])
- AC_PROG_LIBTOOL
- AC_PROG_SED
-+AC_PROG_MKDIR_P
-+AC_PROG_LN_S
- AC_SUBST([in_script], [[\
- '$(SED) -e "s,[@]sbindir[@],$(sbindir),g" \
-@@ -143,11 +145,11 @@ AM_CONDITIONAL(HAVE_LIBKRB5, [test "x$en
- AC_CONFIG_FILES([
-       Makefile
--      lib/Makefile
--      mountd/Makefile
--      adduser/Makefile
-       addshare/Makefile
-+      adduser/Makefile
-       control/Makefile
-+      mountd/Makefile
-+      tools/Makefile
- ])
- AC_OUTPUT
---- a/control/Makefile.am
-+++ b/control/Makefile.am
-@@ -1,11 +1,8 @@
- AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
-             -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common
--LIBS = $(GLIB_LIBS)
--ksmbd_control_LDADD = $(top_builddir)/lib/libksmbdtools.a
--sbin_PROGRAMS = ksmbd.control
--
--ksmbd_control_SOURCES = control.c
-+noinst_LIBRARIES = libcontrol.a
-+libcontrol_a_SOURCES = control.c
- EXTRA_DIST = ksmbd.control.8.in
-@@ -13,3 +10,11 @@ man_MANS = ksmbd.control.8
- $(man_MANS): %: %.in; @$(in_script) $< >$@
- CLEANFILES = $(man_MANS)
-+
-+install-exec-hook: uninstall-hook
-+      $(MKDIR_P) $(DESTDIR)$(sbindir)
-+      ( cd $(DESTDIR)$(sbindir) && \
-+        $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.control )
-+
-+uninstall-hook:
-+      -rm $(DESTDIR)$(sbindir)/ksmbd.control
---- a/control/control.c
-+++ b/control/control.c
-@@ -9,7 +9,7 @@
- #include <fcntl.h>
- #include <errno.h>
--#include "ksmbdtools.h"
-+#include "tools.h"
- #include "version.h"
- static void usage(int status)
-@@ -146,7 +146,7 @@ out:
-       return ret;
- }
--int main(int argc, char *argv[])
-+int control_main(int argc, char **argv)
- {
-       int ret = -EINVAL;
-       int c;
---- a/control/meson.build
-+++ b/control/meson.build
-@@ -1,18 +1,14 @@
--executable(
--  'ksmbd.control',
-+control_lib = static_library(
-+  'control',
-   'control.c',
--  dependencies: [
--    glib_dep,
--    libnl_dep,
--  ],
--  include_directories: tools_incdir,
--  link_with: libksmbdtools,
--  install: true,
--  install_dir: get_option('sbindir'),
-+  include_directories: include_dirs,
-   c_args: [
-     '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
-     '-DRUNSTATEDIR="@0@"'.format(runstatedir),
-   ],
-+  dependencies: [
-+    glib_dep,
-+  ],
- )
- configure_file(
-@@ -21,3 +17,9 @@ configure_file(
-   install_dir: get_option('mandir') / 'man8',
-   configuration: in_data,
- )
-+
-+install_symlink(
-+  'ksmbd.control',
-+  install_dir: get_option('sbindir'),
-+  pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools',
-+)
---- a/include/ksmbdtools.h
-+++ /dev/null
-@@ -1,172 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-or-later */
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#ifndef __KSMBDTOOLS_H__
--#define __KSMBDTOOLS_H__
--
--#ifndef _GNU_SOURCE
--#define _GNU_SOURCE 1
--#endif
--
--#include <errno.h>
--#include <getopt.h>
--#include <glib.h>
--#include <poll.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <string.h>
--#include <sys/types.h>
--#include <sys/wait.h>
--#include <time.h>
--#include <unistd.h>
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif
--
--struct smbconf_global {
--      int                     flags;
--      int                     map_to_guest;
--      char                    *guest_account;
--
--      char                    *server_string;
--      char                    *work_group;
--      char                    *netbios_name;
--      char                    *server_min_protocol;
--      char                    *server_max_protocol;
--      char                    *root_dir;
--      int                     server_signing;
--      int                     sessions_cap;
--      int                     restrict_anon;
--      unsigned short          tcp_port;
--      unsigned short          ipc_timeout;
--      unsigned int            deadtime;
--      int                     bind_interfaces_only;
--      char                    **interfaces;
--      unsigned long           file_max;
--      unsigned int            smb2_max_read;
--      unsigned int            smb2_max_write;
--      unsigned int            smb2_max_trans;
--      unsigned int            smb2_max_credits;
--      unsigned int            smbd_max_io_size;
--      unsigned int            share_fake_fscaps;
--      unsigned int            gen_subauth[3];
--      char                    *krb5_keytab_file;
--      char                    *krb5_service_name;
--      char                    *pwddb;
--      char                    *smbconf;
--};
--
--#define KSMBD_LOCK_FILE               RUNSTATEDIR "/ksmbd.lock"
--
--#define KSMBD_RESTRICT_ANON_TYPE_1    1
--#define KSMBD_RESTRICT_ANON_TYPE_2    2
--
--extern struct smbconf_global global_conf;
--
--#define KSMBD_CONF_MAP_TO_GUEST_NEVER         (0)
--#define KSMBD_CONF_MAP_TO_GUEST_BAD_USER      (1 << 0)
--#define KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD  (1 << 1)
--#define KSMBD_CONF_MAP_TO_GUEST_BAD_UID               (1 << 2)
--
--#define KSMBD_CONF_DEFAULT_NETBIOS_NAME       "KSMBD SERVER"
--#define KSMBD_CONF_DEFAULT_SERVER_STRING      "SMB SERVER"
--#define KSMBD_CONF_DEFAULT_WORK_GROUP         "WORKGROUP"
--
--#define KSMBD_CONF_DEFAULT_GUEST_ACCOUNT      "nobody"
--
--#define KSMBD_CONF_DEFAULT_SESS_CAP   1024
--#define KSMBD_CONF_DEFAULT_TCP_PORT   445
--
--#define KSMBD_CONF_FILE_MAX           10000
--
--#define PATH_PWDDB            SYSCONFDIR "/ksmbd/ksmbdpwd.db"
--#define PATH_SMBCONF          SYSCONFDIR "/ksmbd/ksmbd.conf"
--#define PATH_SMBCONF_FALLBACK SYSCONFDIR "/ksmbd/smb.conf"
--#define PATH_SUBAUTH          SYSCONFDIR "/ksmbd/ksmbd.subauth"
--
--#define KSMBD_HEALTH_START            (0)
--#define KSMBD_HEALTH_RUNNING          (1 << 0)
--#define KSMBD_SHOULD_RELOAD_CONFIG    (1 << 1)
--
--extern int ksmbd_health_status;
--
--#define TRACING_DUMP_NL_MSG   0
--
--#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
--
--#define STR_HELPER(x) #x
--#define STR(x) STR_HELPER(x)
--
--//---------------------------------------------------------------//
--#define LOGAPP                "[%s/%d]:"
--#define PRERR         LOGAPP" ERROR: "
--#define PRINF         LOGAPP" INFO: "
--#define PRDEBUG               LOGAPP" DEBUG: "
--
--#define PR_ERROR      0
--#define PR_INFO               1
--#define PR_DEBUG      2
--
--extern int log_level;
--
--#define PR_LOGGER_STDIO         0
--#define PR_LOGGER_SYSLOG        1
--
--G_GNUC_PRINTF(2, 3)
--extern void __pr_log(int level, const char *fmt, ...);
--extern void set_logger_app_name(const char *an);
--extern const char *get_logger_app_name(void);
--extern void pr_logger_init(int flags);
--extern int set_log_level(int level);
--
--#define pr_log(l, f, ...)                                             \
--      do {                                                            \
--              if ((l) <= log_level)                                   \
--                      __pr_log((l), (f), get_logger_app_name(),       \
--                                      getpid(),                       \
--                                      ##__VA_ARGS__);                 \
--      } while (0)
--
--#define pr_debug(f, ...)      \
--      pr_log(PR_DEBUG, PRDEBUG f, ##__VA_ARGS__)
--#define pr_info(f, ...)       \
--      pr_log(PR_INFO, PRINF f, ##__VA_ARGS__)
--#define pr_err(f, ...)        \
--      pr_log(PR_ERROR, PRERR f, ##__VA_ARGS__)
--
--//---------------------------------------------------------------//
--
--void pr_hex_dump(const void *mem, size_t sz);
--
--char *base64_encode(unsigned char *src, size_t srclen);
--unsigned char *base64_decode(char const *src, size_t *dstlen);
--
--gchar *ksmbd_gconvert(const gchar *str,
--                    gssize       str_len,
--                    int          to_codeset,
--                    int          from_codeset,
--                    gsize       *bytes_read,
--                    gsize       *bytes_written);
--
--enum charset_idx {
--      KSMBD_CHARSET_UTF8              = 0,
--      KSMBD_CHARSET_UTF16LE,
--      KSMBD_CHARSET_UCS2LE,
--      KSMBD_CHARSET_UTF16BE,
--      KSMBD_CHARSET_UCS2BE,
--      KSMBD_CHARSET_MAX               = 5,
--};
--
--#define KSMBD_CHARSET_DEFAULT         KSMBD_CHARSET_UTF8
--
--extern char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1];
--
--int send_signal_to_ksmbd_mountd(int signo);
--int test_file_access(char *conf);
--
--#endif /* __KSMBDTOOLS_H__ */
---- /dev/null
-+++ b/include/tools.h
-@@ -0,0 +1,177 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#ifndef __TOOLS_H__
-+#define __TOOLS_H__
-+
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE 1
-+#endif
-+
-+#include <errno.h>
-+#include <getopt.h>
-+#include <glib.h>
-+#include <poll.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <time.h>
-+#include <unistd.h>
-+
-+#ifdef HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+
-+struct smbconf_global {
-+      int                     flags;
-+      int                     map_to_guest;
-+      char                    *guest_account;
-+
-+      char                    *server_string;
-+      char                    *work_group;
-+      char                    *netbios_name;
-+      char                    *server_min_protocol;
-+      char                    *server_max_protocol;
-+      char                    *root_dir;
-+      int                     server_signing;
-+      int                     sessions_cap;
-+      int                     restrict_anon;
-+      unsigned short          tcp_port;
-+      unsigned short          ipc_timeout;
-+      unsigned int            deadtime;
-+      int                     bind_interfaces_only;
-+      char                    **interfaces;
-+      unsigned long           file_max;
-+      unsigned int            smb2_max_read;
-+      unsigned int            smb2_max_write;
-+      unsigned int            smb2_max_trans;
-+      unsigned int            smb2_max_credits;
-+      unsigned int            smbd_max_io_size;
-+      unsigned int            share_fake_fscaps;
-+      unsigned int            gen_subauth[3];
-+      char                    *krb5_keytab_file;
-+      char                    *krb5_service_name;
-+      char                    *pwddb;
-+      char                    *smbconf;
-+};
-+
-+#define KSMBD_LOCK_FILE               RUNSTATEDIR "/ksmbd.lock"
-+
-+#define KSMBD_RESTRICT_ANON_TYPE_1    1
-+#define KSMBD_RESTRICT_ANON_TYPE_2    2
-+
-+extern struct smbconf_global global_conf;
-+
-+#define KSMBD_CONF_MAP_TO_GUEST_NEVER         (0)
-+#define KSMBD_CONF_MAP_TO_GUEST_BAD_USER      (1 << 0)
-+#define KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD  (1 << 1)
-+#define KSMBD_CONF_MAP_TO_GUEST_BAD_UID               (1 << 2)
-+
-+#define KSMBD_CONF_DEFAULT_NETBIOS_NAME       "KSMBD SERVER"
-+#define KSMBD_CONF_DEFAULT_SERVER_STRING      "SMB SERVER"
-+#define KSMBD_CONF_DEFAULT_WORK_GROUP         "WORKGROUP"
-+
-+#define KSMBD_CONF_DEFAULT_GUEST_ACCOUNT      "nobody"
-+
-+#define KSMBD_CONF_DEFAULT_SESS_CAP   1024
-+#define KSMBD_CONF_DEFAULT_TCP_PORT   445
-+
-+#define KSMBD_CONF_FILE_MAX           10000
-+
-+#define PATH_PWDDB            SYSCONFDIR "/ksmbd/ksmbdpwd.db"
-+#define PATH_SMBCONF          SYSCONFDIR "/ksmbd/ksmbd.conf"
-+#define PATH_SMBCONF_FALLBACK SYSCONFDIR "/ksmbd/smb.conf"
-+#define PATH_SUBAUTH          SYSCONFDIR "/ksmbd/ksmbd.subauth"
-+
-+#define KSMBD_HEALTH_START            (0)
-+#define KSMBD_HEALTH_RUNNING          (1 << 0)
-+#define KSMBD_SHOULD_RELOAD_CONFIG    (1 << 1)
-+
-+extern int ksmbd_health_status;
-+
-+#define TRACING_DUMP_NL_MSG   0
-+
-+#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
-+
-+#define STR_HELPER(x) #x
-+#define STR(x) STR_HELPER(x)
-+
-+//---------------------------------------------------------------//
-+#define LOGAPP                "[%s/%d]:"
-+#define PRERR         LOGAPP" ERROR: "
-+#define PRINF         LOGAPP" INFO: "
-+#define PRDEBUG               LOGAPP" DEBUG: "
-+
-+#define PR_ERROR      0
-+#define PR_INFO               1
-+#define PR_DEBUG      2
-+
-+extern int log_level;
-+
-+#define PR_LOGGER_STDIO         0
-+#define PR_LOGGER_SYSLOG        1
-+
-+G_GNUC_PRINTF(2, 3)
-+extern void __pr_log(int level, const char *fmt, ...);
-+extern void set_logger_app_name(const char *an);
-+extern const char *get_logger_app_name(void);
-+extern void pr_logger_init(int flags);
-+extern int set_log_level(int level);
-+
-+#define pr_log(l, f, ...)                                             \
-+      do {                                                            \
-+              if ((l) <= log_level)                                   \
-+                      __pr_log((l), (f), get_logger_app_name(),       \
-+                                      getpid(),                       \
-+                                      ##__VA_ARGS__);                 \
-+      } while (0)
-+
-+#define pr_debug(f, ...)      \
-+      pr_log(PR_DEBUG, PRDEBUG f, ##__VA_ARGS__)
-+#define pr_info(f, ...)       \
-+      pr_log(PR_INFO, PRINF f, ##__VA_ARGS__)
-+#define pr_err(f, ...)        \
-+      pr_log(PR_ERROR, PRERR f, ##__VA_ARGS__)
-+
-+//---------------------------------------------------------------//
-+
-+void pr_hex_dump(const void *mem, size_t sz);
-+
-+char *base64_encode(unsigned char *src, size_t srclen);
-+unsigned char *base64_decode(char const *src, size_t *dstlen);
-+
-+gchar *ksmbd_gconvert(const gchar *str,
-+                    gssize       str_len,
-+                    int          to_codeset,
-+                    int          from_codeset,
-+                    gsize       *bytes_read,
-+                    gsize       *bytes_written);
-+
-+enum charset_idx {
-+      KSMBD_CHARSET_UTF8              = 0,
-+      KSMBD_CHARSET_UTF16LE,
-+      KSMBD_CHARSET_UCS2LE,
-+      KSMBD_CHARSET_UTF16BE,
-+      KSMBD_CHARSET_UCS2BE,
-+      KSMBD_CHARSET_MAX               = 5,
-+};
-+
-+#define KSMBD_CHARSET_DEFAULT         KSMBD_CHARSET_UTF8
-+
-+extern char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1];
-+
-+int send_signal_to_ksmbd_mountd(int signo);
-+int test_file_access(char *conf);
-+
-+int addshare_main(int argc, char **argv);
-+int adduser_main(int argc, char **argv);
-+int control_main(int argc, char **argv);
-+int mountd_main(int argc, char **argv);
-+
-+#endif /* __TOOLS_H__ */
---- a/ksmbd-tools.spec
-+++ b/ksmbd-tools.spec
-@@ -16,7 +16,7 @@
- #
- Name:           ksmbd-tools
--Version:        3.4.6
-+Version:        master
- Release:        0
- Summary:        ksmbd kernel server userspace utilities
- License:        GPL-2.0-or-later
-@@ -53,6 +53,7 @@ make %{?_smp_mflags}
- %{_sbindir}/ksmbd.adduser
- %{_sbindir}/ksmbd.control
- %{_sbindir}/ksmbd.mountd
-+%{_libexecdir}/ksmbd.tools
- %{_mandir}/man8/ksmbd.addshare.8*
- %{_mandir}/man8/ksmbd.adduser.8*
- %{_mandir}/man8/ksmbd.control.8*
---- a/meson.build
-+++ b/meson.build
-@@ -10,10 +10,10 @@ exec awk '/define KSMBD_TOOLS_VERSION /
-     check: true,
-   ).stdout(),
-   default_options: 'c_std=gnu99',
--  meson_version: '>= 0.51.0',
-+  meson_version: '>= 0.61.5',
- )
--tools_incdir = include_directories(
-+include_dirs = include_directories(
-   '.',
-   'include',
- )
-@@ -151,8 +151,8 @@ configure_file(
-   configuration: in_data,
- )
--subdir('lib')
- subdir('addshare')
- subdir('adduser')
- subdir('control')
- subdir('mountd')
-+subdir('tools')
---- a/mountd/Makefile.am
-+++ b/mountd/Makefile.am
-@@ -1,12 +1,9 @@
- AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
-             -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common
--LIBS = $(GLIB_LIBS) $(LIBNL_LIBS) $(LIBKRB5_LIBS)
--ksmbd_mountd_LDADD = $(top_builddir)/lib/libksmbdtools.a
--sbin_PROGRAMS = ksmbd.mountd
--
--ksmbd_mountd_SOURCES = worker.c ipc.c rpc.c rpc_srvsvc.c rpc_wkssvc.c \
--                       mountd.c smbacl.c rpc_samr.c rpc_lsarpc.c
-+noinst_LIBRARIES = libmountd.a
-+libmountd_a_SOURCES = worker.c ipc.c rpc.c rpc_srvsvc.c rpc_wkssvc.c mountd.c \
-+                      smbacl.c rpc_samr.c rpc_lsarpc.c
- EXTRA_DIST = ksmbd.mountd.8.in
-@@ -14,3 +11,11 @@ man_MANS = ksmbd.mountd.8
- $(man_MANS): %: %.in; @$(in_script) $< >$@
- CLEANFILES = $(man_MANS)
-+
-+install-exec-hook: uninstall-hook
-+      $(MKDIR_P) $(DESTDIR)$(sbindir)
-+      ( cd $(DESTDIR)$(sbindir) && \
-+        $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.mountd )
-+
-+uninstall-hook:
-+      -rm $(DESTDIR)$(sbindir)/ksmbd.mountd
---- a/mountd/ipc.c
-+++ b/mountd/ipc.c
-@@ -17,7 +17,7 @@
- #include <linux/ksmbd_server.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #include <ipc.h>
- #include <worker.h>
- #include <config_parser.h>
---- a/mountd/meson.build
-+++ b/mountd/meson.build
-@@ -1,5 +1,5 @@
--executable(
--  'ksmbd.mountd',
-+mountd_lib = static_library(
-+  'mountd',
-   'worker.c',
-   'ipc.c',
-   'rpc.c',
-@@ -9,18 +9,15 @@ executable(
-   'smbacl.c',
-   'rpc_samr.c',
-   'rpc_lsarpc.c',
--  dependencies: [
--    glib_dep,
--    libnl_dep,
--  ],
--  include_directories: tools_incdir,
--  link_with: libksmbdtools,
--  install: true,
--  install_dir: get_option('sbindir'),
-+  include_directories: include_dirs,
-   c_args: [
-     '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
-     '-DRUNSTATEDIR="@0@"'.format(runstatedir),
-   ],
-+  dependencies: [
-+    glib_dep,
-+    libnl_dep,
-+  ],
- )
- configure_file(
-@@ -29,3 +26,9 @@ configure_file(
-   install_dir: get_option('mandir') / 'man8',
-   configuration: in_data,
- )
-+
-+install_symlink(
-+  'ksmbd.mountd',
-+  install_dir: get_option('sbindir'),
-+  pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools',
-+)
---- a/mountd/mountd.c
-+++ b/mountd/mountd.c
-@@ -5,7 +5,7 @@
-  *   linux-cifsd-devel@lists.sourceforge.net
-  */
--#include <ksmbdtools.h>
-+#include <tools.h>
- #ifndef _GNU_SOURCE
- #define _GNU_SOURCE
-@@ -509,7 +509,7 @@ out:
-       return 0;
- }
--int main(int argc, char *argv[])
-+int mountd_main(int argc, char **argv)
- {
-       int ret = -EINVAL;
-       int c;
---- a/mountd/rpc.c
-+++ b/mountd/rpc.c
-@@ -16,7 +16,7 @@
- #include <rpc_wkssvc.h>
- #include <rpc_samr.h>
- #include <rpc_lsarpc.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- static GHashTable     *pipes_table;
- static GRWLock                pipes_table_lock;
---- a/mountd/rpc_lsarpc.c
-+++ b/mountd/rpc_lsarpc.c
-@@ -16,7 +16,7 @@
- #include <rpc.h>
- #include <rpc_lsarpc.h>
- #include <smbacl.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #define LSARPC_OPNUM_DS_ROLE_GET_PRIMARY_DOMAIN_INFO  0
- #define LSARPC_OPNUM_OPEN_POLICY2                     44
---- a/mountd/rpc_samr.c
-+++ b/mountd/rpc_samr.c
-@@ -15,7 +15,7 @@
- #include <rpc.h>
- #include <rpc_samr.h>
- #include <smbacl.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #define SAMR_OPNUM_CONNECT5           64
- #define SAMR_OPNUM_ENUM_DOMAIN                6
---- a/mountd/rpc_srvsvc.c
-+++ b/mountd/rpc_srvsvc.c
-@@ -15,7 +15,7 @@
- #include <rpc.h>
- #include <rpc_srvsvc.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #define SHARE_TYPE_TEMP                       0x40000000
- #define SHARE_TYPE_HIDDEN             0x80000000
---- a/mountd/rpc_wkssvc.c
-+++ b/mountd/rpc_wkssvc.c
-@@ -15,7 +15,7 @@
- #include <rpc.h>
- #include <rpc_wkssvc.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #define WKSSVC_NETWKSTA_GET_INFO      (0)
---- a/mountd/smbacl.c
-+++ b/mountd/smbacl.c
-@@ -7,7 +7,7 @@
-  */
- #include <smbacl.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #include <glib.h>
- static const struct smb_sid sid_domain = {1, 1, {0, 0, 0, 0, 0, 5},
---- a/mountd/worker.c
-+++ b/mountd/worker.c
-@@ -9,7 +9,7 @@
- #include <errno.h>
- #include <linux/ksmbd_server.h>
--#include <ksmbdtools.h>
-+#include <tools.h>
- #include <worker.h>
- #include <ipc.h>
- #include <rpc.h>
---- a/lib/Makefile.am
-+++ /dev/null
-@@ -1,18 +0,0 @@
--AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
--            -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBKRB5_CFLAGS) -fno-common
--LIBS = $(GLIB_LIBS)
--
--noinst_LIBRARIES = libksmbdtools.a
--libksmbdtools_a_SOURCES = management/tree_conn.c \
--                          management/user.c \
--                          management/share.c \
--                          management/session.c \
--                          config_parser.c \
--                          ksmbdtools.c
--
--if HAVE_LIBKRB5
--libksmbdtools_a_SOURCES += management/spnego.c \
--                           asn1.c \
--                           management/spnego_krb5.c \
--                           management/spnego_mech.h
--endif
---- /dev/null
-+++ b/tools/Makefile.am
-@@ -0,0 +1,21 @@
-+AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \
-+            -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBKRB5_CFLAGS) -fno-common
-+LIBS = $(GLIB_LIBS) $(LIBNL_LIBS) $(LIBKRB5_LIBS)
-+
-+libexec_PROGRAMS = ksmbd.tools
-+ksmbd_tools_SOURCES =     management/tree_conn.c \
-+                          management/user.c \
-+                          management/share.c \
-+                          management/session.c \
-+                          config_parser.c \
-+                          tools.c
-+if HAVE_LIBKRB5
-+ksmbd_tools_SOURCES +=     management/spnego.c \
-+                           asn1.c \
-+                           management/spnego_krb5.c \
-+                           management/spnego_mech.h
-+endif
-+ksmbd_tools_LDADD = $(top_builddir)/addshare/libaddshare.a \
-+                    $(top_builddir)/adduser/libadduser.a \
-+                    $(top_builddir)/control/libcontrol.a \
-+                    $(top_builddir)/mountd/libmountd.a
---- a/lib/config_parser.c
-+++ /dev/null
-@@ -1,770 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <glib.h>
--#include <string.h>
--#include <glib/gstdio.h>
--#include <sys/stat.h>
--#include <sys/types.h>
--#include <unistd.h>
--#include <fcntl.h>
--#include <linux/ksmbd_server.h>
--
--#include <config_parser.h>
--#include <ksmbdtools.h>
--#include <management/user.h>
--#include <management/share.h>
--
--struct smbconf_global global_conf;
--struct smbconf_parser parser;
--struct smbconf_group *global_group, *ipc_group;
--
--unsigned long long memparse(const char *v)
--{
--      char *eptr;
--
--      unsigned long long ret = strtoull(v, &eptr, 0);
--
--      switch (*eptr) {
--      case 'E':
--      case 'e':
--              ret <<= 10;
--      case 'P':
--      case 'p':
--              ret <<= 10;
--      case 'T':
--      case 't':
--              ret <<= 10;
--      case 'G':
--      case 'g':
--              ret <<= 10;
--      case 'M':
--      case 'm':
--              ret <<= 10;
--      case 'K':
--      case 'k':
--              ret <<= 10;
--      }
--
--      return ret;
--}
--
--static void kv_release_cb(gpointer p)
--{
--      g_free(p);
--}
--
--static int is_ascii_space_tab(char c)
--{
--      return c == ' ' || c == '\t';
--}
--
--static int is_a_comment(char *line)
--{
--      return (*line == 0x00 || *line == ';' || *line == '\n' || *line == '#');
--}
--
--static int is_a_group(char *line)
--{
--      char *p = line;
--
--      if (*p != '[')
--              return 0;
--      p++;
--      while (*p && *p != ']')
--              p = g_utf8_find_next_char(p, NULL);
--      if (*p != ']')
--              return 0;
--      return 1;
--}
--
--static int add_new_group(char *line)
--{
--      char *begin = line;
--      char *end = line;
--      char *name = NULL;
--      struct smbconf_group *group = NULL;
--      struct smbconf_group *lookup;
--
--      while (*end && *end != ']')
--              end = g_utf8_find_next_char(end, NULL);
--
--      name = g_strndup(begin + 1, end - begin - 1);
--      if (!name)
--              goto out_free;
--
--      lookup = g_hash_table_lookup(parser.groups, name);
--      if (lookup) {
--              parser.current = lookup;
--              pr_info("Multiple definitions for group `%s'\n", name);
--              g_free(name);
--              return 0;
--      }
--
--      group = g_malloc(sizeof(struct smbconf_group));
--      group->cb_mode = GROUPS_CALLBACK_NONE;
--      group->name = name;
--      group->kv = g_hash_table_new_full(g_str_hash,
--                                        g_str_equal,
--                                        kv_release_cb,
--                                        kv_release_cb);
--      if (!group->kv)
--              goto out_free;
--
--      parser.current = group;
--      g_hash_table_insert(parser.groups, group->name, group);
--      return 0;
--
--out_free:
--      g_free(name);
--      if (group && group->kv)
--              g_hash_table_destroy(group->kv);
--      g_free(group);
--      return -ENOMEM;
--}
--
--static int add_group_key_value(char *line)
--{
--      char *key, *value;
--
--      key = strchr(line, '=');
--      if (!key)
--              return -EINVAL;
--
--      value = key;
--      *key = 0x00;
--      key--;
--      value++;
--
--      while (is_ascii_space_tab(*key))
--              key--;
--      while (is_ascii_space_tab(*value))
--              value++;
--
--      if (is_a_comment(value))
--              return 0;
--
--      if (g_hash_table_lookup(parser.current->kv, key)) {
--              pr_info("Multiple key-value definitions [%s] %s\n",
--                              parser.current->name, key);
--              return 0;
--      }
--
--      key = g_strndup(line, key - line + 1);
--      value = g_strdup(value);
--
--      if (!key || !value) {
--              g_free(key);
--              g_free(value);
--              return -ENOMEM;
--      }
--
--      g_hash_table_insert(parser.current->kv, key, value);
--      return 0;
--}
--
--static int process_smbconf_entry(char *data)
--{
--      while (is_ascii_space_tab(*data))
--              data++;
--
--      if (is_a_comment(data))
--              return 0;
--
--      if (is_a_group(data))
--              return add_new_group(data);
--
--      return add_group_key_value(data);
--}
--
--static int __mmap_parse_file(const char *fname, int (*callback)(char *data))
--{
--      GMappedFile *file;
--      GError *err = NULL;
--      gchar *contents;
--      int len;
--      char *delim;
--      int fd, ret = 0;
--
--      fd = g_open(fname, O_RDONLY, 0);
--      if (fd == -1) {
--              ret = -errno;
--              pr_debug("Can't open `%s': %m\n", fname);
--              return ret;
--      }
--
--      file = g_mapped_file_new_from_fd(fd, FALSE, &err);
--      if (err) {
--              pr_err("Can't map `%s' to memory: %s\n", fname, err->message);
--              g_error_free(err);
--              ret = -EINVAL;
--              goto out;
--      }
--
--      contents = g_mapped_file_get_contents(file);
--      if (!contents)
--              goto out;
--
--      len = g_mapped_file_get_length(file);
--      while (len > 0) {
--              delim = strchr(contents, '\n');
--              if (!delim)
--                      delim = contents + len - 1;
--
--              if (delim) {
--                      size_t sz = delim - contents;
--                      char *data;
--
--                      if (delim == contents) {
--                              contents = delim + 1;
--                              len--;
--                              continue;
--                      }
--
--                      if (!sz)
--                              break;
--
--                      data = g_strndup(contents, sz);
--                      ret = callback(data);
--                      if (ret) {
--                              g_free(data);
--                              goto out;
--                      }
--
--                      g_free(data);
--                      contents = delim + 1;
--                      len -= (sz + 1);
--              }
--      }
--
--      ret = 0;
--out:
--      if (file)
--              g_mapped_file_unref(file);
--
--      if (fd) {
--              g_close(fd, &err);
--              if (err) {
--                      pr_err("Can't close `%s': %s\n", fname, err->message);
--                      g_error_free(err);
--              }
--      }
--      return ret;
--}
--
--static int init_smbconf_parser(void)
--{
--      if (parser.groups)
--              return 0;
--
--      parser.groups = g_hash_table_new(shm_share_name_hash,
--                                       shm_share_name_equal);
--      if (!parser.groups)
--              return -ENOMEM;
--      return 0;
--}
--
--static void release_smbconf_group(gpointer k, gpointer v, gpointer user_data)
--{
--      struct smbconf_group *g = v;
--
--      g_hash_table_destroy(g->kv);
--      g_free(g->name);
--      g_free(g);
--}
--
--static void release_smbconf_parser(void)
--{
--      if (!parser.groups)
--              return;
--
--      g_hash_table_foreach(parser.groups, release_smbconf_group, NULL);
--      g_hash_table_destroy(parser.groups);
--      parser.groups = NULL;
--}
--
--char *cp_ltrim(char *v)
--{
--      if (!v)
--              return NULL;
--
--      while (*v && *v == ' ')
--              v++;
--      if (*v == 0x00)
--              return NULL;
--      return v;
--}
--
--int cp_key_cmp(char *k, char *v)
--{
--      if (!k || !v)
--              return -1;
--      return g_ascii_strncasecmp(k, v, strlen(v));
--}
--
--char *cp_get_group_kv_string(char *v)
--{
--      return g_strdup(v);
--}
--
--int cp_get_group_kv_bool(char *v)
--{
--      if (!g_ascii_strncasecmp(v, "yes", 3) ||
--              !g_ascii_strncasecmp(v, "1", 1) ||
--              !g_ascii_strncasecmp(v, "true", 4) ||
--              !g_ascii_strncasecmp(v, "enable", 6))
--              return 1;
--      return 0;
--}
--
--int cp_get_group_kv_config_opt(char *v)
--{
--      if (!g_ascii_strncasecmp(v, "disabled", 8))
--              return KSMBD_CONFIG_OPT_DISABLED;
--      if (!g_ascii_strncasecmp(v, "enabled", 7))
--              return KSMBD_CONFIG_OPT_ENABLED;
--      if (!g_ascii_strncasecmp(v, "auto", 4))
--              return KSMBD_CONFIG_OPT_AUTO;
--      if (!g_ascii_strncasecmp(v, "mandatory", 9))
--              return KSMBD_CONFIG_OPT_MANDATORY;
--      return KSMBD_CONFIG_OPT_DISABLED;
--}
--
--unsigned long cp_get_group_kv_long_base(char *v, int base)
--{
--      return strtoul(v, NULL, base);
--}
--
--unsigned long cp_get_group_kv_long(char *v)
--{
--      return cp_get_group_kv_long_base(v, 10);
--}
--
--char **cp_get_group_kv_list(char *v)
--{
--      /*
--       * SMB conf lists are "tabs, spaces, commas" separated.
--       */
--      return g_strsplit_set(v, "\t ,", -1);
--}
--
--void cp_group_kv_list_free(char **list)
--{
--      g_strfreev(list);
--}
--
--static int cp_add_global_guest_account(gpointer _v)
--{
--      struct ksmbd_user *user;
--
--      if (usm_add_new_user(cp_get_group_kv_string(_v),
--                           g_strdup("NULL"))) {
--              pr_err("Unable to add guest account\n");
--              return -ENOMEM;
--      }
--
--      user = usm_lookup_user(_v);
--      if (!user) {
--              pr_err("Unable to find user `%s'\n", (char *) _v);
--              return -EINVAL;
--      }
--
--      set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT);
--      put_ksmbd_user(user);
--      global_conf.guest_account = cp_get_group_kv_string(_v);
--      return 0;
--}
--
--static gboolean global_group_kv(gpointer _k, gpointer _v, gpointer user_data)
--{
--      if (!cp_key_cmp(_k, "server string")) {
--              global_conf.server_string = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "workgroup")) {
--              global_conf.work_group = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "netbios name")) {
--              global_conf.netbios_name = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "server min protocol")) {
--              global_conf.server_min_protocol = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "server signing")) {
--              global_conf.server_signing = cp_get_group_kv_config_opt(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "server max protocol")) {
--              global_conf.server_max_protocol = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "guest account")) {
--              cp_add_global_guest_account(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "max active sessions")) {
--              global_conf.sessions_cap = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "tcp port")) {
--              if (!global_conf.tcp_port)
--                      global_conf.tcp_port = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "ipc timeout")) {
--              global_conf.ipc_timeout = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "max open files")) {
--              global_conf.file_max = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "restrict anonymous")) {
--              global_conf.restrict_anon = cp_get_group_kv_long(_v);
--              if (global_conf.restrict_anon > KSMBD_RESTRICT_ANON_TYPE_2 ||
--                              global_conf.restrict_anon < 0) {
--                      global_conf.restrict_anon = 0;
--                      pr_err("Invalid restrict anonymous value\n");
--              }
--
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "map to guest")) {
--              global_conf.map_to_guest = KSMBD_CONF_MAP_TO_GUEST_NEVER;
--              if (!cp_key_cmp(_v, "bad user"))
--                      global_conf.map_to_guest =
--                              KSMBD_CONF_MAP_TO_GUEST_BAD_USER;
--              if (!cp_key_cmp(_v, "bad password"))
--                      global_conf.map_to_guest =
--                              KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD;
--              if (!cp_key_cmp(_v, "bad uid"))
--                      global_conf.map_to_guest =
--                              KSMBD_CONF_MAP_TO_GUEST_BAD_UID;
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "bind interfaces only")) {
--              global_conf.bind_interfaces_only = cp_get_group_kv_bool(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "interfaces")) {
--              global_conf.interfaces = cp_get_group_kv_list(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "deadtime")) {
--              global_conf.deadtime = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb2 leases")) {
--              if (cp_get_group_kv_bool(_v))
--                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB2_LEASES;
--              else
--                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB2_LEASES;
--
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "root directory")) {
--              global_conf.root_dir = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb2 max read")) {
--              global_conf.smb2_max_read = memparse(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb2 max write")) {
--              global_conf.smb2_max_write = memparse(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb2 max trans")) {
--              global_conf.smb2_max_trans = memparse(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb3 encryption")) {
--              if (cp_get_group_kv_bool(_v))
--                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION;
--              else
--                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION;
--
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "share:fake_fscaps")) {
--              global_conf.share_fake_fscaps = cp_get_group_kv_long(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "kerberos service name")) {
--              global_conf.krb5_service_name = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "kerberos keytab file")) {
--              global_conf.krb5_keytab_file = cp_get_group_kv_string(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "server multi channel support")) {
--              if (cp_get_group_kv_bool(_v))
--                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL;
--              else
--                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL;
--
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smb2 max credits")) {
--              global_conf.smb2_max_credits = memparse(_v);
--              return TRUE;
--      }
--
--      if (!cp_key_cmp(_k, "smbd max io size")) {
--              global_conf.smbd_max_io_size = memparse(_v);
--              return TRUE;
--      }
--
--      /* At this point, this is an option that must be applied to all shares */
--      return FALSE;
--}
--
--static void global_conf_default(void)
--{
--      /* The SPARSE_FILES file system capability flag is set by default */
--      global_conf.share_fake_fscaps = 64;
--}
--
--static void global_conf_create(void)
--{
--      if (!global_group || global_group->cb_mode != GROUPS_CALLBACK_INIT)
--              return;
--
--      /*
--       * This will transfer server options to global_conf, and leave behind
--       * in the global parser group, the options that must be applied to every
--       * share
--       */
--      g_hash_table_foreach_remove(global_group->kv, global_group_kv, NULL);
--}
--
--static void append_key_value(gpointer _k, gpointer _v, gpointer user_data)
--{
--      GHashTable *receiver = (GHashTable *)user_data;
--
--      /* Don't override local share options */
--      if (!g_hash_table_lookup(receiver, _k))
--              g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v));
--}
--
--static void global_conf_update(struct smbconf_group *group)
--{
--      if (!global_group)
--              return;
--
--      g_hash_table_foreach(global_group->kv, append_key_value, group->kv);
--}
--
--static void global_conf_fixup_missing(void)
--{
--      /*
--       * Set default global parameters which were not specified
--       * in smb.conf
--       */
--      if (!global_conf.file_max)
--              global_conf.file_max = KSMBD_CONF_FILE_MAX;
--      if (!global_conf.server_string)
--              global_conf.server_string =
--                      cp_get_group_kv_string(
--                                      KSMBD_CONF_DEFAULT_SERVER_STRING);
--      if (!global_conf.netbios_name)
--              global_conf.netbios_name =
--                      cp_get_group_kv_string(KSMBD_CONF_DEFAULT_NETBIOS_NAME);
--      if (!global_conf.work_group)
--              global_conf.work_group =
--                      cp_get_group_kv_string(KSMBD_CONF_DEFAULT_WORK_GROUP);
--      if (!global_conf.tcp_port)
--              global_conf.tcp_port = KSMBD_CONF_DEFAULT_TCP_PORT;
--
--      if (global_conf.sessions_cap <= 0)
--              global_conf.sessions_cap = KSMBD_CONF_DEFAULT_SESS_CAP;
--
--      if (!global_conf.guest_account &&
--          cp_add_global_guest_account(KSMBD_CONF_DEFAULT_GUEST_ACCOUNT))
--              pr_err("Unable to add guest account\n");
--}
--
--static void groups_callback(gpointer _k, gpointer _v, gpointer user_data)
--{
--      struct smbconf_group *group = (struct smbconf_group *)_v;
--      unsigned short cb_mode = *(unsigned short *)user_data;
--
--      if (group == global_group)
--              return;
--
--      group->cb_mode = cb_mode;
--
--      if (group != ipc_group)
--              global_conf_update(group);
--
--      shm_add_new_share(group);
--}
--
--static int cp_add_ipc_group(void)
--{
--      char *comment = NULL, *guest = NULL;
--      int ret = 0;
--
--      if (ipc_group)
--              return ret;
--
--      comment = g_strdup("comment = IPC share");
--      guest = g_strdup("guest ok = yes");
--      ret = add_new_group("[IPC$]");
--      ret |= add_group_key_value(comment);
--      ret |= add_group_key_value(guest);
--      if (ret) {
--              pr_err("Unable to add IPC$ share\n");
--              ret = -EINVAL;
--              goto out;
--      }
--
--      ipc_group = g_hash_table_lookup(parser.groups, "ipc$");
--out:
--      g_free(comment);
--      g_free(guest);
--      return ret;
--}
--
--static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb,
--                              unsigned short cb_mode)
--{
--      int ret;
--
--      global_conf_default();
--
--      ret = cp_smbconfig_hash_create(smbconf);
--      if (ret)
--              return ret;
--
--      ret = cp_add_ipc_group();
--      if (ret)
--              goto out;
--
--      global_group = g_hash_table_lookup(parser.groups, "global");
--      if (global_group)
--              global_group->cb_mode = cb_mode;
--
--      global_conf_create();
--      g_hash_table_foreach(parser.groups, groups_callback, &cb_mode);
--      global_conf_fixup_missing();
--out:
--      cp_smbconfig_destroy();
--      return ret;
--}
--
--int cp_parse_reload_smbconf(const char *smbconf)
--{
--      return __cp_parse_smbconfig(smbconf, groups_callback,
--                                  GROUPS_CALLBACK_REINIT);
--}
--
--int cp_parse_smbconf(const char *smbconf)
--{
--      return __cp_parse_smbconfig(smbconf, groups_callback,
--                                  GROUPS_CALLBACK_INIT);
--}
--
--int cp_parse_pwddb(const char *pwddb)
--{
--      return __mmap_parse_file(pwddb, usm_add_update_user_from_pwdentry);
--}
--
--int cp_smbconfig_hash_create(const char *smbconf)
--{
--      int ret = init_smbconf_parser();
--
--      if (ret)
--              return ret;
--      return __mmap_parse_file(smbconf, process_smbconf_entry);
--}
--
--int cp_parse_subauth(void)
--{
--      return __mmap_parse_file(PATH_SUBAUTH, usm_add_subauth_global_conf);
--}
--
--void cp_smbconfig_destroy(void)
--{
--      release_smbconf_parser();
--}
--
--int cp_parse_external_smbconf_group(char *name, char *opts)
--{
--      char *pos;
--      int i, len;
--
--      if (init_smbconf_parser())
--              return -EINVAL;
--
--      if (!opts || !name)
--              return -EINVAL;
--
--      len = strlen(opts);
--      /* fake smb.conf input */
--      for (i = 0; i < KSMBD_SHARE_CONF_MAX; i++) {
--              pos = strstr(opts, KSMBD_SHARE_CONF[i]);
--              if (!pos)
--                      continue;
--              if (pos != opts)
--                      *(pos - 1) = '\n';
--      }
--
--      if (add_new_group(name))
--              goto error;
--
--      /* split input and feed to normal process_smbconf_entry() */
--      while (len) {
--              char *delim = strchr(opts, '\n');
--
--              if (delim) {
--                      *delim = 0x00;
--                      len -= delim - opts;
--              } else {
--                      len = 0;
--              }
--
--              process_smbconf_entry(opts);
--              if (delim)
--                      opts = delim + 1;
--      }
--      return 0;
--
--error:
--      cp_smbconfig_destroy();
--      return -EINVAL;
--}
---- /dev/null
-+++ b/tools/config_parser.c
-@@ -0,0 +1,770 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <glib.h>
-+#include <string.h>
-+#include <glib/gstdio.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <linux/ksmbd_server.h>
-+
-+#include <config_parser.h>
-+#include <tools.h>
-+#include <management/user.h>
-+#include <management/share.h>
-+
-+struct smbconf_global global_conf;
-+struct smbconf_parser parser;
-+struct smbconf_group *global_group, *ipc_group;
-+
-+unsigned long long memparse(const char *v)
-+{
-+      char *eptr;
-+
-+      unsigned long long ret = strtoull(v, &eptr, 0);
-+
-+      switch (*eptr) {
-+      case 'E':
-+      case 'e':
-+              ret <<= 10;
-+      case 'P':
-+      case 'p':
-+              ret <<= 10;
-+      case 'T':
-+      case 't':
-+              ret <<= 10;
-+      case 'G':
-+      case 'g':
-+              ret <<= 10;
-+      case 'M':
-+      case 'm':
-+              ret <<= 10;
-+      case 'K':
-+      case 'k':
-+              ret <<= 10;
-+      }
-+
-+      return ret;
-+}
-+
-+static void kv_release_cb(gpointer p)
-+{
-+      g_free(p);
-+}
-+
-+static int is_ascii_space_tab(char c)
-+{
-+      return c == ' ' || c == '\t';
-+}
-+
-+static int is_a_comment(char *line)
-+{
-+      return (*line == 0x00 || *line == ';' || *line == '\n' || *line == '#');
-+}
-+
-+static int is_a_group(char *line)
-+{
-+      char *p = line;
-+
-+      if (*p != '[')
-+              return 0;
-+      p++;
-+      while (*p && *p != ']')
-+              p = g_utf8_find_next_char(p, NULL);
-+      if (*p != ']')
-+              return 0;
-+      return 1;
-+}
-+
-+static int add_new_group(char *line)
-+{
-+      char *begin = line;
-+      char *end = line;
-+      char *name = NULL;
-+      struct smbconf_group *group = NULL;
-+      struct smbconf_group *lookup;
-+
-+      while (*end && *end != ']')
-+              end = g_utf8_find_next_char(end, NULL);
-+
-+      name = g_strndup(begin + 1, end - begin - 1);
-+      if (!name)
-+              goto out_free;
-+
-+      lookup = g_hash_table_lookup(parser.groups, name);
-+      if (lookup) {
-+              parser.current = lookup;
-+              pr_info("Multiple definitions for group `%s'\n", name);
-+              g_free(name);
-+              return 0;
-+      }
-+
-+      group = g_malloc(sizeof(struct smbconf_group));
-+      group->cb_mode = GROUPS_CALLBACK_NONE;
-+      group->name = name;
-+      group->kv = g_hash_table_new_full(g_str_hash,
-+                                        g_str_equal,
-+                                        kv_release_cb,
-+                                        kv_release_cb);
-+      if (!group->kv)
-+              goto out_free;
-+
-+      parser.current = group;
-+      g_hash_table_insert(parser.groups, group->name, group);
-+      return 0;
-+
-+out_free:
-+      g_free(name);
-+      if (group && group->kv)
-+              g_hash_table_destroy(group->kv);
-+      g_free(group);
-+      return -ENOMEM;
-+}
-+
-+static int add_group_key_value(char *line)
-+{
-+      char *key, *value;
-+
-+      key = strchr(line, '=');
-+      if (!key)
-+              return -EINVAL;
-+
-+      value = key;
-+      *key = 0x00;
-+      key--;
-+      value++;
-+
-+      while (is_ascii_space_tab(*key))
-+              key--;
-+      while (is_ascii_space_tab(*value))
-+              value++;
-+
-+      if (is_a_comment(value))
-+              return 0;
-+
-+      if (g_hash_table_lookup(parser.current->kv, key)) {
-+              pr_info("Multiple key-value definitions [%s] %s\n",
-+                              parser.current->name, key);
-+              return 0;
-+      }
-+
-+      key = g_strndup(line, key - line + 1);
-+      value = g_strdup(value);
-+
-+      if (!key || !value) {
-+              g_free(key);
-+              g_free(value);
-+              return -ENOMEM;
-+      }
-+
-+      g_hash_table_insert(parser.current->kv, key, value);
-+      return 0;
-+}
-+
-+static int process_smbconf_entry(char *data)
-+{
-+      while (is_ascii_space_tab(*data))
-+              data++;
-+
-+      if (is_a_comment(data))
-+              return 0;
-+
-+      if (is_a_group(data))
-+              return add_new_group(data);
-+
-+      return add_group_key_value(data);
-+}
-+
-+static int __mmap_parse_file(const char *fname, int (*callback)(char *data))
-+{
-+      GMappedFile *file;
-+      GError *err = NULL;
-+      gchar *contents;
-+      int len;
-+      char *delim;
-+      int fd, ret = 0;
-+
-+      fd = g_open(fname, O_RDONLY, 0);
-+      if (fd == -1) {
-+              ret = -errno;
-+              pr_debug("Can't open `%s': %m\n", fname);
-+              return ret;
-+      }
-+
-+      file = g_mapped_file_new_from_fd(fd, FALSE, &err);
-+      if (err) {
-+              pr_err("Can't map `%s' to memory: %s\n", fname, err->message);
-+              g_error_free(err);
-+              ret = -EINVAL;
-+              goto out;
-+      }
-+
-+      contents = g_mapped_file_get_contents(file);
-+      if (!contents)
-+              goto out;
-+
-+      len = g_mapped_file_get_length(file);
-+      while (len > 0) {
-+              delim = strchr(contents, '\n');
-+              if (!delim)
-+                      delim = contents + len - 1;
-+
-+              if (delim) {
-+                      size_t sz = delim - contents;
-+                      char *data;
-+
-+                      if (delim == contents) {
-+                              contents = delim + 1;
-+                              len--;
-+                              continue;
-+                      }
-+
-+                      if (!sz)
-+                              break;
-+
-+                      data = g_strndup(contents, sz);
-+                      ret = callback(data);
-+                      if (ret) {
-+                              g_free(data);
-+                              goto out;
-+                      }
-+
-+                      g_free(data);
-+                      contents = delim + 1;
-+                      len -= (sz + 1);
-+              }
-+      }
-+
-+      ret = 0;
-+out:
-+      if (file)
-+              g_mapped_file_unref(file);
-+
-+      if (fd) {
-+              g_close(fd, &err);
-+              if (err) {
-+                      pr_err("Can't close `%s': %s\n", fname, err->message);
-+                      g_error_free(err);
-+              }
-+      }
-+      return ret;
-+}
-+
-+static int init_smbconf_parser(void)
-+{
-+      if (parser.groups)
-+              return 0;
-+
-+      parser.groups = g_hash_table_new(shm_share_name_hash,
-+                                       shm_share_name_equal);
-+      if (!parser.groups)
-+              return -ENOMEM;
-+      return 0;
-+}
-+
-+static void release_smbconf_group(gpointer k, gpointer v, gpointer user_data)
-+{
-+      struct smbconf_group *g = v;
-+
-+      g_hash_table_destroy(g->kv);
-+      g_free(g->name);
-+      g_free(g);
-+}
-+
-+static void release_smbconf_parser(void)
-+{
-+      if (!parser.groups)
-+              return;
-+
-+      g_hash_table_foreach(parser.groups, release_smbconf_group, NULL);
-+      g_hash_table_destroy(parser.groups);
-+      parser.groups = NULL;
-+}
-+
-+char *cp_ltrim(char *v)
-+{
-+      if (!v)
-+              return NULL;
-+
-+      while (*v && *v == ' ')
-+              v++;
-+      if (*v == 0x00)
-+              return NULL;
-+      return v;
-+}
-+
-+int cp_key_cmp(char *k, char *v)
-+{
-+      if (!k || !v)
-+              return -1;
-+      return g_ascii_strncasecmp(k, v, strlen(v));
-+}
-+
-+char *cp_get_group_kv_string(char *v)
-+{
-+      return g_strdup(v);
-+}
-+
-+int cp_get_group_kv_bool(char *v)
-+{
-+      if (!g_ascii_strncasecmp(v, "yes", 3) ||
-+              !g_ascii_strncasecmp(v, "1", 1) ||
-+              !g_ascii_strncasecmp(v, "true", 4) ||
-+              !g_ascii_strncasecmp(v, "enable", 6))
-+              return 1;
-+      return 0;
-+}
-+
-+int cp_get_group_kv_config_opt(char *v)
-+{
-+      if (!g_ascii_strncasecmp(v, "disabled", 8))
-+              return KSMBD_CONFIG_OPT_DISABLED;
-+      if (!g_ascii_strncasecmp(v, "enabled", 7))
-+              return KSMBD_CONFIG_OPT_ENABLED;
-+      if (!g_ascii_strncasecmp(v, "auto", 4))
-+              return KSMBD_CONFIG_OPT_AUTO;
-+      if (!g_ascii_strncasecmp(v, "mandatory", 9))
-+              return KSMBD_CONFIG_OPT_MANDATORY;
-+      return KSMBD_CONFIG_OPT_DISABLED;
-+}
-+
-+unsigned long cp_get_group_kv_long_base(char *v, int base)
-+{
-+      return strtoul(v, NULL, base);
-+}
-+
-+unsigned long cp_get_group_kv_long(char *v)
-+{
-+      return cp_get_group_kv_long_base(v, 10);
-+}
-+
-+char **cp_get_group_kv_list(char *v)
-+{
-+      /*
-+       * SMB conf lists are "tabs, spaces, commas" separated.
-+       */
-+      return g_strsplit_set(v, "\t ,", -1);
-+}
-+
-+void cp_group_kv_list_free(char **list)
-+{
-+      g_strfreev(list);
-+}
-+
-+static int cp_add_global_guest_account(gpointer _v)
-+{
-+      struct ksmbd_user *user;
-+
-+      if (usm_add_new_user(cp_get_group_kv_string(_v),
-+                           g_strdup("NULL"))) {
-+              pr_err("Unable to add guest account\n");
-+              return -ENOMEM;
-+      }
-+
-+      user = usm_lookup_user(_v);
-+      if (!user) {
-+              pr_err("Unable to find user `%s'\n", (char *) _v);
-+              return -EINVAL;
-+      }
-+
-+      set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT);
-+      put_ksmbd_user(user);
-+      global_conf.guest_account = cp_get_group_kv_string(_v);
-+      return 0;
-+}
-+
-+static gboolean global_group_kv(gpointer _k, gpointer _v, gpointer user_data)
-+{
-+      if (!cp_key_cmp(_k, "server string")) {
-+              global_conf.server_string = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "workgroup")) {
-+              global_conf.work_group = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "netbios name")) {
-+              global_conf.netbios_name = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "server min protocol")) {
-+              global_conf.server_min_protocol = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "server signing")) {
-+              global_conf.server_signing = cp_get_group_kv_config_opt(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "server max protocol")) {
-+              global_conf.server_max_protocol = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "guest account")) {
-+              cp_add_global_guest_account(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "max active sessions")) {
-+              global_conf.sessions_cap = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "tcp port")) {
-+              if (!global_conf.tcp_port)
-+                      global_conf.tcp_port = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "ipc timeout")) {
-+              global_conf.ipc_timeout = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "max open files")) {
-+              global_conf.file_max = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "restrict anonymous")) {
-+              global_conf.restrict_anon = cp_get_group_kv_long(_v);
-+              if (global_conf.restrict_anon > KSMBD_RESTRICT_ANON_TYPE_2 ||
-+                              global_conf.restrict_anon < 0) {
-+                      global_conf.restrict_anon = 0;
-+                      pr_err("Invalid restrict anonymous value\n");
-+              }
-+
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "map to guest")) {
-+              global_conf.map_to_guest = KSMBD_CONF_MAP_TO_GUEST_NEVER;
-+              if (!cp_key_cmp(_v, "bad user"))
-+                      global_conf.map_to_guest =
-+                              KSMBD_CONF_MAP_TO_GUEST_BAD_USER;
-+              if (!cp_key_cmp(_v, "bad password"))
-+                      global_conf.map_to_guest =
-+                              KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD;
-+              if (!cp_key_cmp(_v, "bad uid"))
-+                      global_conf.map_to_guest =
-+                              KSMBD_CONF_MAP_TO_GUEST_BAD_UID;
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "bind interfaces only")) {
-+              global_conf.bind_interfaces_only = cp_get_group_kv_bool(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "interfaces")) {
-+              global_conf.interfaces = cp_get_group_kv_list(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "deadtime")) {
-+              global_conf.deadtime = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb2 leases")) {
-+              if (cp_get_group_kv_bool(_v))
-+                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB2_LEASES;
-+              else
-+                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB2_LEASES;
-+
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "root directory")) {
-+              global_conf.root_dir = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb2 max read")) {
-+              global_conf.smb2_max_read = memparse(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb2 max write")) {
-+              global_conf.smb2_max_write = memparse(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb2 max trans")) {
-+              global_conf.smb2_max_trans = memparse(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb3 encryption")) {
-+              if (cp_get_group_kv_bool(_v))
-+                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION;
-+              else
-+                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION;
-+
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "share:fake_fscaps")) {
-+              global_conf.share_fake_fscaps = cp_get_group_kv_long(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "kerberos service name")) {
-+              global_conf.krb5_service_name = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "kerberos keytab file")) {
-+              global_conf.krb5_keytab_file = cp_get_group_kv_string(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "server multi channel support")) {
-+              if (cp_get_group_kv_bool(_v))
-+                      global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL;
-+              else
-+                      global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL;
-+
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smb2 max credits")) {
-+              global_conf.smb2_max_credits = memparse(_v);
-+              return TRUE;
-+      }
-+
-+      if (!cp_key_cmp(_k, "smbd max io size")) {
-+              global_conf.smbd_max_io_size = memparse(_v);
-+              return TRUE;
-+      }
-+
-+      /* At this point, this is an option that must be applied to all shares */
-+      return FALSE;
-+}
-+
-+static void global_conf_default(void)
-+{
-+      /* The SPARSE_FILES file system capability flag is set by default */
-+      global_conf.share_fake_fscaps = 64;
-+}
-+
-+static void global_conf_create(void)
-+{
-+      if (!global_group || global_group->cb_mode != GROUPS_CALLBACK_INIT)
-+              return;
-+
-+      /*
-+       * This will transfer server options to global_conf, and leave behind
-+       * in the global parser group, the options that must be applied to every
-+       * share
-+       */
-+      g_hash_table_foreach_remove(global_group->kv, global_group_kv, NULL);
-+}
-+
-+static void append_key_value(gpointer _k, gpointer _v, gpointer user_data)
-+{
-+      GHashTable *receiver = (GHashTable *)user_data;
-+
-+      /* Don't override local share options */
-+      if (!g_hash_table_lookup(receiver, _k))
-+              g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v));
-+}
-+
-+static void global_conf_update(struct smbconf_group *group)
-+{
-+      if (!global_group)
-+              return;
-+
-+      g_hash_table_foreach(global_group->kv, append_key_value, group->kv);
-+}
-+
-+static void global_conf_fixup_missing(void)
-+{
-+      /*
-+       * Set default global parameters which were not specified
-+       * in smb.conf
-+       */
-+      if (!global_conf.file_max)
-+              global_conf.file_max = KSMBD_CONF_FILE_MAX;
-+      if (!global_conf.server_string)
-+              global_conf.server_string =
-+                      cp_get_group_kv_string(
-+                                      KSMBD_CONF_DEFAULT_SERVER_STRING);
-+      if (!global_conf.netbios_name)
-+              global_conf.netbios_name =
-+                      cp_get_group_kv_string(KSMBD_CONF_DEFAULT_NETBIOS_NAME);
-+      if (!global_conf.work_group)
-+              global_conf.work_group =
-+                      cp_get_group_kv_string(KSMBD_CONF_DEFAULT_WORK_GROUP);
-+      if (!global_conf.tcp_port)
-+              global_conf.tcp_port = KSMBD_CONF_DEFAULT_TCP_PORT;
-+
-+      if (global_conf.sessions_cap <= 0)
-+              global_conf.sessions_cap = KSMBD_CONF_DEFAULT_SESS_CAP;
-+
-+      if (!global_conf.guest_account &&
-+          cp_add_global_guest_account(KSMBD_CONF_DEFAULT_GUEST_ACCOUNT))
-+              pr_err("Unable to add guest account\n");
-+}
-+
-+static void groups_callback(gpointer _k, gpointer _v, gpointer user_data)
-+{
-+      struct smbconf_group *group = (struct smbconf_group *)_v;
-+      unsigned short cb_mode = *(unsigned short *)user_data;
-+
-+      if (group == global_group)
-+              return;
-+
-+      group->cb_mode = cb_mode;
-+
-+      if (group != ipc_group)
-+              global_conf_update(group);
-+
-+      shm_add_new_share(group);
-+}
-+
-+static int cp_add_ipc_group(void)
-+{
-+      char *comment = NULL, *guest = NULL;
-+      int ret = 0;
-+
-+      if (ipc_group)
-+              return ret;
-+
-+      comment = g_strdup("comment = IPC share");
-+      guest = g_strdup("guest ok = yes");
-+      ret = add_new_group("[IPC$]");
-+      ret |= add_group_key_value(comment);
-+      ret |= add_group_key_value(guest);
-+      if (ret) {
-+              pr_err("Unable to add IPC$ share\n");
-+              ret = -EINVAL;
-+              goto out;
-+      }
-+
-+      ipc_group = g_hash_table_lookup(parser.groups, "ipc$");
-+out:
-+      g_free(comment);
-+      g_free(guest);
-+      return ret;
-+}
-+
-+static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb,
-+                              unsigned short cb_mode)
-+{
-+      int ret;
-+
-+      global_conf_default();
-+
-+      ret = cp_smbconfig_hash_create(smbconf);
-+      if (ret)
-+              return ret;
-+
-+      ret = cp_add_ipc_group();
-+      if (ret)
-+              goto out;
-+
-+      global_group = g_hash_table_lookup(parser.groups, "global");
-+      if (global_group)
-+              global_group->cb_mode = cb_mode;
-+
-+      global_conf_create();
-+      g_hash_table_foreach(parser.groups, groups_callback, &cb_mode);
-+      global_conf_fixup_missing();
-+out:
-+      cp_smbconfig_destroy();
-+      return ret;
-+}
-+
-+int cp_parse_reload_smbconf(const char *smbconf)
-+{
-+      return __cp_parse_smbconfig(smbconf, groups_callback,
-+                                  GROUPS_CALLBACK_REINIT);
-+}
-+
-+int cp_parse_smbconf(const char *smbconf)
-+{
-+      return __cp_parse_smbconfig(smbconf, groups_callback,
-+                                  GROUPS_CALLBACK_INIT);
-+}
-+
-+int cp_parse_pwddb(const char *pwddb)
-+{
-+      return __mmap_parse_file(pwddb, usm_add_update_user_from_pwdentry);
-+}
-+
-+int cp_smbconfig_hash_create(const char *smbconf)
-+{
-+      int ret = init_smbconf_parser();
-+
-+      if (ret)
-+              return ret;
-+      return __mmap_parse_file(smbconf, process_smbconf_entry);
-+}
-+
-+int cp_parse_subauth(void)
-+{
-+      return __mmap_parse_file(PATH_SUBAUTH, usm_add_subauth_global_conf);
-+}
-+
-+void cp_smbconfig_destroy(void)
-+{
-+      release_smbconf_parser();
-+}
-+
-+int cp_parse_external_smbconf_group(char *name, char *opts)
-+{
-+      char *pos;
-+      int i, len;
-+
-+      if (init_smbconf_parser())
-+              return -EINVAL;
-+
-+      if (!opts || !name)
-+              return -EINVAL;
-+
-+      len = strlen(opts);
-+      /* fake smb.conf input */
-+      for (i = 0; i < KSMBD_SHARE_CONF_MAX; i++) {
-+              pos = strstr(opts, KSMBD_SHARE_CONF[i]);
-+              if (!pos)
-+                      continue;
-+              if (pos != opts)
-+                      *(pos - 1) = '\n';
-+      }
-+
-+      if (add_new_group(name))
-+              goto error;
-+
-+      /* split input and feed to normal process_smbconf_entry() */
-+      while (len) {
-+              char *delim = strchr(opts, '\n');
-+
-+              if (delim) {
-+                      *delim = 0x00;
-+                      len -= delim - opts;
-+              } else {
-+                      len = 0;
-+              }
-+
-+              process_smbconf_entry(opts);
-+              if (delim)
-+                      opts = delim + 1;
-+      }
-+      return 0;
-+
-+error:
-+      cp_smbconfig_destroy();
-+      return -EINVAL;
-+}
---- a/lib/management/session.c
-+++ /dev/null
-@@ -1,235 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <stdlib.h>
--#include <string.h>
--#include <glib.h>
--
--#include "linux/ksmbd_server.h"
--#include "management/session.h"
--#include "management/tree_conn.h"
--#include "management/user.h"
--#include "ksmbdtools.h"
--
--static GHashTable     *sessions_table;
--static GRWLock                sessions_table_lock;
--
--static void __free_func(gpointer data, gpointer user_data)
--{
--      struct ksmbd_tree_conn *tree_conn;
--
--      tree_conn = (struct ksmbd_tree_conn *)data;
--      tcm_tree_conn_free(tree_conn);
--}
--
--static void kill_ksmbd_session(struct ksmbd_session *sess)
--{
--      g_list_foreach(sess->tree_conns, __free_func, NULL);
--      g_list_free(sess->tree_conns);
--      g_rw_lock_clear(&sess->update_lock);
--      g_free(sess);
--}
--
--static struct ksmbd_session *new_ksmbd_session(unsigned long long id,
--                                             struct ksmbd_user *user)
--{
--      struct ksmbd_session *sess;
--
--      sess = g_try_malloc0(sizeof(struct ksmbd_session));
--      if (!sess)
--              return NULL;
--
--      g_rw_lock_init(&sess->update_lock);
--      sess->ref_counter = 1;
--      sess->id = id;
--      sess->user = user;
--      return sess;
--}
--
--static void free_hash_entry(gpointer k, gpointer s, gpointer user_data)
--{
--      kill_ksmbd_session(s);
--}
--
--static void sm_clear_sessions(void)
--{
--      g_hash_table_foreach(sessions_table, free_hash_entry, NULL);
--}
--
--static int __sm_remove_session(struct ksmbd_session *sess)
--{
--      int ret = -EINVAL;
--
--      g_rw_lock_writer_lock(&sessions_table_lock);
--      if (g_hash_table_remove(sessions_table, &sess->id))
--              ret = 0;
--      g_rw_lock_writer_unlock(&sessions_table_lock);
--
--      if (!ret)
--              kill_ksmbd_session(sess);
--      return ret;
--}
--
--static struct ksmbd_session *__get_session(struct ksmbd_session *sess)
--{
--      struct ksmbd_session *ret = NULL;
--
--      g_rw_lock_writer_lock(&sess->update_lock);
--      if (sess->ref_counter != 0) {
--              sess->ref_counter++;
--              ret = sess;
--      } else {
--              ret = NULL;
--      }
--      g_rw_lock_writer_unlock(&sess->update_lock);
--      return ret;
--}
--
--static void __put_session(struct ksmbd_session *sess)
--{
--      int drop = 0;
--
--      g_rw_lock_writer_lock(&sess->update_lock);
--      sess->ref_counter--;
--      drop = !sess->ref_counter;
--      g_rw_lock_writer_unlock(&sess->update_lock);
--
--      if (drop)
--              __sm_remove_session(sess);
--}
--
--static struct ksmbd_session *__sm_lookup_session(unsigned long long id)
--{
--      return g_hash_table_lookup(sessions_table, &id);
--}
--
--static struct ksmbd_session *sm_lookup_session(unsigned long long id)
--{
--      struct ksmbd_session *sess;
--
--      g_rw_lock_reader_lock(&sessions_table_lock);
--      sess = __sm_lookup_session(id);
--      if (sess)
--              sess = __get_session(sess);
--      g_rw_lock_reader_unlock(&sessions_table_lock);
--      return sess;
--}
--
--int sm_handle_tree_connect(unsigned long long id,
--                         struct ksmbd_user *user,
--                         struct ksmbd_tree_conn *tree_conn)
--{
--      struct ksmbd_session *sess, *lookup;
--
--retry:
--      sess = sm_lookup_session(id);
--      if (!sess) {
--              sess = new_ksmbd_session(id, user);
--              if (!sess)
--                      return -EINVAL;
--
--              g_rw_lock_writer_lock(&sessions_table_lock);
--              lookup = __sm_lookup_session(id);
--              if (lookup)
--                      lookup = __get_session(lookup);
--              if (lookup) {
--                      kill_ksmbd_session(sess);
--                      sess = lookup;
--              }
--              if (!g_hash_table_insert(sessions_table, &(sess->id), sess)) {
--                      kill_ksmbd_session(sess);
--                      sess = NULL;
--              }
--              g_rw_lock_writer_unlock(&sessions_table_lock);
--
--              if (!sess)
--                      goto retry;
--      }
--
--      g_rw_lock_writer_lock(&sess->update_lock);
--      sess->tree_conns = g_list_insert(sess->tree_conns, tree_conn, -1);
--      g_rw_lock_writer_unlock(&sess->update_lock);
--      return 0;
--}
--
--int sm_check_sessions_capacity(unsigned long long id)
--{
--      int ret = 0;
--      struct ksmbd_session *sess;
--
--      sess = sm_lookup_session(id);
--      if (sess) {
--              __put_session(sess);
--              return ret;
--      }
--
--      if (g_atomic_int_add(&global_conf.sessions_cap, -1) < 1) {
--              ret = -EINVAL;
--              g_atomic_int_inc(&global_conf.sessions_cap);
--      }
--      return ret;
--}
--
--static gint lookup_tree_conn(gconstpointer data, gconstpointer user_data)
--{
--      struct ksmbd_tree_conn *tree_conn = (struct ksmbd_tree_conn *)data;
--      struct ksmbd_tree_conn *dummy = (struct ksmbd_tree_conn *)user_data;
--
--      if (tree_conn->id == dummy->id)
--              return 0;
--      return 1;
--}
--
--int sm_handle_tree_disconnect(unsigned long long sess_id,
--                            unsigned long long tree_conn_id)
--{
--      struct ksmbd_tree_conn dummy;
--      struct ksmbd_session *sess;
--      GList *tc_list;
--
--      sess = sm_lookup_session(sess_id);
--      if (!sess)
--              return 0;
--
--      g_atomic_int_inc(&global_conf.sessions_cap);
--      g_rw_lock_writer_lock(&sess->update_lock);
--      dummy.id = tree_conn_id;
--      tc_list = g_list_find_custom(sess->tree_conns,
--                                   &dummy,
--                                   lookup_tree_conn);
--      if (tc_list) {
--              struct ksmbd_tree_conn *tree_conn;
--
--              tree_conn = (struct ksmbd_tree_conn *)tc_list->data;
--              sess->tree_conns = g_list_remove(sess->tree_conns, tree_conn);
--              sess->ref_counter--;
--              tcm_tree_conn_free(tree_conn);
--      }
--      g_rw_lock_writer_unlock(&sess->update_lock);
--
--      put_ksmbd_user(sess->user);
--      __put_session(sess);
--      return 0;
--}
--
--void sm_destroy(void)
--{
--      if (sessions_table) {
--              sm_clear_sessions();
--              g_hash_table_destroy(sessions_table);
--      }
--      g_rw_lock_clear(&sessions_table_lock);
--}
--
--int sm_init(void)
--{
--      sessions_table = g_hash_table_new(g_int64_hash, g_int64_equal);
--      if (!sessions_table)
--              return -ENOMEM;
--      g_rw_lock_init(&sessions_table_lock);
--      return 0;
--}
---- /dev/null
-+++ b/tools/management/session.c
-@@ -0,0 +1,235 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <glib.h>
-+
-+#include "linux/ksmbd_server.h"
-+#include "management/session.h"
-+#include "management/tree_conn.h"
-+#include "management/user.h"
-+#include "tools.h"
-+
-+static GHashTable     *sessions_table;
-+static GRWLock                sessions_table_lock;
-+
-+static void __free_func(gpointer data, gpointer user_data)
-+{
-+      struct ksmbd_tree_conn *tree_conn;
-+
-+      tree_conn = (struct ksmbd_tree_conn *)data;
-+      tcm_tree_conn_free(tree_conn);
-+}
-+
-+static void kill_ksmbd_session(struct ksmbd_session *sess)
-+{
-+      g_list_foreach(sess->tree_conns, __free_func, NULL);
-+      g_list_free(sess->tree_conns);
-+      g_rw_lock_clear(&sess->update_lock);
-+      g_free(sess);
-+}
-+
-+static struct ksmbd_session *new_ksmbd_session(unsigned long long id,
-+                                             struct ksmbd_user *user)
-+{
-+      struct ksmbd_session *sess;
-+
-+      sess = g_try_malloc0(sizeof(struct ksmbd_session));
-+      if (!sess)
-+              return NULL;
-+
-+      g_rw_lock_init(&sess->update_lock);
-+      sess->ref_counter = 1;
-+      sess->id = id;
-+      sess->user = user;
-+      return sess;
-+}
-+
-+static void free_hash_entry(gpointer k, gpointer s, gpointer user_data)
-+{
-+      kill_ksmbd_session(s);
-+}
-+
-+static void sm_clear_sessions(void)
-+{
-+      g_hash_table_foreach(sessions_table, free_hash_entry, NULL);
-+}
-+
-+static int __sm_remove_session(struct ksmbd_session *sess)
-+{
-+      int ret = -EINVAL;
-+
-+      g_rw_lock_writer_lock(&sessions_table_lock);
-+      if (g_hash_table_remove(sessions_table, &sess->id))
-+              ret = 0;
-+      g_rw_lock_writer_unlock(&sessions_table_lock);
-+
-+      if (!ret)
-+              kill_ksmbd_session(sess);
-+      return ret;
-+}
-+
-+static struct ksmbd_session *__get_session(struct ksmbd_session *sess)
-+{
-+      struct ksmbd_session *ret = NULL;
-+
-+      g_rw_lock_writer_lock(&sess->update_lock);
-+      if (sess->ref_counter != 0) {
-+              sess->ref_counter++;
-+              ret = sess;
-+      } else {
-+              ret = NULL;
-+      }
-+      g_rw_lock_writer_unlock(&sess->update_lock);
-+      return ret;
-+}
-+
-+static void __put_session(struct ksmbd_session *sess)
-+{
-+      int drop = 0;
-+
-+      g_rw_lock_writer_lock(&sess->update_lock);
-+      sess->ref_counter--;
-+      drop = !sess->ref_counter;
-+      g_rw_lock_writer_unlock(&sess->update_lock);
-+
-+      if (drop)
-+              __sm_remove_session(sess);
-+}
-+
-+static struct ksmbd_session *__sm_lookup_session(unsigned long long id)
-+{
-+      return g_hash_table_lookup(sessions_table, &id);
-+}
-+
-+static struct ksmbd_session *sm_lookup_session(unsigned long long id)
-+{
-+      struct ksmbd_session *sess;
-+
-+      g_rw_lock_reader_lock(&sessions_table_lock);
-+      sess = __sm_lookup_session(id);
-+      if (sess)
-+              sess = __get_session(sess);
-+      g_rw_lock_reader_unlock(&sessions_table_lock);
-+      return sess;
-+}
-+
-+int sm_handle_tree_connect(unsigned long long id,
-+                         struct ksmbd_user *user,
-+                         struct ksmbd_tree_conn *tree_conn)
-+{
-+      struct ksmbd_session *sess, *lookup;
-+
-+retry:
-+      sess = sm_lookup_session(id);
-+      if (!sess) {
-+              sess = new_ksmbd_session(id, user);
-+              if (!sess)
-+                      return -EINVAL;
-+
-+              g_rw_lock_writer_lock(&sessions_table_lock);
-+              lookup = __sm_lookup_session(id);
-+              if (lookup)
-+                      lookup = __get_session(lookup);
-+              if (lookup) {
-+                      kill_ksmbd_session(sess);
-+                      sess = lookup;
-+              }
-+              if (!g_hash_table_insert(sessions_table, &(sess->id), sess)) {
-+                      kill_ksmbd_session(sess);
-+                      sess = NULL;
-+              }
-+              g_rw_lock_writer_unlock(&sessions_table_lock);
-+
-+              if (!sess)
-+                      goto retry;
-+      }
-+
-+      g_rw_lock_writer_lock(&sess->update_lock);
-+      sess->tree_conns = g_list_insert(sess->tree_conns, tree_conn, -1);
-+      g_rw_lock_writer_unlock(&sess->update_lock);
-+      return 0;
-+}
-+
-+int sm_check_sessions_capacity(unsigned long long id)
-+{
-+      int ret = 0;
-+      struct ksmbd_session *sess;
-+
-+      sess = sm_lookup_session(id);
-+      if (sess) {
-+              __put_session(sess);
-+              return ret;
-+      }
-+
-+      if (g_atomic_int_add(&global_conf.sessions_cap, -1) < 1) {
-+              ret = -EINVAL;
-+              g_atomic_int_inc(&global_conf.sessions_cap);
-+      }
-+      return ret;
-+}
-+
-+static gint lookup_tree_conn(gconstpointer data, gconstpointer user_data)
-+{
-+      struct ksmbd_tree_conn *tree_conn = (struct ksmbd_tree_conn *)data;
-+      struct ksmbd_tree_conn *dummy = (struct ksmbd_tree_conn *)user_data;
-+
-+      if (tree_conn->id == dummy->id)
-+              return 0;
-+      return 1;
-+}
-+
-+int sm_handle_tree_disconnect(unsigned long long sess_id,
-+                            unsigned long long tree_conn_id)
-+{
-+      struct ksmbd_tree_conn dummy;
-+      struct ksmbd_session *sess;
-+      GList *tc_list;
-+
-+      sess = sm_lookup_session(sess_id);
-+      if (!sess)
-+              return 0;
-+
-+      g_atomic_int_inc(&global_conf.sessions_cap);
-+      g_rw_lock_writer_lock(&sess->update_lock);
-+      dummy.id = tree_conn_id;
-+      tc_list = g_list_find_custom(sess->tree_conns,
-+                                   &dummy,
-+                                   lookup_tree_conn);
-+      if (tc_list) {
-+              struct ksmbd_tree_conn *tree_conn;
-+
-+              tree_conn = (struct ksmbd_tree_conn *)tc_list->data;
-+              sess->tree_conns = g_list_remove(sess->tree_conns, tree_conn);
-+              sess->ref_counter--;
-+              tcm_tree_conn_free(tree_conn);
-+      }
-+      g_rw_lock_writer_unlock(&sess->update_lock);
-+
-+      put_ksmbd_user(sess->user);
-+      __put_session(sess);
-+      return 0;
-+}
-+
-+void sm_destroy(void)
-+{
-+      if (sessions_table) {
-+              sm_clear_sessions();
-+              g_hash_table_destroy(sessions_table);
-+      }
-+      g_rw_lock_clear(&sessions_table_lock);
-+}
-+
-+int sm_init(void)
-+{
-+      sessions_table = g_hash_table_new(g_int64_hash, g_int64_equal);
-+      if (!sessions_table)
-+              return -ENOMEM;
-+      g_rw_lock_init(&sessions_table_lock);
-+      return 0;
-+}
---- a/lib/management/share.c
-+++ /dev/null
-@@ -1,868 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <stdlib.h>
--#include <string.h>
--#include <glib.h>
--#include <sys/types.h>
--#include <pwd.h>
--#include <grp.h>
--
--#include "config_parser.h"
--#include "linux/ksmbd_server.h"
--#include "management/share.h"
--#include "management/user.h"
--#include "ksmbdtools.h"
--
--#define KSMBD_SHARE_STATE_FREEING     1
--
--/*
-- * WARNING:
-- *
-- * This must match KSMBD_SHARE_CONF enum 1:1.
-- * Add new entries ONLY to the bottom.
-- */
--char *KSMBD_SHARE_CONF[KSMBD_SHARE_CONF_MAX] = {
--      "comment",                              /* 0 */
--      "path",
--      "guest ok",
--      "guest account",
--      "read only",
--      "browseable",                           /* 5 */
--      "write ok",
--      "writeable",
--      "store dos attributes",
--      "oplocks",
--      "create mask",                          /* 10 */
--      "directory mask",
--      "force create mode",
--      "force directory mode",
--      "force group",
--      "force user",                           /* 15 */
--      "hide dot files",
--      "valid users",
--      "invalid users",
--      "read list",
--      "write list",                           /* 20 */
--      "admin users",
--      "hosts allow",
--      "hosts deny",
--      "max connections",
--      "veto files",                           /* 25 */
--      "inherit owner",
--      "follow symlinks",
--      "vfs objects",
--      "writable",
--};
--
--static GHashTable     *shares_table;
--static GRWLock                shares_table_lock;
--
--int shm_share_config(char *k, enum KSMBD_SHARE_CONF c)
--{
--      if (c >= KSMBD_SHARE_CONF_MAX)
--              return 0;
--
--      return !cp_key_cmp(k, KSMBD_SHARE_CONF[c]);
--}
--
--static void list_hosts_callback(gpointer k, gpointer v, gpointer user_data)
--{
--      free(k);
--      free(v);
--}
--
--static void free_hosts_map(GHashTable *map)
--{
--      if (map) {
--              g_hash_table_foreach(map, list_hosts_callback, NULL);
--              g_hash_table_destroy(map);
--      }
--}
--
--static void list_user_callback(gpointer k, gpointer u, gpointer user_data)
--{
--      put_ksmbd_user((struct ksmbd_user *)u);
--}
--
--static void free_user_map(GHashTable *map)
--{
--      if (map) {
--              g_hash_table_foreach(map, list_user_callback, NULL);
--              g_hash_table_destroy(map);
--      }
--}
--
--static void kill_ksmbd_share(struct ksmbd_share *share)
--{
--      int i;
--
--      pr_debug("Kill share `%s'\n", share->name);
--
--      for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++)
--              free_user_map(share->maps[i]);
--
--      free_hosts_map(share->hosts_allow_map);
--      free_hosts_map(share->hosts_deny_map);
--
--      g_rw_lock_clear(&share->maps_lock);
--
--      free(share->name);
--      free(share->path);
--      free(share->comment);
--      free(share->veto_list);
--      free(share->guest_account);
--      g_rw_lock_clear(&share->update_lock);
--      g_free(share);
--}
--
--static int __shm_remove_share(struct ksmbd_share *share)
--{
--      int ret = 0;
--
--      if (share->state != KSMBD_SHARE_STATE_FREEING) {
--              g_rw_lock_writer_lock(&shares_table_lock);
--              if (!g_hash_table_remove(shares_table, share->name))
--                      ret = -EINVAL;
--              g_rw_lock_writer_unlock(&shares_table_lock);
--      }
--      if (!ret)
--              kill_ksmbd_share(share);
--      return ret;
--}
--
--struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share)
--{
--      g_rw_lock_writer_lock(&share->update_lock);
--      if (share->ref_count != 0) {
--              share->ref_count++;
--              g_rw_lock_writer_unlock(&share->update_lock);
--      } else {
--              g_rw_lock_writer_unlock(&share->update_lock);
--              share = NULL;
--      }
--
--      return share;
--}
--
--void put_ksmbd_share(struct ksmbd_share *share)
--{
--      int drop;
--
--      if (!share)
--              return;
--
--      g_rw_lock_writer_lock(&share->update_lock);
--      share->ref_count--;
--      drop = !share->ref_count;
--      g_rw_lock_writer_unlock(&share->update_lock);
--
--      if (!drop)
--              return;
--
--      __shm_remove_share(share);
--}
--
--static gboolean put_share_callback(gpointer _k, gpointer _v, gpointer data)
--{
--      struct ksmbd_share *share = (struct ksmbd_share *)_v;
--
--      share->state = KSMBD_SHARE_STATE_FREEING;
--      put_ksmbd_share(share);
--      return TRUE;
--}
--
--void shm_remove_all_shares(void)
--{
--      g_rw_lock_writer_lock(&shares_table_lock);
--      g_hash_table_foreach_remove(shares_table, put_share_callback, NULL);
--      g_rw_lock_writer_unlock(&shares_table_lock);
--}
--
--static struct ksmbd_share *new_ksmbd_share(void)
--{
--      struct ksmbd_share *share;
--      int i;
--
--      share = g_try_malloc0(sizeof(struct ksmbd_share));
--      if (!share)
--              return NULL;
--
--      share->ref_count = 1;
--      /*
--       * Create maps as needed. NULL maps means that share
--       * does not have a corresponding shmbconf entry.
--       */
--      for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++)
--              share->maps[i] = NULL;
--
--      share->hosts_allow_map = NULL;
--      share->hosts_deny_map = NULL;
--      g_rw_lock_init(&share->maps_lock);
--      g_rw_lock_init(&share->update_lock);
--
--      return share;
--}
--
--static void free_hash_entry(gpointer k, gpointer s, gpointer user_data)
--{
--      kill_ksmbd_share(s);
--}
--
--static void shm_clear_shares(void)
--{
--      g_hash_table_foreach(shares_table, free_hash_entry, NULL);
--}
--
--void shm_destroy(void)
--{
--      if (shares_table) {
--              shm_clear_shares();
--              g_hash_table_destroy(shares_table);
--      }
--      g_rw_lock_clear(&shares_table_lock);
--}
--
--static char *shm_casefold_share_name(const char *name, size_t len)
--{
--      char *nfdi_name, *nfdicf_name;
--
--      nfdi_name = g_utf8_normalize(name, len, G_NORMALIZE_NFD);
--      if (!nfdi_name)
--              goto out_ascii;
--
--      nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name));
--      g_free(nfdi_name);
--      return nfdicf_name;
--out_ascii:
--      g_free(nfdi_name);
--      return g_ascii_strdown(name, len);
--}
--
--guint shm_share_name_hash(gconstpointer name)
--{
--      char *cf_name;
--      guint hash;
--
--      cf_name = shm_casefold_share_name(name, strlen(name));
--      hash = g_str_hash(cf_name);
--      g_free(cf_name);
--      return hash;
--}
--
--gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname)
--{
--      char *cf_lname, *cf_rname;
--      gboolean equal;
--
--      cf_lname = shm_casefold_share_name(lname, strlen(lname));
--      cf_rname = shm_casefold_share_name(rname, strlen(rname));
--      equal = g_str_equal(cf_lname, cf_rname);
--      g_free(cf_lname);
--      g_free(cf_rname);
--      return equal;
--}
--
--int shm_init(void)
--{
--      shares_table = g_hash_table_new(shm_share_name_hash,
--                                      shm_share_name_equal);
--      if (!shares_table)
--              return -ENOMEM;
--      g_rw_lock_init(&shares_table_lock);
--      return 0;
--}
--
--static struct ksmbd_share *__shm_lookup_share(char *name)
--{
--      return g_hash_table_lookup(shares_table, name);
--}
--
--struct ksmbd_share *shm_lookup_share(char *name)
--{
--      struct ksmbd_share *share, *ret;
--
--      g_rw_lock_reader_lock(&shares_table_lock);
--      share = __shm_lookup_share(name);
--      if (share) {
--              ret = get_ksmbd_share(share);
--              if (!ret)
--                      share = NULL;
--      }
--      g_rw_lock_reader_unlock(&shares_table_lock);
--      return share;
--}
--
--static GHashTable *parse_list(GHashTable *map, char **list, char grc)
--{
--      int i;
--
--      if (!list)
--              return map;
--
--      if (!map)
--              map = g_hash_table_new(g_str_hash, g_str_equal);
--      if (!map)
--              return map;
--
--      for (i = 0;  list[i] != NULL; i++) {
--              struct ksmbd_user *user;
--              char *p = list[i];
--
--              p = cp_ltrim(p);
--              if (!p)
--                      continue;
--
--              if (*p == grc) {
--                      struct group *gr;
--
--                      gr = getgrnam(p + 1);
--                      if (gr)
--                              parse_list(map, gr->gr_mem, 0x00);
--                      continue;
--              }
--
--              user = usm_lookup_user(p);
--              if (!user) {
--                      pr_info("Drop non-existing user `%s'\n", p);
--                      continue;
--              }
--
--              if (g_hash_table_lookup(map, user->name)) {
--                      pr_debug("User `%s' already exists in a map\n",
--                               user->name);
--                      continue;
--              }
--
--              g_hash_table_insert(map, user->name, user);
--      }
--
--      return map;
--}
--
--static void make_veto_list(struct ksmbd_share *share)
--{
--      int i;
--
--      for (i = 0; i < share->veto_list_sz; i++) {
--              if (share->veto_list[i] == '/')
--                      share->veto_list[i] = 0x00;
--      }
--}
--
--static void force_group(struct ksmbd_share *share, char *name)
--{
--      struct group *grp;
--
--      grp = getgrnam(name);
--      if (grp) {
--              share->force_gid = grp->gr_gid;
--              if (share->force_gid == KSMBD_SHARE_INVALID_GID)
--                      pr_err("Invalid force GID: %u\n", share->force_gid);
--      } else
--              pr_err("Unable to lookup up `/etc/group' entry: %s\n", name);
--}
--
--static void force_user(struct ksmbd_share *share, char *name)
--{
--      struct passwd *passwd;
--
--      passwd = getpwnam(name);
--      if (passwd) {
--              share->force_uid = passwd->pw_uid;
--              /*
--               * smb.conf 'force group' has higher priority than
--               * 'force user'.
--               */
--              if (share->force_gid == KSMBD_SHARE_INVALID_GID)
--                      share->force_gid = passwd->pw_gid;
--              if (share->force_uid == KSMBD_SHARE_INVALID_UID ||
--                              share->force_gid == KSMBD_SHARE_INVALID_GID)
--                      pr_err("Invalid force UID/GID: %u/%u\n",
--                                      share->force_uid, share->force_gid);
--      } else {
--              pr_err("Unable to lookup up `/etc/passwd' entry: %s\n", name);
--      }
--}
--
--static void process_group_kv(gpointer _k, gpointer _v, gpointer user_data)
--{
--      struct ksmbd_share *share = user_data;
--      char *k = _k;
--      char *v = _v;
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_COMMENT)) {
--              share->comment = cp_get_group_kv_string(v);
--              if (share->comment == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_PATH)) {
--              share->path = cp_get_group_kv_string(v);
--              if (share->path == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_OK)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_ACCOUNT)) {
--              struct ksmbd_user *user;
--
--              if (usm_add_new_user(cp_get_group_kv_string(_v),
--                                   g_strdup("NULL"))) {
--                      pr_err("Unable to add guest account\n");
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--                      return;
--              }
--
--              user = usm_lookup_user(_v);
--              if (user) {
--                      set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT);
--                      put_ksmbd_user(user);
--              }
--              share->guest_account = cp_get_group_kv_string(_v);
--              if (!share->guest_account)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_READ_ONLY)) {
--              if (cp_get_group_kv_bool(v)) {
--                      set_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
--              } else {
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
--                      set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
--              }
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_BROWSEABLE)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
--              else
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_OK) ||
--                      shm_share_config(k, KSMBD_SHARE_CONF_WRITEABLE) ||
--                      shm_share_config(k, KSMBD_SHARE_CONF_WRITABLE)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
--              else
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_STORE_DOS_ATTRIBUTES)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
--              else
--                      clear_share_flag(share,
--                                      KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_OPLOCKS)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
--              else
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_CREATE_MASK)) {
--              share->create_mask = cp_get_group_kv_long_base(v, 8);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_DIRECTORY_MASK)) {
--              share->directory_mask = cp_get_group_kv_long_base(v, 8);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_CREATE_MODE)) {
--              share->force_create_mode = cp_get_group_kv_long_base(v, 8);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_DIRECTORY_MODE)) {
--              share->force_directory_mode = cp_get_group_kv_long_base(v, 8);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_GROUP)) {
--              force_group(share, v);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_USER)) {
--              force_user(share, v);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_HIDE_DOT_FILES)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
--              else
--                      clear_share_flag(share,
--                              KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_VALID_USERS)) {
--              char **users_list;
--
--              users_list = cp_get_group_kv_list(v);
--              share->maps[KSMBD_SHARE_VALID_USERS_MAP] =
--                      parse_list(share->maps[KSMBD_SHARE_VALID_USERS_MAP],
--                                 users_list, '@');
--              if (share->maps[KSMBD_SHARE_VALID_USERS_MAP] == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(users_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_INVALID_USERS)) {
--              char **users_list;
--
--              users_list = cp_get_group_kv_list(v);
--              share->maps[KSMBD_SHARE_INVALID_USERS_MAP] =
--                      parse_list(share->maps[KSMBD_SHARE_INVALID_USERS_MAP],
--                                 users_list, '@');
--              if (share->maps[KSMBD_SHARE_INVALID_USERS_MAP] == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(users_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_READ_LIST)) {
--              char **users_list;
--
--              users_list = cp_get_group_kv_list(v);
--              share->maps[KSMBD_SHARE_READ_LIST_MAP] =
--                      parse_list(share->maps[KSMBD_SHARE_READ_LIST_MAP],
--                                 users_list, '@');
--              if (share->maps[KSMBD_SHARE_READ_LIST_MAP] == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(users_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_LIST)) {
--              char **users_list;
--
--              users_list = cp_get_group_kv_list(v);
--              share->maps[KSMBD_SHARE_WRITE_LIST_MAP] =
--                      parse_list(share->maps[KSMBD_SHARE_WRITE_LIST_MAP],
--                                 users_list, '@');
--              if (share->maps[KSMBD_SHARE_WRITE_LIST_MAP] == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(users_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_ADMIN_USERS)) {
--              char **users_list;
--
--              users_list = cp_get_group_kv_list(v);
--              share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] =
--                      parse_list(share->maps[KSMBD_SHARE_ADMIN_USERS_MAP],
--                                 users_list, '@');
--              if (share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(users_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_ALLOW)) {
--              char **hosts_list;
--
--              hosts_list = cp_get_group_kv_list(v);
--              share->hosts_allow_map = parse_list(share->hosts_allow_map,
--                                                  hosts_list, 0x00);
--              if (share->hosts_allow_map == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(hosts_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_DENY)) {
--              char **hosts_list;
--
--              hosts_list = cp_get_group_kv_list(v);
--              share->hosts_deny_map = parse_list(share->hosts_deny_map,
--                                                 hosts_list, 0x00);
--              if (share->hosts_deny_map == NULL)
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              cp_group_kv_list_free(hosts_list);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_MAX_CONNECTIONS)) {
--              share->max_connections = cp_get_group_kv_long_base(v, 10);
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_VETO_FILES)) {
--              share->veto_list = cp_get_group_kv_string(v + 1);
--              if (share->veto_list == NULL) {
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
--              } else {
--                      share->veto_list_sz = strlen(share->veto_list);
--                      make_veto_list(share);
--              }
--              return;
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_INHERIT_OWNER)) {
--              if (cp_get_group_kv_bool(v))
--                      set_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER);
--              else
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER);
--      }
--
--      if (shm_share_config(k, KSMBD_SHARE_CONF_VFS_OBJECTS)) {
--              char *p;
--              int i;
--              char **objects = cp_get_group_kv_list(v);
--
--              if (objects) {
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR);
--                      clear_share_flag(share, KSMBD_SHARE_FLAG_STREAMS);
--                      for (i = 0;  objects[i] != NULL; i++) {
--                              p = cp_ltrim(objects[i]);
--                              if (!p)
--                                      continue;
--                              if (!strcmp(p, "acl_xattr"))
--                                      set_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR);
--                              else if (!strcmp(p, "streams_xattr"))
--                                      set_share_flag(share, KSMBD_SHARE_FLAG_STREAMS);
--                      }
--                      cp_group_kv_list_free(objects);
--              }
--      }
--
--}
--
--static void fixup_missing_fields(struct ksmbd_share *share)
--{
--      if (!share->comment)
--              share->comment = strdup("");
--}
--
--static void init_share_from_group(struct ksmbd_share *share,
--                               struct smbconf_group *group)
--{
--      share->name = g_strdup(group->name);
--      share->create_mask = KSMBD_SHARE_DEFAULT_CREATE_MASK;
--      share->directory_mask = KSMBD_SHARE_DEFAULT_DIRECTORY_MASK;
--      share->force_create_mode = 0;
--      share->force_directory_mode = 0;
--
--      share->force_uid = KSMBD_SHARE_INVALID_UID;
--      share->force_gid = KSMBD_SHARE_INVALID_GID;
--
--      set_share_flag(share, KSMBD_SHARE_FLAG_AVAILABLE);
--      set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
--      set_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
--      set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
--      set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
--      set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
--
--      if (!g_ascii_strcasecmp(share->name, "ipc$"))
--              set_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
--
--      if (group->cb_mode == GROUPS_CALLBACK_REINIT)
--              set_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
--
--      g_hash_table_foreach(group->kv, process_group_kv, share);
--
--      fixup_missing_fields(share);
--}
--
--int shm_add_new_share(struct smbconf_group *group)
--{
--      int ret = 0;
--      struct ksmbd_share *share = new_ksmbd_share();
--
--      if (!share)
--              return -ENOMEM;
--
--      init_share_from_group(share, group);
--      if (test_share_flag(share, KSMBD_SHARE_FLAG_INVALID)) {
--              pr_err("Share `%s' is invalid\n", share->name);
--              kill_ksmbd_share(share);
--              return 0;
--      }
--
--      g_rw_lock_writer_lock(&shares_table_lock);
--      if (__shm_lookup_share(share->name)) {
--              g_rw_lock_writer_unlock(&shares_table_lock);
--              pr_info("Share `%s' already exists\n", share->name);
--              kill_ksmbd_share(share);
--              return 0;
--      }
--
--      pr_debug("New share `%s'\n", share->name);
--      if (!g_hash_table_insert(shares_table, share->name, share)) {
--              kill_ksmbd_share(share);
--              ret = -EINVAL;
--      }
--      g_rw_lock_writer_unlock(&shares_table_lock);
--      return ret;
--}
--
--int shm_lookup_users_map(struct ksmbd_share *share,
--                        enum share_users map,
--                        char *name)
--{
--      int ret = -ENOENT;
--
--      if (map >= KSMBD_SHARE_USERS_MAX) {
--              pr_err("Invalid users map index: %d\n", map);
--              return 0;
--      }
--
--      if (!share->maps[map])
--              return -EINVAL;
--
--      g_rw_lock_reader_lock(&share->maps_lock);
--      if (g_hash_table_lookup(share->maps[map], name))
--              ret = 0;
--      g_rw_lock_reader_unlock(&share->maps_lock);
--
--      return ret;
--}
--
--/*
-- * FIXME
-- * Do a real hosts lookup. IP masks, etc.
-- */
--int shm_lookup_hosts_map(struct ksmbd_share *share,
--                        enum share_hosts map,
--                        char *host)
--{
--      GHashTable *lookup_map = NULL;
--      int ret = -ENOENT;
--
--      if (map >= KSMBD_SHARE_HOSTS_MAX) {
--              pr_err("Invalid hosts map index: %d\n", map);
--              return 0;
--      }
--
--      if (map == KSMBD_SHARE_HOSTS_ALLOW_MAP)
--              lookup_map = share->hosts_allow_map;
--      if (map == KSMBD_SHARE_HOSTS_DENY_MAP)
--              lookup_map = share->hosts_deny_map;
--
--      if (!lookup_map)
--              return -EINVAL;
--
--      g_rw_lock_reader_lock(&share->maps_lock);
--      if (g_hash_table_lookup(lookup_map, host))
--              ret = 0;
--      g_rw_lock_reader_unlock(&share->maps_lock);
--
--      return ret;
--}
--
--int shm_open_connection(struct ksmbd_share *share)
--{
--      int ret = 0;
--
--      g_rw_lock_writer_lock(&share->update_lock);
--      share->num_connections++;
--      if (share->max_connections) {
--              if (share->num_connections >= share->max_connections)
--                      ret = -EINVAL;
--      }
--      g_rw_lock_writer_unlock(&share->update_lock);
--      return ret;
--}
--
--int shm_close_connection(struct ksmbd_share *share)
--{
--      if (!share)
--              return 0;
--
--      g_rw_lock_writer_lock(&share->update_lock);
--      share->num_connections--;
--      g_rw_lock_writer_unlock(&share->update_lock);
--      return 0;
--}
--
--void for_each_ksmbd_share(walk_shares cb, gpointer user_data)
--{
--      g_rw_lock_reader_lock(&shares_table_lock);
--      g_hash_table_foreach(shares_table, cb, user_data);
--      g_rw_lock_reader_unlock(&shares_table_lock);
--}
--
--int shm_share_config_payload_size(struct ksmbd_share *share)
--{
--      int sz = 1;
--
--      if (share && !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
--              if (share->path)
--                      sz += strlen(share->path);
--              if (global_conf.root_dir)
--                      sz += strlen(global_conf.root_dir) + 1;
--              if (share->veto_list_sz)
--                      sz += share->veto_list_sz + 1;
--      }
--
--      return sz;
--}
--
--int shm_handle_share_config_request(struct ksmbd_share *share,
--                                  struct ksmbd_share_config_response *resp)
--{
--      unsigned char *config_payload;
--
--      if (!share)
--              return -EINVAL;
--
--      resp->flags = share->flags;
--      resp->create_mask = share->create_mask;
--      resp->directory_mask = share->directory_mask;
--      resp->force_create_mode = share->force_create_mode;
--      resp->force_directory_mode = share->force_directory_mode;
--      resp->force_uid = share->force_uid;
--      resp->force_gid = share->force_gid;
--      *resp->share_name = 0x00;
--      strncat(resp->share_name, share->name, KSMBD_REQ_MAX_SHARE_NAME - 1);
--      resp->veto_list_sz = share->veto_list_sz;
--
--      if (test_share_flag(share, KSMBD_SHARE_FLAG_PIPE))
--              return 0;
--
--      if (!share->path)
--              return 0;
--
--      config_payload = KSMBD_SHARE_CONFIG_VETO_LIST(resp);
--      if (resp->veto_list_sz) {
--              memcpy(config_payload,
--                     share->veto_list,
--                     resp->veto_list_sz);
--              config_payload += resp->veto_list_sz + 1;
--      }
--      if (global_conf.root_dir)
--              sprintf(config_payload,
--                      "%s%s",
--                      global_conf.root_dir,
--                      share->path);
--      else
--              sprintf(config_payload, "%s", share->path);
--      return 0;
--}
---- /dev/null
-+++ b/tools/management/share.c
-@@ -0,0 +1,868 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <glib.h>
-+#include <sys/types.h>
-+#include <pwd.h>
-+#include <grp.h>
-+
-+#include "config_parser.h"
-+#include "linux/ksmbd_server.h"
-+#include "management/share.h"
-+#include "management/user.h"
-+#include "tools.h"
-+
-+#define KSMBD_SHARE_STATE_FREEING     1
-+
-+/*
-+ * WARNING:
-+ *
-+ * This must match KSMBD_SHARE_CONF enum 1:1.
-+ * Add new entries ONLY to the bottom.
-+ */
-+char *KSMBD_SHARE_CONF[KSMBD_SHARE_CONF_MAX] = {
-+      "comment",                              /* 0 */
-+      "path",
-+      "guest ok",
-+      "guest account",
-+      "read only",
-+      "browseable",                           /* 5 */
-+      "write ok",
-+      "writeable",
-+      "store dos attributes",
-+      "oplocks",
-+      "create mask",                          /* 10 */
-+      "directory mask",
-+      "force create mode",
-+      "force directory mode",
-+      "force group",
-+      "force user",                           /* 15 */
-+      "hide dot files",
-+      "valid users",
-+      "invalid users",
-+      "read list",
-+      "write list",                           /* 20 */
-+      "admin users",
-+      "hosts allow",
-+      "hosts deny",
-+      "max connections",
-+      "veto files",                           /* 25 */
-+      "inherit owner",
-+      "follow symlinks",
-+      "vfs objects",
-+      "writable",
-+};
-+
-+static GHashTable     *shares_table;
-+static GRWLock                shares_table_lock;
-+
-+int shm_share_config(char *k, enum KSMBD_SHARE_CONF c)
-+{
-+      if (c >= KSMBD_SHARE_CONF_MAX)
-+              return 0;
-+
-+      return !cp_key_cmp(k, KSMBD_SHARE_CONF[c]);
-+}
-+
-+static void list_hosts_callback(gpointer k, gpointer v, gpointer user_data)
-+{
-+      free(k);
-+      free(v);
-+}
-+
-+static void free_hosts_map(GHashTable *map)
-+{
-+      if (map) {
-+              g_hash_table_foreach(map, list_hosts_callback, NULL);
-+              g_hash_table_destroy(map);
-+      }
-+}
-+
-+static void list_user_callback(gpointer k, gpointer u, gpointer user_data)
-+{
-+      put_ksmbd_user((struct ksmbd_user *)u);
-+}
-+
-+static void free_user_map(GHashTable *map)
-+{
-+      if (map) {
-+              g_hash_table_foreach(map, list_user_callback, NULL);
-+              g_hash_table_destroy(map);
-+      }
-+}
-+
-+static void kill_ksmbd_share(struct ksmbd_share *share)
-+{
-+      int i;
-+
-+      pr_debug("Kill share `%s'\n", share->name);
-+
-+      for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++)
-+              free_user_map(share->maps[i]);
-+
-+      free_hosts_map(share->hosts_allow_map);
-+      free_hosts_map(share->hosts_deny_map);
-+
-+      g_rw_lock_clear(&share->maps_lock);
-+
-+      free(share->name);
-+      free(share->path);
-+      free(share->comment);
-+      free(share->veto_list);
-+      free(share->guest_account);
-+      g_rw_lock_clear(&share->update_lock);
-+      g_free(share);
-+}
-+
-+static int __shm_remove_share(struct ksmbd_share *share)
-+{
-+      int ret = 0;
-+
-+      if (share->state != KSMBD_SHARE_STATE_FREEING) {
-+              g_rw_lock_writer_lock(&shares_table_lock);
-+              if (!g_hash_table_remove(shares_table, share->name))
-+                      ret = -EINVAL;
-+              g_rw_lock_writer_unlock(&shares_table_lock);
-+      }
-+      if (!ret)
-+              kill_ksmbd_share(share);
-+      return ret;
-+}
-+
-+struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share)
-+{
-+      g_rw_lock_writer_lock(&share->update_lock);
-+      if (share->ref_count != 0) {
-+              share->ref_count++;
-+              g_rw_lock_writer_unlock(&share->update_lock);
-+      } else {
-+              g_rw_lock_writer_unlock(&share->update_lock);
-+              share = NULL;
-+      }
-+
-+      return share;
-+}
-+
-+void put_ksmbd_share(struct ksmbd_share *share)
-+{
-+      int drop;
-+
-+      if (!share)
-+              return;
-+
-+      g_rw_lock_writer_lock(&share->update_lock);
-+      share->ref_count--;
-+      drop = !share->ref_count;
-+      g_rw_lock_writer_unlock(&share->update_lock);
-+
-+      if (!drop)
-+              return;
-+
-+      __shm_remove_share(share);
-+}
-+
-+static gboolean put_share_callback(gpointer _k, gpointer _v, gpointer data)
-+{
-+      struct ksmbd_share *share = (struct ksmbd_share *)_v;
-+
-+      share->state = KSMBD_SHARE_STATE_FREEING;
-+      put_ksmbd_share(share);
-+      return TRUE;
-+}
-+
-+void shm_remove_all_shares(void)
-+{
-+      g_rw_lock_writer_lock(&shares_table_lock);
-+      g_hash_table_foreach_remove(shares_table, put_share_callback, NULL);
-+      g_rw_lock_writer_unlock(&shares_table_lock);
-+}
-+
-+static struct ksmbd_share *new_ksmbd_share(void)
-+{
-+      struct ksmbd_share *share;
-+      int i;
-+
-+      share = g_try_malloc0(sizeof(struct ksmbd_share));
-+      if (!share)
-+              return NULL;
-+
-+      share->ref_count = 1;
-+      /*
-+       * Create maps as needed. NULL maps means that share
-+       * does not have a corresponding shmbconf entry.
-+       */
-+      for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++)
-+              share->maps[i] = NULL;
-+
-+      share->hosts_allow_map = NULL;
-+      share->hosts_deny_map = NULL;
-+      g_rw_lock_init(&share->maps_lock);
-+      g_rw_lock_init(&share->update_lock);
-+
-+      return share;
-+}
-+
-+static void free_hash_entry(gpointer k, gpointer s, gpointer user_data)
-+{
-+      kill_ksmbd_share(s);
-+}
-+
-+static void shm_clear_shares(void)
-+{
-+      g_hash_table_foreach(shares_table, free_hash_entry, NULL);
-+}
-+
-+void shm_destroy(void)
-+{
-+      if (shares_table) {
-+              shm_clear_shares();
-+              g_hash_table_destroy(shares_table);
-+      }
-+      g_rw_lock_clear(&shares_table_lock);
-+}
-+
-+static char *shm_casefold_share_name(const char *name, size_t len)
-+{
-+      char *nfdi_name, *nfdicf_name;
-+
-+      nfdi_name = g_utf8_normalize(name, len, G_NORMALIZE_NFD);
-+      if (!nfdi_name)
-+              goto out_ascii;
-+
-+      nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name));
-+      g_free(nfdi_name);
-+      return nfdicf_name;
-+out_ascii:
-+      g_free(nfdi_name);
-+      return g_ascii_strdown(name, len);
-+}
-+
-+guint shm_share_name_hash(gconstpointer name)
-+{
-+      char *cf_name;
-+      guint hash;
-+
-+      cf_name = shm_casefold_share_name(name, strlen(name));
-+      hash = g_str_hash(cf_name);
-+      g_free(cf_name);
-+      return hash;
-+}
-+
-+gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname)
-+{
-+      char *cf_lname, *cf_rname;
-+      gboolean equal;
-+
-+      cf_lname = shm_casefold_share_name(lname, strlen(lname));
-+      cf_rname = shm_casefold_share_name(rname, strlen(rname));
-+      equal = g_str_equal(cf_lname, cf_rname);
-+      g_free(cf_lname);
-+      g_free(cf_rname);
-+      return equal;
-+}
-+
-+int shm_init(void)
-+{
-+      shares_table = g_hash_table_new(shm_share_name_hash,
-+                                      shm_share_name_equal);
-+      if (!shares_table)
-+              return -ENOMEM;
-+      g_rw_lock_init(&shares_table_lock);
-+      return 0;
-+}
-+
-+static struct ksmbd_share *__shm_lookup_share(char *name)
-+{
-+      return g_hash_table_lookup(shares_table, name);
-+}
-+
-+struct ksmbd_share *shm_lookup_share(char *name)
-+{
-+      struct ksmbd_share *share, *ret;
-+
-+      g_rw_lock_reader_lock(&shares_table_lock);
-+      share = __shm_lookup_share(name);
-+      if (share) {
-+              ret = get_ksmbd_share(share);
-+              if (!ret)
-+                      share = NULL;
-+      }
-+      g_rw_lock_reader_unlock(&shares_table_lock);
-+      return share;
-+}
-+
-+static GHashTable *parse_list(GHashTable *map, char **list, char grc)
-+{
-+      int i;
-+
-+      if (!list)
-+              return map;
-+
-+      if (!map)
-+              map = g_hash_table_new(g_str_hash, g_str_equal);
-+      if (!map)
-+              return map;
-+
-+      for (i = 0;  list[i] != NULL; i++) {
-+              struct ksmbd_user *user;
-+              char *p = list[i];
-+
-+              p = cp_ltrim(p);
-+              if (!p)
-+                      continue;
-+
-+              if (*p == grc) {
-+                      struct group *gr;
-+
-+                      gr = getgrnam(p + 1);
-+                      if (gr)
-+                              parse_list(map, gr->gr_mem, 0x00);
-+                      continue;
-+              }
-+
-+              user = usm_lookup_user(p);
-+              if (!user) {
-+                      pr_info("Drop non-existing user `%s'\n", p);
-+                      continue;
-+              }
-+
-+              if (g_hash_table_lookup(map, user->name)) {
-+                      pr_debug("User `%s' already exists in a map\n",
-+                               user->name);
-+                      continue;
-+              }
-+
-+              g_hash_table_insert(map, user->name, user);
-+      }
-+
-+      return map;
-+}
-+
-+static void make_veto_list(struct ksmbd_share *share)
-+{
-+      int i;
-+
-+      for (i = 0; i < share->veto_list_sz; i++) {
-+              if (share->veto_list[i] == '/')
-+                      share->veto_list[i] = 0x00;
-+      }
-+}
-+
-+static void force_group(struct ksmbd_share *share, char *name)
-+{
-+      struct group *grp;
-+
-+      grp = getgrnam(name);
-+      if (grp) {
-+              share->force_gid = grp->gr_gid;
-+              if (share->force_gid == KSMBD_SHARE_INVALID_GID)
-+                      pr_err("Invalid force GID: %u\n", share->force_gid);
-+      } else
-+              pr_err("Unable to lookup up `/etc/group' entry: %s\n", name);
-+}
-+
-+static void force_user(struct ksmbd_share *share, char *name)
-+{
-+      struct passwd *passwd;
-+
-+      passwd = getpwnam(name);
-+      if (passwd) {
-+              share->force_uid = passwd->pw_uid;
-+              /*
-+               * smb.conf 'force group' has higher priority than
-+               * 'force user'.
-+               */
-+              if (share->force_gid == KSMBD_SHARE_INVALID_GID)
-+                      share->force_gid = passwd->pw_gid;
-+              if (share->force_uid == KSMBD_SHARE_INVALID_UID ||
-+                              share->force_gid == KSMBD_SHARE_INVALID_GID)
-+                      pr_err("Invalid force UID/GID: %u/%u\n",
-+                                      share->force_uid, share->force_gid);
-+      } else {
-+              pr_err("Unable to lookup up `/etc/passwd' entry: %s\n", name);
-+      }
-+}
-+
-+static void process_group_kv(gpointer _k, gpointer _v, gpointer user_data)
-+{
-+      struct ksmbd_share *share = user_data;
-+      char *k = _k;
-+      char *v = _v;
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_COMMENT)) {
-+              share->comment = cp_get_group_kv_string(v);
-+              if (share->comment == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_PATH)) {
-+              share->path = cp_get_group_kv_string(v);
-+              if (share->path == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_OK)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_ACCOUNT)) {
-+              struct ksmbd_user *user;
-+
-+              if (usm_add_new_user(cp_get_group_kv_string(_v),
-+                                   g_strdup("NULL"))) {
-+                      pr_err("Unable to add guest account\n");
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+                      return;
-+              }
-+
-+              user = usm_lookup_user(_v);
-+              if (user) {
-+                      set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT);
-+                      put_ksmbd_user(user);
-+              }
-+              share->guest_account = cp_get_group_kv_string(_v);
-+              if (!share->guest_account)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_READ_ONLY)) {
-+              if (cp_get_group_kv_bool(v)) {
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
-+              } else {
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
-+              }
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_BROWSEABLE)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
-+              else
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_OK) ||
-+                      shm_share_config(k, KSMBD_SHARE_CONF_WRITEABLE) ||
-+                      shm_share_config(k, KSMBD_SHARE_CONF_WRITABLE)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
-+              else
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_STORE_DOS_ATTRIBUTES)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
-+              else
-+                      clear_share_flag(share,
-+                                      KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_OPLOCKS)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
-+              else
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_CREATE_MASK)) {
-+              share->create_mask = cp_get_group_kv_long_base(v, 8);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_DIRECTORY_MASK)) {
-+              share->directory_mask = cp_get_group_kv_long_base(v, 8);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_CREATE_MODE)) {
-+              share->force_create_mode = cp_get_group_kv_long_base(v, 8);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_DIRECTORY_MODE)) {
-+              share->force_directory_mode = cp_get_group_kv_long_base(v, 8);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_GROUP)) {
-+              force_group(share, v);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_USER)) {
-+              force_user(share, v);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_HIDE_DOT_FILES)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
-+              else
-+                      clear_share_flag(share,
-+                              KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_VALID_USERS)) {
-+              char **users_list;
-+
-+              users_list = cp_get_group_kv_list(v);
-+              share->maps[KSMBD_SHARE_VALID_USERS_MAP] =
-+                      parse_list(share->maps[KSMBD_SHARE_VALID_USERS_MAP],
-+                                 users_list, '@');
-+              if (share->maps[KSMBD_SHARE_VALID_USERS_MAP] == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(users_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_INVALID_USERS)) {
-+              char **users_list;
-+
-+              users_list = cp_get_group_kv_list(v);
-+              share->maps[KSMBD_SHARE_INVALID_USERS_MAP] =
-+                      parse_list(share->maps[KSMBD_SHARE_INVALID_USERS_MAP],
-+                                 users_list, '@');
-+              if (share->maps[KSMBD_SHARE_INVALID_USERS_MAP] == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(users_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_READ_LIST)) {
-+              char **users_list;
-+
-+              users_list = cp_get_group_kv_list(v);
-+              share->maps[KSMBD_SHARE_READ_LIST_MAP] =
-+                      parse_list(share->maps[KSMBD_SHARE_READ_LIST_MAP],
-+                                 users_list, '@');
-+              if (share->maps[KSMBD_SHARE_READ_LIST_MAP] == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(users_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_LIST)) {
-+              char **users_list;
-+
-+              users_list = cp_get_group_kv_list(v);
-+              share->maps[KSMBD_SHARE_WRITE_LIST_MAP] =
-+                      parse_list(share->maps[KSMBD_SHARE_WRITE_LIST_MAP],
-+                                 users_list, '@');
-+              if (share->maps[KSMBD_SHARE_WRITE_LIST_MAP] == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(users_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_ADMIN_USERS)) {
-+              char **users_list;
-+
-+              users_list = cp_get_group_kv_list(v);
-+              share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] =
-+                      parse_list(share->maps[KSMBD_SHARE_ADMIN_USERS_MAP],
-+                                 users_list, '@');
-+              if (share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(users_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_ALLOW)) {
-+              char **hosts_list;
-+
-+              hosts_list = cp_get_group_kv_list(v);
-+              share->hosts_allow_map = parse_list(share->hosts_allow_map,
-+                                                  hosts_list, 0x00);
-+              if (share->hosts_allow_map == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(hosts_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_DENY)) {
-+              char **hosts_list;
-+
-+              hosts_list = cp_get_group_kv_list(v);
-+              share->hosts_deny_map = parse_list(share->hosts_deny_map,
-+                                                 hosts_list, 0x00);
-+              if (share->hosts_deny_map == NULL)
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              cp_group_kv_list_free(hosts_list);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_MAX_CONNECTIONS)) {
-+              share->max_connections = cp_get_group_kv_long_base(v, 10);
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_VETO_FILES)) {
-+              share->veto_list = cp_get_group_kv_string(v + 1);
-+              if (share->veto_list == NULL) {
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INVALID);
-+              } else {
-+                      share->veto_list_sz = strlen(share->veto_list);
-+                      make_veto_list(share);
-+              }
-+              return;
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_INHERIT_OWNER)) {
-+              if (cp_get_group_kv_bool(v))
-+                      set_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER);
-+              else
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER);
-+      }
-+
-+      if (shm_share_config(k, KSMBD_SHARE_CONF_VFS_OBJECTS)) {
-+              char *p;
-+              int i;
-+              char **objects = cp_get_group_kv_list(v);
-+
-+              if (objects) {
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR);
-+                      clear_share_flag(share, KSMBD_SHARE_FLAG_STREAMS);
-+                      for (i = 0;  objects[i] != NULL; i++) {
-+                              p = cp_ltrim(objects[i]);
-+                              if (!p)
-+                                      continue;
-+                              if (!strcmp(p, "acl_xattr"))
-+                                      set_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR);
-+                              else if (!strcmp(p, "streams_xattr"))
-+                                      set_share_flag(share, KSMBD_SHARE_FLAG_STREAMS);
-+                      }
-+                      cp_group_kv_list_free(objects);
-+              }
-+      }
-+
-+}
-+
-+static void fixup_missing_fields(struct ksmbd_share *share)
-+{
-+      if (!share->comment)
-+              share->comment = strdup("");
-+}
-+
-+static void init_share_from_group(struct ksmbd_share *share,
-+                               struct smbconf_group *group)
-+{
-+      share->name = g_strdup(group->name);
-+      share->create_mask = KSMBD_SHARE_DEFAULT_CREATE_MASK;
-+      share->directory_mask = KSMBD_SHARE_DEFAULT_DIRECTORY_MASK;
-+      share->force_create_mode = 0;
-+      share->force_directory_mode = 0;
-+
-+      share->force_uid = KSMBD_SHARE_INVALID_UID;
-+      share->force_gid = KSMBD_SHARE_INVALID_GID;
-+
-+      set_share_flag(share, KSMBD_SHARE_FLAG_AVAILABLE);
-+      set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE);
-+      set_share_flag(share, KSMBD_SHARE_FLAG_READONLY);
-+      set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES);
-+      set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS);
-+      set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS);
-+
-+      if (!g_ascii_strcasecmp(share->name, "ipc$"))
-+              set_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
-+
-+      if (group->cb_mode == GROUPS_CALLBACK_REINIT)
-+              set_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
-+
-+      g_hash_table_foreach(group->kv, process_group_kv, share);
-+
-+      fixup_missing_fields(share);
-+}
-+
-+int shm_add_new_share(struct smbconf_group *group)
-+{
-+      int ret = 0;
-+      struct ksmbd_share *share = new_ksmbd_share();
-+
-+      if (!share)
-+              return -ENOMEM;
-+
-+      init_share_from_group(share, group);
-+      if (test_share_flag(share, KSMBD_SHARE_FLAG_INVALID)) {
-+              pr_err("Share `%s' is invalid\n", share->name);
-+              kill_ksmbd_share(share);
-+              return 0;
-+      }
-+
-+      g_rw_lock_writer_lock(&shares_table_lock);
-+      if (__shm_lookup_share(share->name)) {
-+              g_rw_lock_writer_unlock(&shares_table_lock);
-+              pr_info("Share `%s' already exists\n", share->name);
-+              kill_ksmbd_share(share);
-+              return 0;
-+      }
-+
-+      pr_debug("New share `%s'\n", share->name);
-+      if (!g_hash_table_insert(shares_table, share->name, share)) {
-+              kill_ksmbd_share(share);
-+              ret = -EINVAL;
-+      }
-+      g_rw_lock_writer_unlock(&shares_table_lock);
-+      return ret;
-+}
-+
-+int shm_lookup_users_map(struct ksmbd_share *share,
-+                        enum share_users map,
-+                        char *name)
-+{
-+      int ret = -ENOENT;
-+
-+      if (map >= KSMBD_SHARE_USERS_MAX) {
-+              pr_err("Invalid users map index: %d\n", map);
-+              return 0;
-+      }
-+
-+      if (!share->maps[map])
-+              return -EINVAL;
-+
-+      g_rw_lock_reader_lock(&share->maps_lock);
-+      if (g_hash_table_lookup(share->maps[map], name))
-+              ret = 0;
-+      g_rw_lock_reader_unlock(&share->maps_lock);
-+
-+      return ret;
-+}
-+
-+/*
-+ * FIXME
-+ * Do a real hosts lookup. IP masks, etc.
-+ */
-+int shm_lookup_hosts_map(struct ksmbd_share *share,
-+                        enum share_hosts map,
-+                        char *host)
-+{
-+      GHashTable *lookup_map = NULL;
-+      int ret = -ENOENT;
-+
-+      if (map >= KSMBD_SHARE_HOSTS_MAX) {
-+              pr_err("Invalid hosts map index: %d\n", map);
-+              return 0;
-+      }
-+
-+      if (map == KSMBD_SHARE_HOSTS_ALLOW_MAP)
-+              lookup_map = share->hosts_allow_map;
-+      if (map == KSMBD_SHARE_HOSTS_DENY_MAP)
-+              lookup_map = share->hosts_deny_map;
-+
-+      if (!lookup_map)
-+              return -EINVAL;
-+
-+      g_rw_lock_reader_lock(&share->maps_lock);
-+      if (g_hash_table_lookup(lookup_map, host))
-+              ret = 0;
-+      g_rw_lock_reader_unlock(&share->maps_lock);
-+
-+      return ret;
-+}
-+
-+int shm_open_connection(struct ksmbd_share *share)
-+{
-+      int ret = 0;
-+
-+      g_rw_lock_writer_lock(&share->update_lock);
-+      share->num_connections++;
-+      if (share->max_connections) {
-+              if (share->num_connections >= share->max_connections)
-+                      ret = -EINVAL;
-+      }
-+      g_rw_lock_writer_unlock(&share->update_lock);
-+      return ret;
-+}
-+
-+int shm_close_connection(struct ksmbd_share *share)
-+{
-+      if (!share)
-+              return 0;
-+
-+      g_rw_lock_writer_lock(&share->update_lock);
-+      share->num_connections--;
-+      g_rw_lock_writer_unlock(&share->update_lock);
-+      return 0;
-+}
-+
-+void for_each_ksmbd_share(walk_shares cb, gpointer user_data)
-+{
-+      g_rw_lock_reader_lock(&shares_table_lock);
-+      g_hash_table_foreach(shares_table, cb, user_data);
-+      g_rw_lock_reader_unlock(&shares_table_lock);
-+}
-+
-+int shm_share_config_payload_size(struct ksmbd_share *share)
-+{
-+      int sz = 1;
-+
-+      if (share && !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
-+              if (share->path)
-+                      sz += strlen(share->path);
-+              if (global_conf.root_dir)
-+                      sz += strlen(global_conf.root_dir) + 1;
-+              if (share->veto_list_sz)
-+                      sz += share->veto_list_sz + 1;
-+      }
-+
-+      return sz;
-+}
-+
-+int shm_handle_share_config_request(struct ksmbd_share *share,
-+                                  struct ksmbd_share_config_response *resp)
-+{
-+      unsigned char *config_payload;
-+
-+      if (!share)
-+              return -EINVAL;
-+
-+      resp->flags = share->flags;
-+      resp->create_mask = share->create_mask;
-+      resp->directory_mask = share->directory_mask;
-+      resp->force_create_mode = share->force_create_mode;
-+      resp->force_directory_mode = share->force_directory_mode;
-+      resp->force_uid = share->force_uid;
-+      resp->force_gid = share->force_gid;
-+      *resp->share_name = 0x00;
-+      strncat(resp->share_name, share->name, KSMBD_REQ_MAX_SHARE_NAME - 1);
-+      resp->veto_list_sz = share->veto_list_sz;
-+
-+      if (test_share_flag(share, KSMBD_SHARE_FLAG_PIPE))
-+              return 0;
-+
-+      if (!share->path)
-+              return 0;
-+
-+      config_payload = KSMBD_SHARE_CONFIG_VETO_LIST(resp);
-+      if (resp->veto_list_sz) {
-+              memcpy(config_payload,
-+                     share->veto_list,
-+                     resp->veto_list_sz);
-+              config_payload += resp->veto_list_sz + 1;
-+      }
-+      if (global_conf.root_dir)
-+              sprintf(config_payload,
-+                      "%s%s",
-+                      global_conf.root_dir,
-+                      share->path);
-+      else
-+              sprintf(config_payload, "%s", share->path);
-+      return 0;
-+}
---- a/lib/management/spnego.c
-+++ /dev/null
-@@ -1,348 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2020 LG Electronics
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include "ksmbdtools.h"
--
--#ifndef _GNU_SOURCE
--#define _GNU_SOURCE
--#endif
--
--#include <stdlib.h>
--#include <stdio.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <fcntl.h>
--#include <stdint.h>
--#include <stdbool.h>
--
--#include <linux/ksmbd_server.h>
--#include <management/spnego.h>
--#include <asn1.h>
--#include "spnego_mech.h"
--
--static struct spnego_mech_ctx mech_ctxs[SPNEGO_MAX_MECHS];
--
--static struct spnego_mech_ctx *get_mech(int mech_type)
--{
--      if (mech_type >= SPNEGO_MAX_MECHS)
--              return NULL;
--      return &mech_ctxs[mech_type];
--}
--
--int spnego_init(void)
--{
--      struct spnego_mech_ctx *mech_ctx;
--      int i;
--
--      mech_ctx = &mech_ctxs[SPNEGO_MECH_MSKRB5];
--      mech_ctx->ops = &spnego_mskrb5_operations;
--      if (global_conf.krb5_service_name)
--              mech_ctx->params.krb5.service_name =
--                      strdup(global_conf.krb5_service_name);
--      if (global_conf.krb5_keytab_file)
--              mech_ctx->params.krb5.keytab_name =
--                      strdup(global_conf.krb5_keytab_file);
--
--      mech_ctx = &mech_ctxs[SPNEGO_MECH_KRB5];
--      mech_ctx->ops = &spnego_krb5_operations;
--      if (global_conf.krb5_service_name)
--              mech_ctx->params.krb5.service_name =
--                      strdup(global_conf.krb5_service_name);
--      if (global_conf.krb5_keytab_file)
--              mech_ctx->params.krb5.keytab_name =
--                      strdup(global_conf.krb5_keytab_file);
--
--      for (i = 0; i < SPNEGO_MAX_MECHS; i++) {
--              if (mech_ctxs[i].ops->setup &&
--                              mech_ctxs[i].ops->setup(&mech_ctxs[i])) {
--                      pr_err("Failed to init Kerberos 5\n");
--                      goto out_err;
--              }
--      }
--
--      return 0;
--out_err:
--      for (; i >= 0; i--) {
--              if (mech_ctxs[i].ops->cleanup)
--                      mech_ctxs[i].ops->cleanup(&mech_ctxs[i]);
--      }
--      return -ENOTSUP;
--}
--
--void spnego_destroy(void)
--{
--      int i;
--
--      for (i = 0; i < SPNEGO_MAX_MECHS; i++) {
--              if (mech_ctxs[i].ops && mech_ctxs[i].ops->cleanup)
--                      mech_ctxs[i].ops->cleanup(&mech_ctxs[i]);
--      }
--}
--
--static int compare_oid(unsigned long *oid1, unsigned int oid1len,
--                  unsigned long *oid2, unsigned int oid2len)
--{
--      unsigned int i;
--
--      if (oid1len != oid2len)
--              return 1;
--
--      for (i = 0; i < oid1len; i++) {
--              if (oid1[i] != oid2[i])
--                      return 1;
--      }
--      return 0;
--}
--
--static bool is_supported_mech(unsigned long *oid, unsigned int len,
--                      int *mech_type)
--{
--      if (!compare_oid(oid, len, MSKRB5_OID, ARRAY_SIZE(MSKRB5_OID))) {
--              *mech_type = SPNEGO_MECH_MSKRB5;
--              return true;
--      }
--
--      if (!compare_oid(oid, len, KRB5_OID, ARRAY_SIZE(KRB5_OID))) {
--              *mech_type = SPNEGO_MECH_KRB5;
--              return true;
--      }
--
--      *mech_type = SPNEGO_MAX_MECHS;
--      return false;
--}
--
--static int decode_asn1_header(struct asn1_ctx *ctx, unsigned char **end,
--              unsigned int cls, unsigned int con, unsigned int tag)
--{
--      unsigned int d_cls, d_con, d_tag;
--
--      if (asn1_header_decode(ctx, end, &d_cls, &d_con, &d_tag) == 0 ||
--              (d_cls != cls || d_con != con || d_tag != tag))
--              return -EINVAL;
--      return 0;
--}
--
--static int decode_negTokenInit(unsigned char *negToken, int token_len,
--                      int *mech_type, unsigned char **krb5_ap_req,
--                      unsigned int *req_len)
--{
--      struct asn1_ctx ctx;
--      unsigned char *end, *mech_types_end, *id;
--      unsigned long *oid = NULL;
--      unsigned int len;
--
--      asn1_open(&ctx, negToken, token_len);
--
--      /* GSSAPI header */
--      if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) {
--              pr_debug("Error decoding SPNEGO application tag\n");
--              return -EINVAL;
--      }
--
--      /* SPNEGO oid */
--      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) ||
--                      asn1_oid_decode(&ctx, end, &oid, &len) == 0 ||
--                      compare_oid(oid, len, SPNEGO_OID, SPNEGO_OID_LEN)) {
--              pr_debug("Error decoding SPNEGO OID\n");
--              g_free(oid);
--              return -EINVAL;
--      }
--      g_free(oid);
--
--      /* negoTokenInit */
--      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) ||
--                      decode_asn1_header(&ctx, &end,
--                              ASN1_UNI, ASN1_CON, ASN1_SEQ)) {
--              pr_debug("Error decoding negTokenInit tag\n");
--              return -EINVAL;
--      }
--
--      /* mechTypes */
--      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) ||
--                      decode_asn1_header(&ctx, &end,
--                              ASN1_UNI, ASN1_CON, ASN1_SEQ)) {
--              pr_debug("Error decoding mechTypes tag\n");
--              return -EINVAL;
--      }
--
--      mech_types_end = end;
--      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) ||
--                      asn1_oid_decode(&ctx, end, &oid, &len) == 0) {
--              pr_debug("Error decoding Kerberos 5 OIDs\n");
--              return -EINVAL;
--      }
--
--      if (!is_supported_mech(oid, len, mech_type)) {
--              g_free(oid);
--              pr_debug("Not a supported mechanism\n");
--              return -EINVAL;
--      }
--      g_free(oid);
--
--      ctx.pointer = mech_types_end;
--      /* mechToken */
--      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 2) ||
--                      decode_asn1_header(&ctx, &end,
--                              ASN1_UNI, ASN1_PRI, ASN1_OTS)) {
--              pr_debug("Error decoding krb5_blob\n");
--              return -EINVAL;
--      }
--
--      if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) {
--              pr_debug("Error decoding GSSAPI application tag\n");
--              return -EINVAL;
--      }
--
--      /* Kerberos 5 oid */
--      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI)) {
--              pr_debug("Error decoding Kerberos 5 OID tag\n");
--              return -EINVAL;
--      }
--
--      if (asn1_oid_decode(&ctx, end, &oid, &len) == 0 ||
--                      compare_oid(oid, len, KRB5_OID,
--                              ARRAY_SIZE(KRB5_OID))) {
--              pr_debug("Not a Kerberos 5 OID\n");
--              g_free(oid);
--              return -EINVAL;
--      }
--      g_free(oid);
--
--      /* AP_REQ id */
--      if (asn1_read(&ctx, &id, 2) == 0 || id[0] != 1 || id[1] != 0) {
--              if (id)
--                      free(id);
--              pr_debug("Error decoding AP_REQ ID\n");
--              return -EINVAL;
--      }
--      free(id);
--
--      /* AP_REQ */
--      *req_len = (unsigned int)(ctx.end - ctx.pointer);
--      *krb5_ap_req = ctx.pointer;
--      return 0;
--}
--
--static int encode_negTokenTarg(char *in_blob, int in_len,
--                      const unsigned long *oid, int oid_len,
--                      char **out_blob, int *out_len)
--{
--      unsigned char *buf;
--      unsigned char *sup_oid, *krb5_oid;
--      int sup_oid_len, krb5_oid_len;
--      unsigned int neg_result_len, sup_mech_len, rep_token_len, len;
--
--      if (asn1_oid_encode(oid, oid_len, &sup_oid, &sup_oid_len))
--              return -ENOMEM;
--      if (asn1_oid_encode(KRB5_OID, ARRAY_SIZE(KRB5_OID),
--                      &krb5_oid, &krb5_oid_len)) {
--              g_free(sup_oid);
--              return -ENOMEM;
--      }
--
--      neg_result_len = asn1_header_len(1, 2);
--      sup_mech_len = asn1_header_len(sup_oid_len, 2);
--      rep_token_len = asn1_header_len(krb5_oid_len, 1);
--      rep_token_len += 2 + in_len;
--      rep_token_len = asn1_header_len(rep_token_len, 3);
--
--      *out_len = asn1_header_len(
--                      neg_result_len + sup_mech_len + rep_token_len, 2);
--      *out_blob = g_try_malloc0(*out_len);
--      if (*out_blob == NULL)
--              return -ENOMEM;
--      buf = *out_blob;
--
--      /* negTokenTarg */
--      len = *out_len;
--      asn1_header_encode(&buf,
--                      ASN1_CTX, ASN1_CON, 1,
--                      &len);
--      asn1_header_encode(&buf,
--                      ASN1_UNI, ASN1_CON, ASN1_SEQ,
--                      &len);
--
--      /* negTokenTarg/negResult */
--      len = neg_result_len;
--      asn1_header_encode(&buf,
--                      ASN1_CTX, ASN1_CON, 0,
--                      &len);
--      asn1_header_encode(&buf,
--                      ASN1_UNI, ASN1_PRI, ASN1_ENUM,
--                      &len);
--      *buf++ = 0;
--
--      /* negTokenTarg/supportedMechType */
--      len = sup_mech_len;
--      asn1_header_encode(&buf,
--                      ASN1_CTX, ASN1_CON, 1,
--                      &len);
--      asn1_header_encode(&buf,
--                      ASN1_UNI, ASN1_PRI, ASN1_OJI,
--                      &len);
--      memcpy(buf, sup_oid, sup_oid_len);
--      buf += len;
--
--      /* negTokenTarg/responseToken */
--      len = rep_token_len;
--      asn1_header_encode(&buf,
--                      ASN1_CTX, ASN1_CON, 2,
--                      &len);
--      asn1_header_encode(&buf,
--                      ASN1_UNI, ASN1_PRI, ASN1_OTS,
--                      &len);
--      asn1_header_encode(&buf,
--                      ASN1_APL, ASN1_CON, 0,
--                      &len);
--      /* negTokenTarg/responseToken/OID */
--      len = asn1_header_len(krb5_oid_len, 1);
--      asn1_header_encode(&buf,
--                      ASN1_UNI, ASN1_PRI, ASN1_OJI,
--                      &len);
--      /* negTokenTarg/responseToken/mechToken*/
--      memcpy(buf, krb5_oid, krb5_oid_len);
--      buf += len;
--      /* AP_REP id */
--      *buf++ = 2;
--      *buf++ = 0;
--      memcpy(buf, in_blob, in_len);
--
--      g_free(sup_oid);
--      g_free(krb5_oid);
--}
--
--int spnego_handle_authen_request(struct ksmbd_spnego_authen_request *req,
--                      struct ksmbd_spnego_auth_out *auth_out)
--{
--      struct spnego_mech_ctx *mech_ctx;
--      unsigned char *mech_token;
--      int token_len, mech_type;
--      int retval = 0;
--
--      if (decode_negTokenInit(req->spnego_blob, (int)req->spnego_blob_len,
--                              &mech_type, &mech_token, &token_len)) {
--              pr_info("Error decoding negTokenInit\n");
--              return -EINVAL;
--      }
--
--      mech_ctx = get_mech(mech_type);
--      if (!mech_ctx) {
--              retval = -ENOTSUP;
--              pr_info("No support for Kerberos 5\n");
--              goto out;
--      }
--
--      if (mech_ctx->ops->handle_authen(mech_ctx,
--                              mech_token, token_len,
--                              auth_out, encode_negTokenTarg)) {
--              retval = -EPERM;
--              pr_info("Error authenticating\n");
--              goto out;
--      }
--out:
--      return retval;
--}
---- /dev/null
-+++ b/tools/management/spnego.c
-@@ -0,0 +1,348 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2020 LG Electronics
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include "tools.h"
-+
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
-+#endif
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <sys/types.h>
-+#include <fcntl.h>
-+#include <stdint.h>
-+#include <stdbool.h>
-+
-+#include <linux/ksmbd_server.h>
-+#include <management/spnego.h>
-+#include <asn1.h>
-+#include "spnego_mech.h"
-+
-+static struct spnego_mech_ctx mech_ctxs[SPNEGO_MAX_MECHS];
-+
-+static struct spnego_mech_ctx *get_mech(int mech_type)
-+{
-+      if (mech_type >= SPNEGO_MAX_MECHS)
-+              return NULL;
-+      return &mech_ctxs[mech_type];
-+}
-+
-+int spnego_init(void)
-+{
-+      struct spnego_mech_ctx *mech_ctx;
-+      int i;
-+
-+      mech_ctx = &mech_ctxs[SPNEGO_MECH_MSKRB5];
-+      mech_ctx->ops = &spnego_mskrb5_operations;
-+      if (global_conf.krb5_service_name)
-+              mech_ctx->params.krb5.service_name =
-+                      strdup(global_conf.krb5_service_name);
-+      if (global_conf.krb5_keytab_file)
-+              mech_ctx->params.krb5.keytab_name =
-+                      strdup(global_conf.krb5_keytab_file);
-+
-+      mech_ctx = &mech_ctxs[SPNEGO_MECH_KRB5];
-+      mech_ctx->ops = &spnego_krb5_operations;
-+      if (global_conf.krb5_service_name)
-+              mech_ctx->params.krb5.service_name =
-+                      strdup(global_conf.krb5_service_name);
-+      if (global_conf.krb5_keytab_file)
-+              mech_ctx->params.krb5.keytab_name =
-+                      strdup(global_conf.krb5_keytab_file);
-+
-+      for (i = 0; i < SPNEGO_MAX_MECHS; i++) {
-+              if (mech_ctxs[i].ops->setup &&
-+                              mech_ctxs[i].ops->setup(&mech_ctxs[i])) {
-+                      pr_err("Failed to init Kerberos 5\n");
-+                      goto out_err;
-+              }
-+      }
-+
-+      return 0;
-+out_err:
-+      for (; i >= 0; i--) {
-+              if (mech_ctxs[i].ops->cleanup)
-+                      mech_ctxs[i].ops->cleanup(&mech_ctxs[i]);
-+      }
-+      return -ENOTSUP;
-+}
-+
-+void spnego_destroy(void)
-+{
-+      int i;
-+
-+      for (i = 0; i < SPNEGO_MAX_MECHS; i++) {
-+              if (mech_ctxs[i].ops && mech_ctxs[i].ops->cleanup)
-+                      mech_ctxs[i].ops->cleanup(&mech_ctxs[i]);
-+      }
-+}
-+
-+static int compare_oid(unsigned long *oid1, unsigned int oid1len,
-+                  unsigned long *oid2, unsigned int oid2len)
-+{
-+      unsigned int i;
-+
-+      if (oid1len != oid2len)
-+              return 1;
-+
-+      for (i = 0; i < oid1len; i++) {
-+              if (oid1[i] != oid2[i])
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static bool is_supported_mech(unsigned long *oid, unsigned int len,
-+                      int *mech_type)
-+{
-+      if (!compare_oid(oid, len, MSKRB5_OID, ARRAY_SIZE(MSKRB5_OID))) {
-+              *mech_type = SPNEGO_MECH_MSKRB5;
-+              return true;
-+      }
-+
-+      if (!compare_oid(oid, len, KRB5_OID, ARRAY_SIZE(KRB5_OID))) {
-+              *mech_type = SPNEGO_MECH_KRB5;
-+              return true;
-+      }
-+
-+      *mech_type = SPNEGO_MAX_MECHS;
-+      return false;
-+}
-+
-+static int decode_asn1_header(struct asn1_ctx *ctx, unsigned char **end,
-+              unsigned int cls, unsigned int con, unsigned int tag)
-+{
-+      unsigned int d_cls, d_con, d_tag;
-+
-+      if (asn1_header_decode(ctx, end, &d_cls, &d_con, &d_tag) == 0 ||
-+              (d_cls != cls || d_con != con || d_tag != tag))
-+              return -EINVAL;
-+      return 0;
-+}
-+
-+static int decode_negTokenInit(unsigned char *negToken, int token_len,
-+                      int *mech_type, unsigned char **krb5_ap_req,
-+                      unsigned int *req_len)
-+{
-+      struct asn1_ctx ctx;
-+      unsigned char *end, *mech_types_end, *id;
-+      unsigned long *oid = NULL;
-+      unsigned int len;
-+
-+      asn1_open(&ctx, negToken, token_len);
-+
-+      /* GSSAPI header */
-+      if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) {
-+              pr_debug("Error decoding SPNEGO application tag\n");
-+              return -EINVAL;
-+      }
-+
-+      /* SPNEGO oid */
-+      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) ||
-+                      asn1_oid_decode(&ctx, end, &oid, &len) == 0 ||
-+                      compare_oid(oid, len, SPNEGO_OID, SPNEGO_OID_LEN)) {
-+              pr_debug("Error decoding SPNEGO OID\n");
-+              g_free(oid);
-+              return -EINVAL;
-+      }
-+      g_free(oid);
-+
-+      /* negoTokenInit */
-+      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) ||
-+                      decode_asn1_header(&ctx, &end,
-+                              ASN1_UNI, ASN1_CON, ASN1_SEQ)) {
-+              pr_debug("Error decoding negTokenInit tag\n");
-+              return -EINVAL;
-+      }
-+
-+      /* mechTypes */
-+      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) ||
-+                      decode_asn1_header(&ctx, &end,
-+                              ASN1_UNI, ASN1_CON, ASN1_SEQ)) {
-+              pr_debug("Error decoding mechTypes tag\n");
-+              return -EINVAL;
-+      }
-+
-+      mech_types_end = end;
-+      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) ||
-+                      asn1_oid_decode(&ctx, end, &oid, &len) == 0) {
-+              pr_debug("Error decoding Kerberos 5 OIDs\n");
-+              return -EINVAL;
-+      }
-+
-+      if (!is_supported_mech(oid, len, mech_type)) {
-+              g_free(oid);
-+              pr_debug("Not a supported mechanism\n");
-+              return -EINVAL;
-+      }
-+      g_free(oid);
-+
-+      ctx.pointer = mech_types_end;
-+      /* mechToken */
-+      if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 2) ||
-+                      decode_asn1_header(&ctx, &end,
-+                              ASN1_UNI, ASN1_PRI, ASN1_OTS)) {
-+              pr_debug("Error decoding krb5_blob\n");
-+              return -EINVAL;
-+      }
-+
-+      if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) {
-+              pr_debug("Error decoding GSSAPI application tag\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Kerberos 5 oid */
-+      if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI)) {
-+              pr_debug("Error decoding Kerberos 5 OID tag\n");
-+              return -EINVAL;
-+      }
-+
-+      if (asn1_oid_decode(&ctx, end, &oid, &len) == 0 ||
-+                      compare_oid(oid, len, KRB5_OID,
-+                              ARRAY_SIZE(KRB5_OID))) {
-+              pr_debug("Not a Kerberos 5 OID\n");
-+              g_free(oid);
-+              return -EINVAL;
-+      }
-+      g_free(oid);
-+
-+      /* AP_REQ id */
-+      if (asn1_read(&ctx, &id, 2) == 0 || id[0] != 1 || id[1] != 0) {
-+              if (id)
-+                      free(id);
-+              pr_debug("Error decoding AP_REQ ID\n");
-+              return -EINVAL;
-+      }
-+      free(id);
-+
-+      /* AP_REQ */
-+      *req_len = (unsigned int)(ctx.end - ctx.pointer);
-+      *krb5_ap_req = ctx.pointer;
-+      return 0;
-+}
-+
-+static int encode_negTokenTarg(char *in_blob, int in_len,
-+                      const unsigned long *oid, int oid_len,
-+                      char **out_blob, int *out_len)
-+{
-+      unsigned char *buf;
-+      unsigned char *sup_oid, *krb5_oid;
-+      int sup_oid_len, krb5_oid_len;
-+      unsigned int neg_result_len, sup_mech_len, rep_token_len, len;
-+
-+      if (asn1_oid_encode(oid, oid_len, &sup_oid, &sup_oid_len))
-+              return -ENOMEM;
-+      if (asn1_oid_encode(KRB5_OID, ARRAY_SIZE(KRB5_OID),
-+                      &krb5_oid, &krb5_oid_len)) {
-+              g_free(sup_oid);
-+              return -ENOMEM;
-+      }
-+
-+      neg_result_len = asn1_header_len(1, 2);
-+      sup_mech_len = asn1_header_len(sup_oid_len, 2);
-+      rep_token_len = asn1_header_len(krb5_oid_len, 1);
-+      rep_token_len += 2 + in_len;
-+      rep_token_len = asn1_header_len(rep_token_len, 3);
-+
-+      *out_len = asn1_header_len(
-+                      neg_result_len + sup_mech_len + rep_token_len, 2);
-+      *out_blob = g_try_malloc0(*out_len);
-+      if (*out_blob == NULL)
-+              return -ENOMEM;
-+      buf = *out_blob;
-+
-+      /* negTokenTarg */
-+      len = *out_len;
-+      asn1_header_encode(&buf,
-+                      ASN1_CTX, ASN1_CON, 1,
-+                      &len);
-+      asn1_header_encode(&buf,
-+                      ASN1_UNI, ASN1_CON, ASN1_SEQ,
-+                      &len);
-+
-+      /* negTokenTarg/negResult */
-+      len = neg_result_len;
-+      asn1_header_encode(&buf,
-+                      ASN1_CTX, ASN1_CON, 0,
-+                      &len);
-+      asn1_header_encode(&buf,
-+                      ASN1_UNI, ASN1_PRI, ASN1_ENUM,
-+                      &len);
-+      *buf++ = 0;
-+
-+      /* negTokenTarg/supportedMechType */
-+      len = sup_mech_len;
-+      asn1_header_encode(&buf,
-+                      ASN1_CTX, ASN1_CON, 1,
-+                      &len);
-+      asn1_header_encode(&buf,
-+                      ASN1_UNI, ASN1_PRI, ASN1_OJI,
-+                      &len);
-+      memcpy(buf, sup_oid, sup_oid_len);
-+      buf += len;
-+
-+      /* negTokenTarg/responseToken */
-+      len = rep_token_len;
-+      asn1_header_encode(&buf,
-+                      ASN1_CTX, ASN1_CON, 2,
-+                      &len);
-+      asn1_header_encode(&buf,
-+                      ASN1_UNI, ASN1_PRI, ASN1_OTS,
-+                      &len);
-+      asn1_header_encode(&buf,
-+                      ASN1_APL, ASN1_CON, 0,
-+                      &len);
-+      /* negTokenTarg/responseToken/OID */
-+      len = asn1_header_len(krb5_oid_len, 1);
-+      asn1_header_encode(&buf,
-+                      ASN1_UNI, ASN1_PRI, ASN1_OJI,
-+                      &len);
-+      /* negTokenTarg/responseToken/mechToken*/
-+      memcpy(buf, krb5_oid, krb5_oid_len);
-+      buf += len;
-+      /* AP_REP id */
-+      *buf++ = 2;
-+      *buf++ = 0;
-+      memcpy(buf, in_blob, in_len);
-+
-+      g_free(sup_oid);
-+      g_free(krb5_oid);
-+}
-+
-+int spnego_handle_authen_request(struct ksmbd_spnego_authen_request *req,
-+                      struct ksmbd_spnego_auth_out *auth_out)
-+{
-+      struct spnego_mech_ctx *mech_ctx;
-+      unsigned char *mech_token;
-+      int token_len, mech_type;
-+      int retval = 0;
-+
-+      if (decode_negTokenInit(req->spnego_blob, (int)req->spnego_blob_len,
-+                              &mech_type, &mech_token, &token_len)) {
-+              pr_info("Error decoding negTokenInit\n");
-+              return -EINVAL;
-+      }
-+
-+      mech_ctx = get_mech(mech_type);
-+      if (!mech_ctx) {
-+              retval = -ENOTSUP;
-+              pr_info("No support for Kerberos 5\n");
-+              goto out;
-+      }
-+
-+      if (mech_ctx->ops->handle_authen(mech_ctx,
-+                              mech_token, token_len,
-+                              auth_out, encode_negTokenTarg)) {
-+              retval = -EPERM;
-+              pr_info("Error authenticating\n");
-+              goto out;
-+      }
-+out:
-+      return retval;
-+}
---- a/lib/management/spnego_krb5.c
-+++ /dev/null
-@@ -1,408 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2020 LG Electronics
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include "ksmbdtools.h"
--
--#include <stdlib.h>
--#include <string.h>
--#include <unistd.h>
--#include <sys/types.h>
--#include <sys/socket.h>
--#include <netdb.h>
--#include <krb5.h>
--
--#include <management/spnego.h>
--#include <asn1.h>
--#include "spnego_mech.h"
--
--#ifndef HAVE_KRB5_AUTH_CON_GETRECVSUBKEY
--krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context context,
--                      krb5_auth_context auth_context, krb5_keyblock **keyblock)
--{
--      return krb5_auth_con_getremotesubkey(context, auth_context, keyblock);
--}
--#endif /* HAVE_KRB5_AUTH_CON_GETRECVSUBKEY */
--
--#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE
--#define KRB5_KEY_TYPE(k)      ((k)->keytype)
--#define KRB5_KEY_LENGTH(k)    ((k)->keyvalue.length)
--#define KRB5_KEY_DATA(k)      ((k)->keyvalue.data)
--#else
--#define KRB5_KEY_TYPE(k)      ((k)->enctype)
--#define KRB5_KEY_LENGTH(k)    ((k)->length)
--#define KRB5_KEY_DATA(k)      ((k)->contents)
--#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
--
--struct spnego_krb5_ctx {
--      krb5_context    context;
--      krb5_keytab     keytab;
--      krb5_creds      creds;
--};
--
--#define SERVICE_NAME  "cifs"
--
--#define pr_krb5_err(_context, _retval, _fmt, ...)             \
--      do {                                                    \
--              const char *msg = krb5_get_error_message(_context, _retval);    \
--              pr_err("%s: " _fmt, msg, ##__VA_ARGS__);        \
--              krb5_free_error_message(_context, msg);         \
--      } while (0)
--
--static char *get_service_name(void)
--{
--      return strdup(SERVICE_NAME);
--}
--
--static char *get_host_name(void)
--{
--      struct addrinfo hint, *ai;
--      char *host_name;
--      char hostname[NI_MAXHOST];
--
--      if (gethostname(hostname, sizeof(hostname)))
--              return NULL;
--
--      memset(&hint, 0, sizeof(hint));
--      hint.ai_family = AF_UNSPEC;
--      hint.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
--      if (getaddrinfo(hostname, NULL, &hint, &ai))
--              return NULL;
--
--      host_name = strdup(ai->ai_canonname);
--      freeaddrinfo(ai);
--      return host_name;
--}
--
--/* Service full name is <service name>[/<host FQDN>[@REALM>]] */
--static int parse_service_full_name(char *service_full_name,
--                      char **service_name,
--                      char **host_name)
--{
--      char *name, *delim;
--
--      *service_name = NULL;
--      *host_name = NULL;
--
--      if (!service_full_name) {
--              *service_name = get_service_name();
--              *host_name = get_host_name();
--              goto out;
--      }
--
--      name = service_full_name;
--      delim = strchr(name, '/');
--      if (!delim) {
--              *service_name = strdup(name);
--              *host_name = get_host_name();
--              goto out;
--      }
--      *service_name = strndup(name, delim - name);
--      if (*service_name == NULL)
--              return -ENOMEM;
--
--      name = delim + 1;
--      delim = strchr(name, '@');
--      if (!delim) {
--              *host_name = strdup(name);
--              goto out;
--      }
--      *host_name = strndup(name, delim - name);
--      if (*host_name == NULL) {
--              free(*service_name);
--              *service_name = NULL;
--              return -ENOMEM;
--      }
--out:
--      /* we assume the host name is FQDN if it has "." */
--      if (*host_name && strchr(*host_name, '.'))
--              return 0;
--
--      free(*service_name);
--      free(*host_name);
--      *service_name = NULL;
--      *host_name = NULL;
--      return -EINVAL;
--}
--
--static krb5_error_code acquire_creds_from_keytab(krb5_context context,
--              char *service_full_name, char *keytab_name,
--              krb5_creds *out_creds, krb5_keytab *keytab)
--{
--      krb5_error_code retval;
--      krb5_principal sprinc = NULL;
--      char *host_name = NULL, *service_name = NULL;
--
--      if (keytab_name)
--              retval = krb5_kt_resolve(context, keytab_name, keytab);
--      else
--              retval = krb5_kt_default(context, keytab);
--      if (retval) {
--              pr_krb5_err(context, retval, "while resolving keytab\n");
--              return retval;
--      }
--
--      if (parse_service_full_name(service_full_name,
--                              &service_name, &host_name)) {
--              retval = KRB5_ERR_HOST_REALM_UNKNOWN;
--              pr_krb5_err(context, retval, "while getting host name\n");
--              goto out_err;
--      }
--
--      retval = krb5_sname_to_principal(context, host_name, service_name,
--                      KRB5_NT_UNKNOWN, &sprinc);
--      if (retval) {
--              pr_krb5_err(context, retval, "while generating service name\n");
--              goto out_err;
--      }
--
--      retval = krb5_get_init_creds_keytab(context, out_creds, sprinc,
--                      *keytab, 0, NULL, NULL);
--      if (retval) {
--              char *name;
--
--              krb5_unparse_name(context, sprinc, &name);
--              pr_krb5_err(context, retval,
--                      "while getting credentials for %s\n", name);
--              krb5_free_unparsed_name(context, name);
--              goto out_err;
--      }
--
--      free(host_name);
--      free(service_name);
--      return 0;
--out_err:
--      if (sprinc)
--              krb5_free_principal(context, sprinc);
--      if (service_name)
--              free(service_name);
--      if (host_name)
--              free(host_name);
--      if (*keytab)
--              krb5_kt_close(context, *keytab);
--      return retval;
--}
--
--static int handle_krb5_authen(struct spnego_mech_ctx *mech_ctx,
--                      char *in_blob, unsigned int in_len,
--                      struct ksmbd_spnego_auth_out *auth_out,
--                      spnego_encode_t spnego_encode)
--{
--      struct spnego_krb5_ctx *krb5_ctx;
--      char *client_name;
--      krb5_auth_context auth_context;
--      krb5_data packet, ap_rep;
--      krb5_ticket *ticket = NULL;
--      krb5_keyblock *session_key;
--#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER
--      krb5_authenticator *authenti;
--#else
--      krb5_authenticator authenti;
--#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */
--      krb5_principal client;
--      int retval = -EINVAL;
--      krb5_error_code krb_retval;
--
--      krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private;
--      if (!krb5_ctx)
--              return -EINVAL;
--
--      krb_retval = krb5_auth_con_init(krb5_ctx->context, &auth_context);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while initializing auth context\n");
--              return -EINVAL;
--      }
--
--      packet.length = in_len;
--      packet.data = (krb5_pointer)in_blob;
--      krb_retval = krb5_rd_req(krb5_ctx->context, &auth_context, &packet,
--                              krb5_ctx->creds.client, krb5_ctx->keytab,
--                              NULL, &ticket);
--      if (krb_retval) {
--              char *name;
--
--              krb5_unparse_name(krb5_ctx->context, krb5_ctx->creds.client,
--                              &name);
--              krb5_auth_con_free(krb5_ctx->context, auth_context);
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                      "while decoding AP_REQ with %s creds\n", name);
--              krb5_free_unparsed_name(krb5_ctx->context, name);
--              return -EINVAL;
--      }
--
--      krb_retval = krb5_auth_con_getrecvsubkey(krb5_ctx->context,
--                              auth_context, &session_key);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while reading session key\n");
--              goto out_free_con_auth;
--      }
--
--      krb_retval = krb5_mk_rep(krb5_ctx->context, auth_context, &ap_rep);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while making AP_REP\n");
--              goto out_free_key;
--      }
--
--      krb_retval = krb5_auth_con_getauthenticator(krb5_ctx->context,
--                              auth_context, &authenti);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while getting authenticator\n");
--              goto out_free_rep;
--      }
--
--#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT
--      krb_retval = krb5_build_principal_ext(krb5_ctx->context, &client,
--                      strlen(authenti->crealm), authenti->crealm, 0);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while getting authenticator client\n");
--              goto out_free_auth;
--      }
--      krb_retval = copy_PrincipalName(&authenti->cname, &client->name);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while copying authenticator client name\n");
--              goto out_free_client;
--      }
--#else
--      client = authenti->client;
--#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */
--
--      krb_retval = krb5_unparse_name_flags(krb5_ctx->context,
--                              client,
--                              KRB5_PRINCIPAL_UNPARSE_NO_REALM, &client_name);
--      if (krb_retval) {
--              pr_krb5_err(krb5_ctx->context, krb_retval,
--                              "while unparsing client name\n");
--              goto out_free_client;
--      }
--
--      memset(auth_out, 0, sizeof(*auth_out));
--      auth_out->user_name = strdup(client_name);
--      if (!auth_out->user_name) {
--              krb5_free_unparsed_name(krb5_ctx->context, client_name);
--              retval = -ENOMEM;
--              goto out_free_client;
--      }
--      krb5_free_unparsed_name(krb5_ctx->context, client_name);
--
--      auth_out->sess_key = malloc(KRB5_KEY_LENGTH(session_key));
--      if (!auth_out->sess_key) {
--              free(auth_out->user_name);
--              retval = -ENOMEM;
--              goto out_free_client;
--      }
--      memcpy(auth_out->sess_key, KRB5_KEY_DATA(session_key), KRB5_KEY_LENGTH(session_key));
--      auth_out->key_len = KRB5_KEY_LENGTH(session_key);
--
--      if (spnego_encode(ap_rep.data, ap_rep.length,
--                      mech_ctx->oid, mech_ctx->oid_len,
--                      &auth_out->spnego_blob, &auth_out->blob_len)) {
--              free(auth_out->user_name);
--              free(auth_out->sess_key);
--              goto out_free_client;
--      }
--
--      pr_info("Authenticated user `%s'\n", auth_out->user_name);
--      retval = 0;
--
--out_free_client:
--#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT
--      krb5_free_principal(krb5_ctx->context, client);
--#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */
--out_free_auth:
--#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER
--      krb5_free_authenticator(krb5_ctx->context, authenti);
--#else
--      krb5_free_authenticator(krb5_ctx->context, &authenti);
--#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */
--out_free_rep:
--      krb5_free_data_contents(krb5_ctx->context, &ap_rep);
--out_free_key:
--      krb5_free_keyblock(krb5_ctx->context, session_key);
--out_free_con_auth:
--      krb5_free_ticket(krb5_ctx->context, ticket);
--      krb5_auth_con_free(krb5_ctx->context, auth_context);
--      return retval;
--}
--
--static int setup_krb5_ctx(struct spnego_mech_ctx *mech_ctx)
--{
--      struct spnego_krb5_ctx *krb5_ctx;
--      krb5_error_code krb_retval;
--
--      krb5_ctx = g_try_malloc0(sizeof(*krb5_ctx));
--      if (!krb5_ctx)
--              return -ENOMEM;
--
--      krb_retval = krb5_init_context(&krb5_ctx->context);
--      if (krb_retval) {
--              g_free(krb5_ctx);
--              pr_err("while initializing krb5 context\n");
--              return -EINVAL;
--      }
--
--      krb_retval = acquire_creds_from_keytab(krb5_ctx->context,
--                      mech_ctx->params.krb5.service_name,
--                      mech_ctx->params.krb5.keytab_name,
--                      &krb5_ctx->creds, &krb5_ctx->keytab);
--      if (krb_retval) {
--              krb5_free_context(krb5_ctx->context);
--              g_free(krb5_ctx);
--              return -EINVAL;
--      }
--
--      mech_ctx->private = krb5_ctx;
--      return 0;
--}
--
--static int setup_krb5(struct spnego_mech_ctx *mech_ctx)
--{
--      mech_ctx->oid = KRB5_OID;
--      mech_ctx->oid_len = ARRAY_SIZE(KRB5_OID);
--      return setup_krb5_ctx(mech_ctx);
--}
--
--static int setup_mskrb5(struct spnego_mech_ctx *mech_ctx)
--{
--      mech_ctx->oid = MSKRB5_OID;
--      mech_ctx->oid_len = ARRAY_SIZE(MSKRB5_OID);
--      return setup_krb5_ctx(mech_ctx);
--}
--
--static void cleanup_krb5(struct spnego_mech_ctx *mech_ctx)
--{
--      if (mech_ctx->private) {
--              struct spnego_krb5_ctx *krb5_ctx;
--
--              krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private;
--              krb5_free_cred_contents(krb5_ctx->context, &krb5_ctx->creds);
--              krb5_kt_close(krb5_ctx->context, krb5_ctx->keytab);
--              krb5_free_context(krb5_ctx->context);
--              g_free(krb5_ctx);
--              mech_ctx->private = NULL;
--      }
--      if (mech_ctx->params.krb5.service_name)
--              free(mech_ctx->params.krb5.service_name);
--      if (mech_ctx->params.krb5.keytab_name)
--              free(mech_ctx->params.krb5.keytab_name);
--}
--
--struct spnego_mech_operations spnego_krb5_operations = {
--      .setup          = setup_krb5,
--      .cleanup        = cleanup_krb5,
--      .handle_authen  = handle_krb5_authen,
--};
--
--struct spnego_mech_operations spnego_mskrb5_operations = {
--      .setup          = setup_mskrb5,
--      .cleanup        = cleanup_krb5,
--      .handle_authen  = handle_krb5_authen,
--};
---- /dev/null
-+++ b/tools/management/spnego_krb5.c
-@@ -0,0 +1,408 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2020 LG Electronics
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include "tools.h"
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <netdb.h>
-+#include <krb5.h>
-+
-+#include <management/spnego.h>
-+#include <asn1.h>
-+#include "spnego_mech.h"
-+
-+#ifndef HAVE_KRB5_AUTH_CON_GETRECVSUBKEY
-+krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context context,
-+                      krb5_auth_context auth_context, krb5_keyblock **keyblock)
-+{
-+      return krb5_auth_con_getremotesubkey(context, auth_context, keyblock);
-+}
-+#endif /* HAVE_KRB5_AUTH_CON_GETRECVSUBKEY */
-+
-+#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE
-+#define KRB5_KEY_TYPE(k)      ((k)->keytype)
-+#define KRB5_KEY_LENGTH(k)    ((k)->keyvalue.length)
-+#define KRB5_KEY_DATA(k)      ((k)->keyvalue.data)
-+#else
-+#define KRB5_KEY_TYPE(k)      ((k)->enctype)
-+#define KRB5_KEY_LENGTH(k)    ((k)->length)
-+#define KRB5_KEY_DATA(k)      ((k)->contents)
-+#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
-+
-+struct spnego_krb5_ctx {
-+      krb5_context    context;
-+      krb5_keytab     keytab;
-+      krb5_creds      creds;
-+};
-+
-+#define SERVICE_NAME  "cifs"
-+
-+#define pr_krb5_err(_context, _retval, _fmt, ...)             \
-+      do {                                                    \
-+              const char *msg = krb5_get_error_message(_context, _retval);    \
-+              pr_err("%s: " _fmt, msg, ##__VA_ARGS__);        \
-+              krb5_free_error_message(_context, msg);         \
-+      } while (0)
-+
-+static char *get_service_name(void)
-+{
-+      return strdup(SERVICE_NAME);
-+}
-+
-+static char *get_host_name(void)
-+{
-+      struct addrinfo hint, *ai;
-+      char *host_name;
-+      char hostname[NI_MAXHOST];
-+
-+      if (gethostname(hostname, sizeof(hostname)))
-+              return NULL;
-+
-+      memset(&hint, 0, sizeof(hint));
-+      hint.ai_family = AF_UNSPEC;
-+      hint.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
-+      if (getaddrinfo(hostname, NULL, &hint, &ai))
-+              return NULL;
-+
-+      host_name = strdup(ai->ai_canonname);
-+      freeaddrinfo(ai);
-+      return host_name;
-+}
-+
-+/* Service full name is <service name>[/<host FQDN>[@REALM>]] */
-+static int parse_service_full_name(char *service_full_name,
-+                      char **service_name,
-+                      char **host_name)
-+{
-+      char *name, *delim;
-+
-+      *service_name = NULL;
-+      *host_name = NULL;
-+
-+      if (!service_full_name) {
-+              *service_name = get_service_name();
-+              *host_name = get_host_name();
-+              goto out;
-+      }
-+
-+      name = service_full_name;
-+      delim = strchr(name, '/');
-+      if (!delim) {
-+              *service_name = strdup(name);
-+              *host_name = get_host_name();
-+              goto out;
-+      }
-+      *service_name = strndup(name, delim - name);
-+      if (*service_name == NULL)
-+              return -ENOMEM;
-+
-+      name = delim + 1;
-+      delim = strchr(name, '@');
-+      if (!delim) {
-+              *host_name = strdup(name);
-+              goto out;
-+      }
-+      *host_name = strndup(name, delim - name);
-+      if (*host_name == NULL) {
-+              free(*service_name);
-+              *service_name = NULL;
-+              return -ENOMEM;
-+      }
-+out:
-+      /* we assume the host name is FQDN if it has "." */
-+      if (*host_name && strchr(*host_name, '.'))
-+              return 0;
-+
-+      free(*service_name);
-+      free(*host_name);
-+      *service_name = NULL;
-+      *host_name = NULL;
-+      return -EINVAL;
-+}
-+
-+static krb5_error_code acquire_creds_from_keytab(krb5_context context,
-+              char *service_full_name, char *keytab_name,
-+              krb5_creds *out_creds, krb5_keytab *keytab)
-+{
-+      krb5_error_code retval;
-+      krb5_principal sprinc = NULL;
-+      char *host_name = NULL, *service_name = NULL;
-+
-+      if (keytab_name)
-+              retval = krb5_kt_resolve(context, keytab_name, keytab);
-+      else
-+              retval = krb5_kt_default(context, keytab);
-+      if (retval) {
-+              pr_krb5_err(context, retval, "while resolving keytab\n");
-+              return retval;
-+      }
-+
-+      if (parse_service_full_name(service_full_name,
-+                              &service_name, &host_name)) {
-+              retval = KRB5_ERR_HOST_REALM_UNKNOWN;
-+              pr_krb5_err(context, retval, "while getting host name\n");
-+              goto out_err;
-+      }
-+
-+      retval = krb5_sname_to_principal(context, host_name, service_name,
-+                      KRB5_NT_UNKNOWN, &sprinc);
-+      if (retval) {
-+              pr_krb5_err(context, retval, "while generating service name\n");
-+              goto out_err;
-+      }
-+
-+      retval = krb5_get_init_creds_keytab(context, out_creds, sprinc,
-+                      *keytab, 0, NULL, NULL);
-+      if (retval) {
-+              char *name;
-+
-+              krb5_unparse_name(context, sprinc, &name);
-+              pr_krb5_err(context, retval,
-+                      "while getting credentials for %s\n", name);
-+              krb5_free_unparsed_name(context, name);
-+              goto out_err;
-+      }
-+
-+      free(host_name);
-+      free(service_name);
-+      return 0;
-+out_err:
-+      if (sprinc)
-+              krb5_free_principal(context, sprinc);
-+      if (service_name)
-+              free(service_name);
-+      if (host_name)
-+              free(host_name);
-+      if (*keytab)
-+              krb5_kt_close(context, *keytab);
-+      return retval;
-+}
-+
-+static int handle_krb5_authen(struct spnego_mech_ctx *mech_ctx,
-+                      char *in_blob, unsigned int in_len,
-+                      struct ksmbd_spnego_auth_out *auth_out,
-+                      spnego_encode_t spnego_encode)
-+{
-+      struct spnego_krb5_ctx *krb5_ctx;
-+      char *client_name;
-+      krb5_auth_context auth_context;
-+      krb5_data packet, ap_rep;
-+      krb5_ticket *ticket = NULL;
-+      krb5_keyblock *session_key;
-+#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER
-+      krb5_authenticator *authenti;
-+#else
-+      krb5_authenticator authenti;
-+#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */
-+      krb5_principal client;
-+      int retval = -EINVAL;
-+      krb5_error_code krb_retval;
-+
-+      krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private;
-+      if (!krb5_ctx)
-+              return -EINVAL;
-+
-+      krb_retval = krb5_auth_con_init(krb5_ctx->context, &auth_context);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while initializing auth context\n");
-+              return -EINVAL;
-+      }
-+
-+      packet.length = in_len;
-+      packet.data = (krb5_pointer)in_blob;
-+      krb_retval = krb5_rd_req(krb5_ctx->context, &auth_context, &packet,
-+                              krb5_ctx->creds.client, krb5_ctx->keytab,
-+                              NULL, &ticket);
-+      if (krb_retval) {
-+              char *name;
-+
-+              krb5_unparse_name(krb5_ctx->context, krb5_ctx->creds.client,
-+                              &name);
-+              krb5_auth_con_free(krb5_ctx->context, auth_context);
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                      "while decoding AP_REQ with %s creds\n", name);
-+              krb5_free_unparsed_name(krb5_ctx->context, name);
-+              return -EINVAL;
-+      }
-+
-+      krb_retval = krb5_auth_con_getrecvsubkey(krb5_ctx->context,
-+                              auth_context, &session_key);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while reading session key\n");
-+              goto out_free_con_auth;
-+      }
-+
-+      krb_retval = krb5_mk_rep(krb5_ctx->context, auth_context, &ap_rep);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while making AP_REP\n");
-+              goto out_free_key;
-+      }
-+
-+      krb_retval = krb5_auth_con_getauthenticator(krb5_ctx->context,
-+                              auth_context, &authenti);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while getting authenticator\n");
-+              goto out_free_rep;
-+      }
-+
-+#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT
-+      krb_retval = krb5_build_principal_ext(krb5_ctx->context, &client,
-+                      strlen(authenti->crealm), authenti->crealm, 0);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while getting authenticator client\n");
-+              goto out_free_auth;
-+      }
-+      krb_retval = copy_PrincipalName(&authenti->cname, &client->name);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while copying authenticator client name\n");
-+              goto out_free_client;
-+      }
-+#else
-+      client = authenti->client;
-+#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */
-+
-+      krb_retval = krb5_unparse_name_flags(krb5_ctx->context,
-+                              client,
-+                              KRB5_PRINCIPAL_UNPARSE_NO_REALM, &client_name);
-+      if (krb_retval) {
-+              pr_krb5_err(krb5_ctx->context, krb_retval,
-+                              "while unparsing client name\n");
-+              goto out_free_client;
-+      }
-+
-+      memset(auth_out, 0, sizeof(*auth_out));
-+      auth_out->user_name = strdup(client_name);
-+      if (!auth_out->user_name) {
-+              krb5_free_unparsed_name(krb5_ctx->context, client_name);
-+              retval = -ENOMEM;
-+              goto out_free_client;
-+      }
-+      krb5_free_unparsed_name(krb5_ctx->context, client_name);
-+
-+      auth_out->sess_key = malloc(KRB5_KEY_LENGTH(session_key));
-+      if (!auth_out->sess_key) {
-+              free(auth_out->user_name);
-+              retval = -ENOMEM;
-+              goto out_free_client;
-+      }
-+      memcpy(auth_out->sess_key, KRB5_KEY_DATA(session_key), KRB5_KEY_LENGTH(session_key));
-+      auth_out->key_len = KRB5_KEY_LENGTH(session_key);
-+
-+      if (spnego_encode(ap_rep.data, ap_rep.length,
-+                      mech_ctx->oid, mech_ctx->oid_len,
-+                      &auth_out->spnego_blob, &auth_out->blob_len)) {
-+              free(auth_out->user_name);
-+              free(auth_out->sess_key);
-+              goto out_free_client;
-+      }
-+
-+      pr_info("Authenticated user `%s'\n", auth_out->user_name);
-+      retval = 0;
-+
-+out_free_client:
-+#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT
-+      krb5_free_principal(krb5_ctx->context, client);
-+#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */
-+out_free_auth:
-+#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER
-+      krb5_free_authenticator(krb5_ctx->context, authenti);
-+#else
-+      krb5_free_authenticator(krb5_ctx->context, &authenti);
-+#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */
-+out_free_rep:
-+      krb5_free_data_contents(krb5_ctx->context, &ap_rep);
-+out_free_key:
-+      krb5_free_keyblock(krb5_ctx->context, session_key);
-+out_free_con_auth:
-+      krb5_free_ticket(krb5_ctx->context, ticket);
-+      krb5_auth_con_free(krb5_ctx->context, auth_context);
-+      return retval;
-+}
-+
-+static int setup_krb5_ctx(struct spnego_mech_ctx *mech_ctx)
-+{
-+      struct spnego_krb5_ctx *krb5_ctx;
-+      krb5_error_code krb_retval;
-+
-+      krb5_ctx = g_try_malloc0(sizeof(*krb5_ctx));
-+      if (!krb5_ctx)
-+              return -ENOMEM;
-+
-+      krb_retval = krb5_init_context(&krb5_ctx->context);
-+      if (krb_retval) {
-+              g_free(krb5_ctx);
-+              pr_err("while initializing krb5 context\n");
-+              return -EINVAL;
-+      }
-+
-+      krb_retval = acquire_creds_from_keytab(krb5_ctx->context,
-+                      mech_ctx->params.krb5.service_name,
-+                      mech_ctx->params.krb5.keytab_name,
-+                      &krb5_ctx->creds, &krb5_ctx->keytab);
-+      if (krb_retval) {
-+              krb5_free_context(krb5_ctx->context);
-+              g_free(krb5_ctx);
-+              return -EINVAL;
-+      }
-+
-+      mech_ctx->private = krb5_ctx;
-+      return 0;
-+}
-+
-+static int setup_krb5(struct spnego_mech_ctx *mech_ctx)
-+{
-+      mech_ctx->oid = KRB5_OID;
-+      mech_ctx->oid_len = ARRAY_SIZE(KRB5_OID);
-+      return setup_krb5_ctx(mech_ctx);
-+}
-+
-+static int setup_mskrb5(struct spnego_mech_ctx *mech_ctx)
-+{
-+      mech_ctx->oid = MSKRB5_OID;
-+      mech_ctx->oid_len = ARRAY_SIZE(MSKRB5_OID);
-+      return setup_krb5_ctx(mech_ctx);
-+}
-+
-+static void cleanup_krb5(struct spnego_mech_ctx *mech_ctx)
-+{
-+      if (mech_ctx->private) {
-+              struct spnego_krb5_ctx *krb5_ctx;
-+
-+              krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private;
-+              krb5_free_cred_contents(krb5_ctx->context, &krb5_ctx->creds);
-+              krb5_kt_close(krb5_ctx->context, krb5_ctx->keytab);
-+              krb5_free_context(krb5_ctx->context);
-+              g_free(krb5_ctx);
-+              mech_ctx->private = NULL;
-+      }
-+      if (mech_ctx->params.krb5.service_name)
-+              free(mech_ctx->params.krb5.service_name);
-+      if (mech_ctx->params.krb5.keytab_name)
-+              free(mech_ctx->params.krb5.keytab_name);
-+}
-+
-+struct spnego_mech_operations spnego_krb5_operations = {
-+      .setup          = setup_krb5,
-+      .cleanup        = cleanup_krb5,
-+      .handle_authen  = handle_krb5_authen,
-+};
-+
-+struct spnego_mech_operations spnego_mskrb5_operations = {
-+      .setup          = setup_mskrb5,
-+      .cleanup        = cleanup_krb5,
-+      .handle_authen  = handle_krb5_authen,
-+};
---- a/lib/management/tree_conn.c
-+++ /dev/null
-@@ -1,231 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <stdlib.h>
--#include <string.h>
--#include <glib.h>
--
--#include "linux/ksmbd_server.h"
--#include "management/tree_conn.h"
--#include "management/session.h"
--#include "management/share.h"
--#include "management/user.h"
--#include "ksmbdtools.h"
--
--static struct ksmbd_tree_conn *new_ksmbd_tree_conn(void)
--{
--      struct ksmbd_tree_conn *conn;
--
--      conn = g_try_malloc0(sizeof(struct ksmbd_tree_conn));
--      if (!conn)
--              return NULL;
--
--      conn->id = 0;
--      return conn;
--}
--
--void tcm_tree_conn_free(struct ksmbd_tree_conn *conn)
--{
--      shm_close_connection(conn->share);
--      put_ksmbd_share(conn->share);
--      g_free(conn);
--}
--
--int tcm_handle_tree_connect(struct ksmbd_tree_connect_request *req,
--                          struct ksmbd_tree_connect_response *resp)
--{
--      struct ksmbd_user *user = NULL;
--      struct ksmbd_share *share = NULL;
--      struct ksmbd_tree_conn *conn = new_ksmbd_tree_conn();
--      int ret;
--
--      if (!conn) {
--              resp->status = KSMBD_TREE_CONN_STATUS_NOMEM;
--              return -ENOMEM;
--      }
--
--      if (sm_check_sessions_capacity(req->session_id)) {
--              resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS;
--              pr_debug("treecon: Too many active sessions\n");
--              goto out_error;
--      }
--
--      if (global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) {
--              if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) {
--                      resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
--                      pr_debug("treecon: Bad user password\n");
--                      goto out_error;
--              }
--      }
--
--      share = shm_lookup_share(req->share);
--      if (!share) {
--              resp->status = KSMBD_TREE_CONN_STATUS_NO_SHARE;
--              pr_err("treecon: Unknown net share: %s\n", req->share);
--              goto out_error;
--      }
--
--      if (test_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE))
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
--      if (test_share_flag(share, KSMBD_SHARE_FLAG_READONLY))
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY);
--      if (test_share_flag(share, KSMBD_SHARE_FLAG_UPDATE))
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_UPDATE);
--
--      if (shm_open_connection(share)) {
--              resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS;
--              pr_debug("treecon: Too many connections to net share\n");
--              goto out_error;
--      }
--
--      ret = shm_lookup_hosts_map(share,
--                                 KSMBD_SHARE_HOSTS_ALLOW_MAP,
--                                 req->peer_addr);
--      if (ret == -ENOENT) {
--              resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED;
--              pr_debug("treecon: Host denied: %s\n", req->peer_addr);
--              goto out_error;
--      }
--
--      if (ret != 0) {
--              ret = shm_lookup_hosts_map(share,
--                                         KSMBD_SHARE_HOSTS_DENY_MAP,
--                                         req->peer_addr);
--              if (ret == 0) {
--                      resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED;
--                      pr_err("treecon: Host denied: %s\n", req->peer_addr);
--                      goto out_error;
--              }
--      }
--
--      if (global_conf.restrict_anon >= KSMBD_RESTRICT_ANON_TYPE_1) {
--              int deny;
--
--              deny = !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK);
--              deny |= test_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
--
--              if (req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT &&
--                              deny) {
--                      pr_debug("treecon: Deny, restricted session\n");
--                      resp->status = KSMBD_TREE_CONN_STATUS_ERROR;
--                      goto out_error;
--              }
--      }
--
--      if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) &&
--          !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE) &&
--          !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) {
--              pr_debug("treecon: Deny, guest not allowed\n");
--              resp->status = KSMBD_TREE_CONN_STATUS_ERROR;
--              goto out_error;
--      }
--
--      if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) &&
--           test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) {
--              pr_debug("treecon: Net share permits guest login\n");
--              user = usm_lookup_user(share->guest_account);
--              if (user) {
--                      set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
--                      goto bind;
--              }
--
--              user = usm_lookup_user(global_conf.guest_account);
--              if (user) {
--                      set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
--                      goto bind;
--              }
--      }
--
--      user = usm_lookup_user(req->account);
--      if (!user) {
--              resp->status = KSMBD_TREE_CONN_STATUS_NO_USER;
--              pr_err("treecon: User `%s' not found\n", req->account);
--              goto out_error;
--      }
--
--      user->failed_login_count = 0;
--      user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION;
--
--      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
--
--      ret = shm_lookup_users_map(share,
--                                 KSMBD_SHARE_ADMIN_USERS_MAP,
--                                 req->account);
--      if (ret == 0) {
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT);
--              goto bind;
--      }
--
--      ret = shm_lookup_users_map(share,
--                                 KSMBD_SHARE_INVALID_USERS_MAP,
--                                 req->account);
--      if (ret == 0) {
--              resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
--              pr_err("treecon: User is on invalid users list\n");
--              goto out_error;
--      }
--
--      ret = shm_lookup_users_map(share,
--                                 KSMBD_SHARE_READ_LIST_MAP,
--                                 req->account);
--      if (ret == 0) {
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY);
--              clear_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
--              goto bind;
--      }
--
--      ret = shm_lookup_users_map(share,
--                                 KSMBD_SHARE_WRITE_LIST_MAP,
--                                 req->account);
--      if (ret == 0) {
--              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
--              goto bind;
--      }
--
--      ret = shm_lookup_users_map(share,
--                                 KSMBD_SHARE_VALID_USERS_MAP,
--                                 req->account);
--      if (ret == 0)
--              goto bind;
--      if (ret == -ENOENT) {
--              resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
--              pr_err("treecon: User is not on valid users list\n");
--              goto out_error;
--      }
--
--bind:
--      conn->id = req->connect_id;
--      conn->share = share;
--      resp->status = KSMBD_TREE_CONN_STATUS_OK;
--      resp->connection_flags = conn->flags;
--
--      if (sm_handle_tree_connect(req->session_id, user, conn)) {
--              pr_err("treecon: Unable to bind tree connection\n");
--              tcm_tree_conn_free(conn);
--              put_ksmbd_user(user);
--      }
--
--      g_rw_lock_writer_lock(&share->update_lock);
--      clear_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
--      g_rw_lock_writer_unlock(&share->update_lock);
--
--      return 0;
--out_error:
--      tcm_tree_conn_free(conn);
--      shm_close_connection(share);
--      put_ksmbd_share(share);
--      put_ksmbd_user(user);
--      return -EINVAL;
--}
--
--int tcm_handle_tree_disconnect(unsigned long long sess_id,
--                             unsigned long long tree_conn_id)
--{
--      sm_handle_tree_disconnect(sess_id, tree_conn_id);
--      return 0;
--}
---- /dev/null
-+++ b/tools/management/tree_conn.c
-@@ -0,0 +1,231 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <glib.h>
-+
-+#include "linux/ksmbd_server.h"
-+#include "management/tree_conn.h"
-+#include "management/session.h"
-+#include "management/share.h"
-+#include "management/user.h"
-+#include "tools.h"
-+
-+static struct ksmbd_tree_conn *new_ksmbd_tree_conn(void)
-+{
-+      struct ksmbd_tree_conn *conn;
-+
-+      conn = g_try_malloc0(sizeof(struct ksmbd_tree_conn));
-+      if (!conn)
-+              return NULL;
-+
-+      conn->id = 0;
-+      return conn;
-+}
-+
-+void tcm_tree_conn_free(struct ksmbd_tree_conn *conn)
-+{
-+      shm_close_connection(conn->share);
-+      put_ksmbd_share(conn->share);
-+      g_free(conn);
-+}
-+
-+int tcm_handle_tree_connect(struct ksmbd_tree_connect_request *req,
-+                          struct ksmbd_tree_connect_response *resp)
-+{
-+      struct ksmbd_user *user = NULL;
-+      struct ksmbd_share *share = NULL;
-+      struct ksmbd_tree_conn *conn = new_ksmbd_tree_conn();
-+      int ret;
-+
-+      if (!conn) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_NOMEM;
-+              return -ENOMEM;
-+      }
-+
-+      if (sm_check_sessions_capacity(req->session_id)) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS;
-+              pr_debug("treecon: Too many active sessions\n");
-+              goto out_error;
-+      }
-+
-+      if (global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) {
-+              if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) {
-+                      resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
-+                      pr_debug("treecon: Bad user password\n");
-+                      goto out_error;
-+              }
-+      }
-+
-+      share = shm_lookup_share(req->share);
-+      if (!share) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_NO_SHARE;
-+              pr_err("treecon: Unknown net share: %s\n", req->share);
-+              goto out_error;
-+      }
-+
-+      if (test_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE))
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
-+      if (test_share_flag(share, KSMBD_SHARE_FLAG_READONLY))
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY);
-+      if (test_share_flag(share, KSMBD_SHARE_FLAG_UPDATE))
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_UPDATE);
-+
-+      if (shm_open_connection(share)) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS;
-+              pr_debug("treecon: Too many connections to net share\n");
-+              goto out_error;
-+      }
-+
-+      ret = shm_lookup_hosts_map(share,
-+                                 KSMBD_SHARE_HOSTS_ALLOW_MAP,
-+                                 req->peer_addr);
-+      if (ret == -ENOENT) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED;
-+              pr_debug("treecon: Host denied: %s\n", req->peer_addr);
-+              goto out_error;
-+      }
-+
-+      if (ret != 0) {
-+              ret = shm_lookup_hosts_map(share,
-+                                         KSMBD_SHARE_HOSTS_DENY_MAP,
-+                                         req->peer_addr);
-+              if (ret == 0) {
-+                      resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED;
-+                      pr_err("treecon: Host denied: %s\n", req->peer_addr);
-+                      goto out_error;
-+              }
-+      }
-+
-+      if (global_conf.restrict_anon >= KSMBD_RESTRICT_ANON_TYPE_1) {
-+              int deny;
-+
-+              deny = !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK);
-+              deny |= test_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
-+
-+              if (req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT &&
-+                              deny) {
-+                      pr_debug("treecon: Deny, restricted session\n");
-+                      resp->status = KSMBD_TREE_CONN_STATUS_ERROR;
-+                      goto out_error;
-+              }
-+      }
-+
-+      if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) &&
-+          !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE) &&
-+          !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) {
-+              pr_debug("treecon: Deny, guest not allowed\n");
-+              resp->status = KSMBD_TREE_CONN_STATUS_ERROR;
-+              goto out_error;
-+      }
-+
-+      if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) &&
-+           test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) {
-+              pr_debug("treecon: Net share permits guest login\n");
-+              user = usm_lookup_user(share->guest_account);
-+              if (user) {
-+                      set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
-+                      goto bind;
-+              }
-+
-+              user = usm_lookup_user(global_conf.guest_account);
-+              if (user) {
-+                      set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
-+                      goto bind;
-+              }
-+      }
-+
-+      user = usm_lookup_user(req->account);
-+      if (!user) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_NO_USER;
-+              pr_err("treecon: User `%s' not found\n", req->account);
-+              goto out_error;
-+      }
-+
-+      user->failed_login_count = 0;
-+      user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION;
-+
-+      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT);
-+
-+      ret = shm_lookup_users_map(share,
-+                                 KSMBD_SHARE_ADMIN_USERS_MAP,
-+                                 req->account);
-+      if (ret == 0) {
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT);
-+              goto bind;
-+      }
-+
-+      ret = shm_lookup_users_map(share,
-+                                 KSMBD_SHARE_INVALID_USERS_MAP,
-+                                 req->account);
-+      if (ret == 0) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
-+              pr_err("treecon: User is on invalid users list\n");
-+              goto out_error;
-+      }
-+
-+      ret = shm_lookup_users_map(share,
-+                                 KSMBD_SHARE_READ_LIST_MAP,
-+                                 req->account);
-+      if (ret == 0) {
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY);
-+              clear_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
-+              goto bind;
-+      }
-+
-+      ret = shm_lookup_users_map(share,
-+                                 KSMBD_SHARE_WRITE_LIST_MAP,
-+                                 req->account);
-+      if (ret == 0) {
-+              set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
-+              goto bind;
-+      }
-+
-+      ret = shm_lookup_users_map(share,
-+                                 KSMBD_SHARE_VALID_USERS_MAP,
-+                                 req->account);
-+      if (ret == 0)
-+              goto bind;
-+      if (ret == -ENOENT) {
-+              resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER;
-+              pr_err("treecon: User is not on valid users list\n");
-+              goto out_error;
-+      }
-+
-+bind:
-+      conn->id = req->connect_id;
-+      conn->share = share;
-+      resp->status = KSMBD_TREE_CONN_STATUS_OK;
-+      resp->connection_flags = conn->flags;
-+
-+      if (sm_handle_tree_connect(req->session_id, user, conn)) {
-+              pr_err("treecon: Unable to bind tree connection\n");
-+              tcm_tree_conn_free(conn);
-+              put_ksmbd_user(user);
-+      }
-+
-+      g_rw_lock_writer_lock(&share->update_lock);
-+      clear_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
-+      g_rw_lock_writer_unlock(&share->update_lock);
-+
-+      return 0;
-+out_error:
-+      tcm_tree_conn_free(conn);
-+      shm_close_connection(share);
-+      put_ksmbd_share(share);
-+      put_ksmbd_user(user);
-+      return -EINVAL;
-+}
-+
-+int tcm_handle_tree_disconnect(unsigned long long sess_id,
-+                             unsigned long long tree_conn_id)
-+{
-+      sm_handle_tree_disconnect(sess_id, tree_conn_id);
-+      return 0;
-+}
---- a/lib/management/user.c
-+++ /dev/null
-@@ -1,412 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <stdlib.h>
--#include <string.h>
--#include <glib.h>
--
--#include "linux/ksmbd_server.h"
--#include "management/user.h"
--#include "ksmbdtools.h"
--
--#define KSMBD_USER_STATE_FREEING      1
--
--static GHashTable     *users_table;
--static GRWLock                users_table_lock;
--
--static void kill_ksmbd_user(struct ksmbd_user *user)
--{
--      pr_debug("Kill user `%s'\n", user->name);
--
--      free(user->name);
--      free(user->pass_b64);
--      free(user->pass);
--      g_rw_lock_clear(&user->update_lock);
--      g_free(user);
--}
--
--static int __usm_remove_user(struct ksmbd_user *user)
--{
--      int ret = 0;
--
--      if (user->state != KSMBD_USER_STATE_FREEING) {
--              g_rw_lock_writer_lock(&users_table_lock);
--              if (!g_hash_table_remove(users_table, user->name))
--                      ret = -EINVAL;
--              g_rw_lock_writer_unlock(&users_table_lock);
--      }
--      if (!ret)
--              kill_ksmbd_user(user);
--      return ret;
--}
--
--struct ksmbd_user *get_ksmbd_user(struct ksmbd_user *user)
--{
--      g_rw_lock_writer_lock(&user->update_lock);
--      if (user->ref_count != 0) {
--              user->ref_count++;
--              g_rw_lock_writer_unlock(&user->update_lock);
--      } else {
--              g_rw_lock_writer_unlock(&user->update_lock);
--              user = NULL;
--      }
--      return user;
--}
--
--void put_ksmbd_user(struct ksmbd_user *user)
--{
--      int drop;
--
--      if (!user)
--              return;
--
--      g_rw_lock_writer_lock(&user->update_lock);
--      user->ref_count--;
--      drop = !user->ref_count;
--      g_rw_lock_writer_unlock(&user->update_lock);
--
--      if (!drop)
--              return;
--
--      __usm_remove_user(user);
--}
--
--static gboolean put_user_callback(gpointer _k, gpointer _v, gpointer data)
--{
--      struct ksmbd_user *user = (struct ksmbd_user *)_v;
--
--      user->state = KSMBD_USER_STATE_FREEING;
--      put_ksmbd_user(user);
--      return TRUE;
--}
--
--void usm_remove_all_users(void)
--{
--      g_rw_lock_writer_lock(&users_table_lock);
--      g_hash_table_foreach_remove(users_table, put_user_callback, NULL);
--      g_rw_lock_writer_unlock(&users_table_lock);
--}
--
--static struct ksmbd_user *new_ksmbd_user(char *name, char *pwd)
--{
--      struct ksmbd_user *user;
--      struct passwd *passwd;
--      size_t pass_sz;
--
--      user = g_try_malloc0(sizeof(struct ksmbd_user));
--      if (!user)
--              return NULL;
--
--      g_rw_lock_init(&user->update_lock);
--      user->name = name;
--      user->pass_b64 = pwd;
--      user->ref_count = 1;
--      user->gid = 9999;
--      user->uid = 9999;
--      passwd = getpwnam(name);
--      if (passwd) {
--              user->uid = passwd->pw_uid;
--              user->gid = passwd->pw_gid;
--      }
--
--      user->pass = base64_decode(user->pass_b64, &pass_sz);
--      user->pass_sz = (int)pass_sz;
--      return user;
--}
--
--static void free_hash_entry(gpointer k, gpointer u, gpointer user_data)
--{
--      kill_ksmbd_user(u);
--}
--
--static void usm_clear_users(void)
--{
--      g_hash_table_foreach(users_table, free_hash_entry, NULL);
--}
--
--void usm_destroy(void)
--{
--      if (users_table) {
--              usm_clear_users();
--              g_hash_table_destroy(users_table);
--      }
--      g_rw_lock_clear(&users_table_lock);
--}
--
--int usm_init(void)
--{
--      users_table = g_hash_table_new(g_str_hash, g_str_equal);
--      if (!users_table)
--              return -ENOMEM;
--      g_rw_lock_init(&users_table_lock);
--      return 0;
--}
--
--static struct ksmbd_user *__usm_lookup_user(char *name)
--{
--      return g_hash_table_lookup(users_table, name);
--}
--
--struct ksmbd_user *usm_lookup_user(char *name)
--{
--      struct ksmbd_user *user, *ret;
--
--      if (!name)
--              return NULL;
--
--      g_rw_lock_reader_lock(&users_table_lock);
--      user = __usm_lookup_user(name);
--      if (user) {
--              ret = get_ksmbd_user(user);
--              if (!ret)
--                      user = NULL;
--      }
--      g_rw_lock_reader_unlock(&users_table_lock);
--      return user;
--}
--
--int usm_add_new_user(char *name, char *pwd)
--{
--      int ret = 0;
--      struct ksmbd_user *user = new_ksmbd_user(name, pwd);
--
--      if (!user) {
--              free(name);
--              free(pwd);
--              return -ENOMEM;
--      }
--
--      g_rw_lock_writer_lock(&users_table_lock);
--      if (__usm_lookup_user(name)) {
--              g_rw_lock_writer_unlock(&users_table_lock);
--              pr_info("User `%s' already exists\n", name);
--              kill_ksmbd_user(user);
--              return 0;
--      }
--
--      pr_debug("New user `%s'\n", user->name);
--      if (!g_hash_table_insert(users_table, user->name, user)) {
--              kill_ksmbd_user(user);
--              ret = -EINVAL;
--      }
--      g_rw_lock_writer_unlock(&users_table_lock);
--      return ret;
--}
--
--int usm_add_update_user_from_pwdentry(char *data)
--{
--      struct ksmbd_user *user;
--      char *name;
--      char *pwd;
--      char *pos = strchr(data, ':');
--      int ret;
--
--      if (!pos) {
--              pr_err("Invalid pwd entry: %s\n", data);
--              return -EINVAL;
--      }
--
--      *pos = 0x00;
--      name = g_strdup(data);
--      pwd = g_strdup(pos + 1);
--
--      if (!name || !pwd) {
--              free(name);
--              free(pwd);
--              return -ENOMEM;
--      }
--
--      user = usm_lookup_user(name);
--      if (user) {
--              ret = usm_update_user_password(user, pwd);
--              put_ksmbd_user(user);
--
--              free(name);
--              free(pwd);
--              return ret;
--      }
--      return usm_add_new_user(name, pwd);
--}
--
--int usm_add_subauth_global_conf(char *data)
--{
--      char *pos = data;
--      char *spos;
--
--      if (!pos)
--              return -EINVAL;
--
--      spos = strchr(pos, ':');
--      if (!spos) {
--              pr_err("Invalid subauth entry: %s\n", data);
--              return -EINVAL;
--      }
--
--      *spos = 0x00;
--      global_conf.gen_subauth[0] = atoi(pos);
--      pos = spos + 1;
--
--      spos = strchr(pos, ':');
--      if (!spos) {
--              pr_err("Invalid subauth entry: %s\n", data);
--              return -EINVAL;
--      }
--      *spos = 0x00;
--      global_conf.gen_subauth[1] = atoi(pos);
--      global_conf.gen_subauth[2] = atoi(spos + 1);
--
--      return 0;
--}
--
--void for_each_ksmbd_user(walk_users cb, gpointer user_data)
--{
--      g_rw_lock_reader_lock(&users_table_lock);
--      g_hash_table_foreach(users_table, cb, user_data);
--      g_rw_lock_reader_unlock(&users_table_lock);
--}
--
--int usm_update_user_password(struct ksmbd_user *user, char *pswd)
--{
--      size_t pass_sz;
--      char *pass_b64 = g_strdup(pswd);
--      char *pass = base64_decode(pass_b64, &pass_sz);
--
--      if (!pass_b64 || !pass) {
--              free(pass_b64);
--              free(pass);
--              pr_err("Out of memory\n");
--              return -ENOMEM;
--      }
--
--      pr_debug("Update user password: %s\n", user->name);
--      g_rw_lock_writer_lock(&user->update_lock);
--      free(user->pass_b64);
--      free(user->pass);
--      user->pass_b64 = pass_b64;
--      user->pass = pass;
--      user->pass_sz = (int)pass_sz;
--      g_rw_lock_writer_unlock(&user->update_lock);
--
--      return 0;
--}
--
--static int usm_copy_user_passhash(struct ksmbd_user *user,
--                                char *pass,
--                                size_t sz)
--{
--      int ret = -ENOSPC;
--
--      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
--              return 0;
--
--      g_rw_lock_reader_lock(&user->update_lock);
--      if (sz >= user->pass_sz) {
--              memcpy(pass, user->pass, user->pass_sz);
--              ret = user->pass_sz;
--      }
--      g_rw_lock_reader_unlock(&user->update_lock);
--
--      return ret;
--}
--
--static int usm_copy_user_account(struct ksmbd_user *user,
--                               char *account,
--                               size_t sz)
--{
--      int account_sz;
--
--      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
--              return 0;
--
--      account_sz = strlen(user->name);
--      if (sz >= account_sz) {
--              memcpy(account, user->name, account_sz);
--              return 0;
--      }
--      pr_err("Cannot copy user data, buffer overrun\n");
--      return -ENOSPC;
--}
--
--static void __handle_login_request(struct ksmbd_login_response *resp,
--                                 struct ksmbd_user *user)
--{
--      int hash_sz;
--
--      resp->gid = user->gid;
--      resp->uid = user->uid;
--      resp->status = user->flags;
--      resp->status |= KSMBD_USER_FLAG_OK;
--
--      hash_sz = usm_copy_user_passhash(user,
--                                       resp->hash,
--                                       sizeof(resp->hash));
--      if (hash_sz < 0) {
--              resp->status = KSMBD_USER_FLAG_INVALID;
--      } else {
--              resp->hash_sz = (unsigned short)hash_sz;
--              if (usm_copy_user_account(user,
--                                        resp->account,
--                                        sizeof(resp->account)))
--                      resp->status = KSMBD_USER_FLAG_INVALID;
--      }
--}
--
--int usm_handle_login_request(struct ksmbd_login_request *req,
--                           struct ksmbd_login_response *resp)
--{
--      struct ksmbd_user *user = NULL;
--      int null_session = 0;
--
--      if (req->account[0] == '\0')
--              null_session = 1;
--
--      if (!null_session)
--              user = usm_lookup_user(req->account);
--      if (user) {
--              __handle_login_request(resp, user);
--              put_ksmbd_user(user);
--              return 0;
--      }
--
--      resp->status = KSMBD_USER_FLAG_BAD_USER;
--      if (!null_session &&
--              global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER)
--              return 0;
--
--      if (null_session ||
--              global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_BAD_USER)
--              user = usm_lookup_user(global_conf.guest_account);
--
--      if (!user)
--              return 0;
--
--      __handle_login_request(resp, user);
--      put_ksmbd_user(user);
--      return 0;
--}
--
--int usm_handle_logout_request(struct ksmbd_logout_request *req)
--{
--      struct ksmbd_user *user;
--
--      user = usm_lookup_user(req->account);
--      if (!user)
--              return -ENOENT;
--
--      if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) {
--              if (user->failed_login_count < 10)
--                      user->failed_login_count++;
--              else
--                      user->flags |= KSMBD_USER_FLAG_DELAY_SESSION;
--      } else {
--              user->failed_login_count = 0;
--              user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION;
--      }
--
--      put_ksmbd_user(user);
--      return 0;
--}
---- /dev/null
-+++ b/tools/management/user.c
-@@ -0,0 +1,412 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <glib.h>
-+
-+#include "linux/ksmbd_server.h"
-+#include "management/user.h"
-+#include "tools.h"
-+
-+#define KSMBD_USER_STATE_FREEING      1
-+
-+static GHashTable     *users_table;
-+static GRWLock                users_table_lock;
-+
-+static void kill_ksmbd_user(struct ksmbd_user *user)
-+{
-+      pr_debug("Kill user `%s'\n", user->name);
-+
-+      free(user->name);
-+      free(user->pass_b64);
-+      free(user->pass);
-+      g_rw_lock_clear(&user->update_lock);
-+      g_free(user);
-+}
-+
-+static int __usm_remove_user(struct ksmbd_user *user)
-+{
-+      int ret = 0;
-+
-+      if (user->state != KSMBD_USER_STATE_FREEING) {
-+              g_rw_lock_writer_lock(&users_table_lock);
-+              if (!g_hash_table_remove(users_table, user->name))
-+                      ret = -EINVAL;
-+              g_rw_lock_writer_unlock(&users_table_lock);
-+      }
-+      if (!ret)
-+              kill_ksmbd_user(user);
-+      return ret;
-+}
-+
-+struct ksmbd_user *get_ksmbd_user(struct ksmbd_user *user)
-+{
-+      g_rw_lock_writer_lock(&user->update_lock);
-+      if (user->ref_count != 0) {
-+              user->ref_count++;
-+              g_rw_lock_writer_unlock(&user->update_lock);
-+      } else {
-+              g_rw_lock_writer_unlock(&user->update_lock);
-+              user = NULL;
-+      }
-+      return user;
-+}
-+
-+void put_ksmbd_user(struct ksmbd_user *user)
-+{
-+      int drop;
-+
-+      if (!user)
-+              return;
-+
-+      g_rw_lock_writer_lock(&user->update_lock);
-+      user->ref_count--;
-+      drop = !user->ref_count;
-+      g_rw_lock_writer_unlock(&user->update_lock);
-+
-+      if (!drop)
-+              return;
-+
-+      __usm_remove_user(user);
-+}
-+
-+static gboolean put_user_callback(gpointer _k, gpointer _v, gpointer data)
-+{
-+      struct ksmbd_user *user = (struct ksmbd_user *)_v;
-+
-+      user->state = KSMBD_USER_STATE_FREEING;
-+      put_ksmbd_user(user);
-+      return TRUE;
-+}
-+
-+void usm_remove_all_users(void)
-+{
-+      g_rw_lock_writer_lock(&users_table_lock);
-+      g_hash_table_foreach_remove(users_table, put_user_callback, NULL);
-+      g_rw_lock_writer_unlock(&users_table_lock);
-+}
-+
-+static struct ksmbd_user *new_ksmbd_user(char *name, char *pwd)
-+{
-+      struct ksmbd_user *user;
-+      struct passwd *passwd;
-+      size_t pass_sz;
-+
-+      user = g_try_malloc0(sizeof(struct ksmbd_user));
-+      if (!user)
-+              return NULL;
-+
-+      g_rw_lock_init(&user->update_lock);
-+      user->name = name;
-+      user->pass_b64 = pwd;
-+      user->ref_count = 1;
-+      user->gid = 9999;
-+      user->uid = 9999;
-+      passwd = getpwnam(name);
-+      if (passwd) {
-+              user->uid = passwd->pw_uid;
-+              user->gid = passwd->pw_gid;
-+      }
-+
-+      user->pass = base64_decode(user->pass_b64, &pass_sz);
-+      user->pass_sz = (int)pass_sz;
-+      return user;
-+}
-+
-+static void free_hash_entry(gpointer k, gpointer u, gpointer user_data)
-+{
-+      kill_ksmbd_user(u);
-+}
-+
-+static void usm_clear_users(void)
-+{
-+      g_hash_table_foreach(users_table, free_hash_entry, NULL);
-+}
-+
-+void usm_destroy(void)
-+{
-+      if (users_table) {
-+              usm_clear_users();
-+              g_hash_table_destroy(users_table);
-+      }
-+      g_rw_lock_clear(&users_table_lock);
-+}
-+
-+int usm_init(void)
-+{
-+      users_table = g_hash_table_new(g_str_hash, g_str_equal);
-+      if (!users_table)
-+              return -ENOMEM;
-+      g_rw_lock_init(&users_table_lock);
-+      return 0;
-+}
-+
-+static struct ksmbd_user *__usm_lookup_user(char *name)
-+{
-+      return g_hash_table_lookup(users_table, name);
-+}
-+
-+struct ksmbd_user *usm_lookup_user(char *name)
-+{
-+      struct ksmbd_user *user, *ret;
-+
-+      if (!name)
-+              return NULL;
-+
-+      g_rw_lock_reader_lock(&users_table_lock);
-+      user = __usm_lookup_user(name);
-+      if (user) {
-+              ret = get_ksmbd_user(user);
-+              if (!ret)
-+                      user = NULL;
-+      }
-+      g_rw_lock_reader_unlock(&users_table_lock);
-+      return user;
-+}
-+
-+int usm_add_new_user(char *name, char *pwd)
-+{
-+      int ret = 0;
-+      struct ksmbd_user *user = new_ksmbd_user(name, pwd);
-+
-+      if (!user) {
-+              free(name);
-+              free(pwd);
-+              return -ENOMEM;
-+      }
-+
-+      g_rw_lock_writer_lock(&users_table_lock);
-+      if (__usm_lookup_user(name)) {
-+              g_rw_lock_writer_unlock(&users_table_lock);
-+              pr_info("User `%s' already exists\n", name);
-+              kill_ksmbd_user(user);
-+              return 0;
-+      }
-+
-+      pr_debug("New user `%s'\n", user->name);
-+      if (!g_hash_table_insert(users_table, user->name, user)) {
-+              kill_ksmbd_user(user);
-+              ret = -EINVAL;
-+      }
-+      g_rw_lock_writer_unlock(&users_table_lock);
-+      return ret;
-+}
-+
-+int usm_add_update_user_from_pwdentry(char *data)
-+{
-+      struct ksmbd_user *user;
-+      char *name;
-+      char *pwd;
-+      char *pos = strchr(data, ':');
-+      int ret;
-+
-+      if (!pos) {
-+              pr_err("Invalid pwd entry: %s\n", data);
-+              return -EINVAL;
-+      }
-+
-+      *pos = 0x00;
-+      name = g_strdup(data);
-+      pwd = g_strdup(pos + 1);
-+
-+      if (!name || !pwd) {
-+              free(name);
-+              free(pwd);
-+              return -ENOMEM;
-+      }
-+
-+      user = usm_lookup_user(name);
-+      if (user) {
-+              ret = usm_update_user_password(user, pwd);
-+              put_ksmbd_user(user);
-+
-+              free(name);
-+              free(pwd);
-+              return ret;
-+      }
-+      return usm_add_new_user(name, pwd);
-+}
-+
-+int usm_add_subauth_global_conf(char *data)
-+{
-+      char *pos = data;
-+      char *spos;
-+
-+      if (!pos)
-+              return -EINVAL;
-+
-+      spos = strchr(pos, ':');
-+      if (!spos) {
-+              pr_err("Invalid subauth entry: %s\n", data);
-+              return -EINVAL;
-+      }
-+
-+      *spos = 0x00;
-+      global_conf.gen_subauth[0] = atoi(pos);
-+      pos = spos + 1;
-+
-+      spos = strchr(pos, ':');
-+      if (!spos) {
-+              pr_err("Invalid subauth entry: %s\n", data);
-+              return -EINVAL;
-+      }
-+      *spos = 0x00;
-+      global_conf.gen_subauth[1] = atoi(pos);
-+      global_conf.gen_subauth[2] = atoi(spos + 1);
-+
-+      return 0;
-+}
-+
-+void for_each_ksmbd_user(walk_users cb, gpointer user_data)
-+{
-+      g_rw_lock_reader_lock(&users_table_lock);
-+      g_hash_table_foreach(users_table, cb, user_data);
-+      g_rw_lock_reader_unlock(&users_table_lock);
-+}
-+
-+int usm_update_user_password(struct ksmbd_user *user, char *pswd)
-+{
-+      size_t pass_sz;
-+      char *pass_b64 = g_strdup(pswd);
-+      char *pass = base64_decode(pass_b64, &pass_sz);
-+
-+      if (!pass_b64 || !pass) {
-+              free(pass_b64);
-+              free(pass);
-+              pr_err("Out of memory\n");
-+              return -ENOMEM;
-+      }
-+
-+      pr_debug("Update user password: %s\n", user->name);
-+      g_rw_lock_writer_lock(&user->update_lock);
-+      free(user->pass_b64);
-+      free(user->pass);
-+      user->pass_b64 = pass_b64;
-+      user->pass = pass;
-+      user->pass_sz = (int)pass_sz;
-+      g_rw_lock_writer_unlock(&user->update_lock);
-+
-+      return 0;
-+}
-+
-+static int usm_copy_user_passhash(struct ksmbd_user *user,
-+                                char *pass,
-+                                size_t sz)
-+{
-+      int ret = -ENOSPC;
-+
-+      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
-+              return 0;
-+
-+      g_rw_lock_reader_lock(&user->update_lock);
-+      if (sz >= user->pass_sz) {
-+              memcpy(pass, user->pass, user->pass_sz);
-+              ret = user->pass_sz;
-+      }
-+      g_rw_lock_reader_unlock(&user->update_lock);
-+
-+      return ret;
-+}
-+
-+static int usm_copy_user_account(struct ksmbd_user *user,
-+                               char *account,
-+                               size_t sz)
-+{
-+      int account_sz;
-+
-+      if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT))
-+              return 0;
-+
-+      account_sz = strlen(user->name);
-+      if (sz >= account_sz) {
-+              memcpy(account, user->name, account_sz);
-+              return 0;
-+      }
-+      pr_err("Cannot copy user data, buffer overrun\n");
-+      return -ENOSPC;
-+}
-+
-+static void __handle_login_request(struct ksmbd_login_response *resp,
-+                                 struct ksmbd_user *user)
-+{
-+      int hash_sz;
-+
-+      resp->gid = user->gid;
-+      resp->uid = user->uid;
-+      resp->status = user->flags;
-+      resp->status |= KSMBD_USER_FLAG_OK;
-+
-+      hash_sz = usm_copy_user_passhash(user,
-+                                       resp->hash,
-+                                       sizeof(resp->hash));
-+      if (hash_sz < 0) {
-+              resp->status = KSMBD_USER_FLAG_INVALID;
-+      } else {
-+              resp->hash_sz = (unsigned short)hash_sz;
-+              if (usm_copy_user_account(user,
-+                                        resp->account,
-+                                        sizeof(resp->account)))
-+                      resp->status = KSMBD_USER_FLAG_INVALID;
-+      }
-+}
-+
-+int usm_handle_login_request(struct ksmbd_login_request *req,
-+                           struct ksmbd_login_response *resp)
-+{
-+      struct ksmbd_user *user = NULL;
-+      int null_session = 0;
-+
-+      if (req->account[0] == '\0')
-+              null_session = 1;
-+
-+      if (!null_session)
-+              user = usm_lookup_user(req->account);
-+      if (user) {
-+              __handle_login_request(resp, user);
-+              put_ksmbd_user(user);
-+              return 0;
-+      }
-+
-+      resp->status = KSMBD_USER_FLAG_BAD_USER;
-+      if (!null_session &&
-+              global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER)
-+              return 0;
-+
-+      if (null_session ||
-+              global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_BAD_USER)
-+              user = usm_lookup_user(global_conf.guest_account);
-+
-+      if (!user)
-+              return 0;
-+
-+      __handle_login_request(resp, user);
-+      put_ksmbd_user(user);
-+      return 0;
-+}
-+
-+int usm_handle_logout_request(struct ksmbd_logout_request *req)
-+{
-+      struct ksmbd_user *user;
-+
-+      user = usm_lookup_user(req->account);
-+      if (!user)
-+              return -ENOENT;
-+
-+      if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) {
-+              if (user->failed_login_count < 10)
-+                      user->failed_login_count++;
-+              else
-+                      user->flags |= KSMBD_USER_FLAG_DELAY_SESSION;
-+      } else {
-+              user->failed_login_count = 0;
-+              user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION;
-+      }
-+
-+      put_ksmbd_user(user);
-+      return 0;
-+}
---- a/lib/meson.build
-+++ /dev/null
-@@ -1,31 +0,0 @@
--core_files = [
--  'management/tree_conn.c',
--  'management/user.c',
--  'management/share.c',
--  'management/session.c',
--  'config_parser.c',
--  'ksmbdtools.c',
--]
--
--if krb5_dep.found()
--  core_files += [
--    'management/spnego.c',
--    'asn1.c',
--    'management/spnego_krb5.c',
--  ]
--endif
--
--libksmbdtools = static_library(
--  'ksmbdtools',
--  core_files,
--  include_directories: tools_incdir,
--  dependencies: [
--    glib_dep,
--    krb5_dep,
--    asn1_lib,
--  ],
--  c_args: [
--    '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
--    '-DRUNSTATEDIR="@0@"'.format(runstatedir),
--  ],
--)
---- /dev/null
-+++ b/tools/meson.build
-@@ -0,0 +1,39 @@
-+ksmbd_tools_files = [
-+  'management/tree_conn.c',
-+  'management/user.c',
-+  'management/share.c',
-+  'management/session.c',
-+  'config_parser.c',
-+  'tools.c',
-+]
-+
-+if krb5_dep.found()
-+  ksmbd_tools_files += [
-+    'management/spnego.c',
-+    'asn1.c',
-+    'management/spnego_krb5.c',
-+  ]
-+endif
-+
-+executable(
-+  'ksmbd.tools',
-+  ksmbd_tools_files,
-+  include_directories: include_dirs,
-+  c_args: [
-+    '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')),
-+    '-DRUNSTATEDIR="@0@"'.format(runstatedir),
-+  ],
-+  dependencies: [
-+    glib_dep,
-+    krb5_dep,
-+    asn1_lib,
-+  ],
-+  link_with: [
-+    addshare_lib,
-+    adduser_lib,
-+    control_lib,
-+    mountd_lib,
-+  ],
-+  install: true,
-+  install_dir: get_option('libexecdir'),
-+)
---- a/lib/ksmbdtools.c
-+++ /dev/null
-@@ -1,276 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#include <syslog.h>
--
--#include <unistd.h>
--#include <sys/stat.h>
--#include <fcntl.h>
--
--#include <stdio.h>
--#include <ksmbdtools.h>
--
--int log_level = PR_INFO;
--int ksmbd_health_status;
--
--static const char *app_name = "unknown";
--static int log_open;
--
--typedef void (*logger)(int level, const char *fmt, va_list list);
--
--char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1] = {
--      "UTF-8",
--      "UTF-16LE",
--      "UCS-2LE",
--      "UTF-16BE",
--      "UCS-2BE",
--      "OOPS"
--};
--
--static int syslog_level(int level)
--{
--      if (level == PR_ERROR)
--              return LOG_ERR;
--      if (level == PR_INFO)
--              return LOG_INFO;
--      if (level == PR_DEBUG)
--              return LOG_DEBUG;
--
--      return LOG_ERR;
--}
--
--G_GNUC_PRINTF(2, 0)
--static void __pr_log_stdio(int level, const char *fmt, va_list list)
--{
--      char buf[1024];
--
--      vsnprintf(buf, sizeof(buf), fmt, list);
--      printf("%s", buf);
--}
--
--G_GNUC_PRINTF(2, 0)
--static void __pr_log_syslog(int level, const char *fmt, va_list list)
--{
--      vsyslog(syslog_level(level), fmt, list);
--}
--
--static logger __logger = __pr_log_stdio;
--
--void set_logger_app_name(const char *an)
--{
--      app_name = an;
--}
--
--const char *get_logger_app_name(void)
--{
--      return app_name;
--}
--
--void __pr_log(int level, const char *fmt, ...)
--{
--      va_list list;
--
--      va_start(list, fmt);
--      __logger(level, fmt, list);
--      va_end(list);
--}
--
--void pr_logger_init(int flag)
--{
--      if (flag == PR_LOGGER_SYSLOG) {
--              if (log_open) {
--                      closelog();
--                      log_open = 0;
--              }
--              openlog("ksmbd", LOG_NDELAY, LOG_LOCAL5);
--              __logger = __pr_log_syslog;
--              log_open = 1;
--      }
--}
--
--int set_log_level(int level)
--{
--      int old_level;
--
--      if (log_level == PR_DEBUG)
--              return log_level;
--
--      old_level = log_level;
--      log_level = level;
--      return old_level;
--}
--
--#if TRACING_DUMP_NL_MSG
--#define PR_HEX_DUMP_WIDTH     160
--void pr_hex_dump(const void *mem, size_t sz)
--{
--      char xline[PR_HEX_DUMP_WIDTH];
--      char sline[PR_HEX_DUMP_WIDTH];
--      int xi = 0, si = 0, mi = 0;
--
--      while (mi < sz) {
--              char c = *((char *)mem + mi);
--
--              mi++;
--              xi += sprintf(xline + xi, "%02X ", 0xff & c);
--              if (c > ' ' && c < '~')
--                      si += sprintf(sline + si, "%c", c);
--              else
--                      si += sprintf(sline + si, ".");
--              if (xi >= PR_HEX_DUMP_WIDTH / 2) {
--                      pr_err("%s         %s\n", xline, sline);
--                      xi = 0;
--                      si = 0;
--              }
--      }
--
--      if (xi) {
--              int sz = PR_HEX_DUMP_WIDTH / 2 - xi + 1;
--
--              if (sz > 0) {
--                      memset(xline + xi, ' ', sz);
--                      xline[PR_HEX_DUMP_WIDTH / 2 + 1] = 0x00;
--              }
--              pr_err("%s         %s\n", xline, sline);
--      }
--}
--#else
--void pr_hex_dump(const void *mem, size_t sz)
--{
--}
--#endif
--
--char *base64_encode(unsigned char *src, size_t srclen)
--{
--      return g_base64_encode(src, srclen);
--}
--
--unsigned char *base64_decode(char const *src, size_t *dstlen)
--{
--      unsigned char *ret = g_base64_decode(src, dstlen);
--
--      if (ret)
--              ret[*dstlen] = 0x00;
--      return ret;
--}
--
--static int codeset_has_altname(int codeset)
--{
--      if (codeset == KSMBD_CHARSET_UTF16LE ||
--                      codeset == KSMBD_CHARSET_UTF16BE)
--              return 1;
--      return 0;
--}
--
--gchar *ksmbd_gconvert(const gchar *str,
--                    gssize       str_len,
--                    int          to_codeset,
--                    int          from_codeset,
--                    gsize       *bytes_read,
--                    gsize       *bytes_written)
--{
--      gchar *converted;
--      GError *err;
--
--retry:
--      err = NULL;
--      if (from_codeset >= KSMBD_CHARSET_MAX) {
--              pr_err("Unknown source codeset: %d\n", from_codeset);
--              return NULL;
--      }
--
--      if (to_codeset >= KSMBD_CHARSET_MAX) {
--              pr_err("Unknown target codeset: %d\n", to_codeset);
--              return NULL;
--      }
--
--      converted = g_convert(str,
--                            str_len,
--                            ksmbd_conv_charsets[to_codeset],
--                            ksmbd_conv_charsets[from_codeset],
--                            bytes_read,
--                            bytes_written,
--                            &err);
--      if (err) {
--              int has_altname = 0;
--
--              if (codeset_has_altname(to_codeset)) {
--                      to_codeset++;
--                      has_altname = 1;
--              }
--
--              if (codeset_has_altname(from_codeset)) {
--                      from_codeset++;
--                      has_altname = 1;
--              }
--
--              pr_info("%s\n", err->message);
--              g_error_free(err);
--
--              if (has_altname) {
--                      pr_info("Will try `%s' and `%s'\n",
--                              ksmbd_conv_charsets[to_codeset],
--                              ksmbd_conv_charsets[from_codeset]);
--                      goto retry;
--              }
--
--              pr_err("Can't convert string: %s\n", err->message);
--              g_error_free(err);
--              return NULL;
--      }
--
--      return converted;
--}
--
--int send_signal_to_ksmbd_mountd(int signo)
--{
--      int fd, ret = -EINVAL;
--      char pid_buf[10] = {0};
--      int pid;
--
--      fd = open(KSMBD_LOCK_FILE, O_RDONLY);
--      if (fd < 0) {
--              pr_debug("Can't open `%s': %m\n", KSMBD_LOCK_FILE);
--              return ret;
--      }
--
--      if (read(fd, &pid_buf, sizeof(pid_buf)) == -1) {
--              pr_err("Can't read manager PID: %m\n");
--              goto out;
--      }
--
--      pid = strtol(pid_buf, NULL, 10);
--      if (signo)
--              pr_debug("Send signal %d (%s) to PID %d\n",
--                       signo, strsignal(signo), pid);
--      if (kill(pid, signo) == -1) {
--              ret = -errno;
--              if (signo)
--                      pr_err("Unable to send signal %d (%s) to PID %d: %m\n",
--                                      signo, strsignal(signo), pid);
--              goto out;
--      }
--
--      ret = 0;
--out:
--      close(fd);
--      return ret;
--}
--
--int test_file_access(char *conf)
--{
--      int fd;
--
--      fd = open(conf, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP);
--      if (fd < 0) {
--              pr_debug("Can't open `%s': %m\n", conf);
--              return -EINVAL;
--      }
--
--      close(fd);
--      return 0;
--}
---- /dev/null
-+++ b/tools/tools.c
-@@ -0,0 +1,301 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#include <syslog.h>
-+
-+#include <unistd.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+
-+#include <stdio.h>
-+#include <tools.h>
-+
-+int log_level = PR_INFO;
-+int ksmbd_health_status;
-+
-+static const char *app_name = "unknown";
-+static int log_open;
-+
-+typedef void (*logger)(int level, const char *fmt, va_list list);
-+
-+char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1] = {
-+      "UTF-8",
-+      "UTF-16LE",
-+      "UCS-2LE",
-+      "UTF-16BE",
-+      "UCS-2BE",
-+      "OOPS"
-+};
-+
-+static int syslog_level(int level)
-+{
-+      if (level == PR_ERROR)
-+              return LOG_ERR;
-+      if (level == PR_INFO)
-+              return LOG_INFO;
-+      if (level == PR_DEBUG)
-+              return LOG_DEBUG;
-+
-+      return LOG_ERR;
-+}
-+
-+G_GNUC_PRINTF(2, 0)
-+static void __pr_log_stdio(int level, const char *fmt, va_list list)
-+{
-+      char buf[1024];
-+
-+      vsnprintf(buf, sizeof(buf), fmt, list);
-+      printf("%s", buf);
-+}
-+
-+G_GNUC_PRINTF(2, 0)
-+static void __pr_log_syslog(int level, const char *fmt, va_list list)
-+{
-+      vsyslog(syslog_level(level), fmt, list);
-+}
-+
-+static logger __logger = __pr_log_stdio;
-+
-+void set_logger_app_name(const char *an)
-+{
-+      app_name = an;
-+}
-+
-+const char *get_logger_app_name(void)
-+{
-+      return app_name;
-+}
-+
-+void __pr_log(int level, const char *fmt, ...)
-+{
-+      va_list list;
-+
-+      va_start(list, fmt);
-+      __logger(level, fmt, list);
-+      va_end(list);
-+}
-+
-+void pr_logger_init(int flag)
-+{
-+      if (flag == PR_LOGGER_SYSLOG) {
-+              if (log_open) {
-+                      closelog();
-+                      log_open = 0;
-+              }
-+              openlog("ksmbd", LOG_NDELAY, LOG_LOCAL5);
-+              __logger = __pr_log_syslog;
-+              log_open = 1;
-+      }
-+}
-+
-+int set_log_level(int level)
-+{
-+      int old_level;
-+
-+      if (log_level == PR_DEBUG)
-+              return log_level;
-+
-+      old_level = log_level;
-+      log_level = level;
-+      return old_level;
-+}
-+
-+#if TRACING_DUMP_NL_MSG
-+#define PR_HEX_DUMP_WIDTH     160
-+void pr_hex_dump(const void *mem, size_t sz)
-+{
-+      char xline[PR_HEX_DUMP_WIDTH];
-+      char sline[PR_HEX_DUMP_WIDTH];
-+      int xi = 0, si = 0, mi = 0;
-+
-+      while (mi < sz) {
-+              char c = *((char *)mem + mi);
-+
-+              mi++;
-+              xi += sprintf(xline + xi, "%02X ", 0xff & c);
-+              if (c > ' ' && c < '~')
-+                      si += sprintf(sline + si, "%c", c);
-+              else
-+                      si += sprintf(sline + si, ".");
-+              if (xi >= PR_HEX_DUMP_WIDTH / 2) {
-+                      pr_err("%s         %s\n", xline, sline);
-+                      xi = 0;
-+                      si = 0;
-+              }
-+      }
-+
-+      if (xi) {
-+              int sz = PR_HEX_DUMP_WIDTH / 2 - xi + 1;
-+
-+              if (sz > 0) {
-+                      memset(xline + xi, ' ', sz);
-+                      xline[PR_HEX_DUMP_WIDTH / 2 + 1] = 0x00;
-+              }
-+              pr_err("%s         %s\n", xline, sline);
-+      }
-+}
-+#else
-+void pr_hex_dump(const void *mem, size_t sz)
-+{
-+}
-+#endif
-+
-+char *base64_encode(unsigned char *src, size_t srclen)
-+{
-+      return g_base64_encode(src, srclen);
-+}
-+
-+unsigned char *base64_decode(char const *src, size_t *dstlen)
-+{
-+      unsigned char *ret = g_base64_decode(src, dstlen);
-+
-+      if (ret)
-+              ret[*dstlen] = 0x00;
-+      return ret;
-+}
-+
-+static int codeset_has_altname(int codeset)
-+{
-+      if (codeset == KSMBD_CHARSET_UTF16LE ||
-+                      codeset == KSMBD_CHARSET_UTF16BE)
-+              return 1;
-+      return 0;
-+}
-+
-+gchar *ksmbd_gconvert(const gchar *str,
-+                    gssize       str_len,
-+                    int          to_codeset,
-+                    int          from_codeset,
-+                    gsize       *bytes_read,
-+                    gsize       *bytes_written)
-+{
-+      gchar *converted;
-+      GError *err;
-+
-+retry:
-+      err = NULL;
-+      if (from_codeset >= KSMBD_CHARSET_MAX) {
-+              pr_err("Unknown source codeset: %d\n", from_codeset);
-+              return NULL;
-+      }
-+
-+      if (to_codeset >= KSMBD_CHARSET_MAX) {
-+              pr_err("Unknown target codeset: %d\n", to_codeset);
-+              return NULL;
-+      }
-+
-+      converted = g_convert(str,
-+                            str_len,
-+                            ksmbd_conv_charsets[to_codeset],
-+                            ksmbd_conv_charsets[from_codeset],
-+                            bytes_read,
-+                            bytes_written,
-+                            &err);
-+      if (err) {
-+              int has_altname = 0;
-+
-+              if (codeset_has_altname(to_codeset)) {
-+                      to_codeset++;
-+                      has_altname = 1;
-+              }
-+
-+              if (codeset_has_altname(from_codeset)) {
-+                      from_codeset++;
-+                      has_altname = 1;
-+              }
-+
-+              pr_info("%s\n", err->message);
-+              g_error_free(err);
-+
-+              if (has_altname) {
-+                      pr_info("Will try `%s' and `%s'\n",
-+                              ksmbd_conv_charsets[to_codeset],
-+                              ksmbd_conv_charsets[from_codeset]);
-+                      goto retry;
-+              }
-+
-+              pr_err("Can't convert string: %s\n", err->message);
-+              g_error_free(err);
-+              return NULL;
-+      }
-+
-+      return converted;
-+}
-+
-+int send_signal_to_ksmbd_mountd(int signo)
-+{
-+      int fd, ret = -EINVAL;
-+      char pid_buf[10] = {0};
-+      int pid;
-+
-+      fd = open(KSMBD_LOCK_FILE, O_RDONLY);
-+      if (fd < 0) {
-+              pr_debug("Can't open `%s': %m\n", KSMBD_LOCK_FILE);
-+              return ret;
-+      }
-+
-+      if (read(fd, &pid_buf, sizeof(pid_buf)) == -1) {
-+              pr_err("Can't read manager PID: %m\n");
-+              goto out;
-+      }
-+
-+      pid = strtol(pid_buf, NULL, 10);
-+      if (signo)
-+              pr_debug("Send signal %d (%s) to PID %d\n",
-+                       signo, strsignal(signo), pid);
-+      if (kill(pid, signo) == -1) {
-+              ret = -errno;
-+              if (signo)
-+                      pr_err("Unable to send signal %d (%s) to PID %d: %m\n",
-+                                      signo, strsignal(signo), pid);
-+              goto out;
-+      }
-+
-+      ret = 0;
-+out:
-+      close(fd);
-+      return ret;
-+}
-+
-+int test_file_access(char *conf)
-+{
-+      int fd;
-+
-+      fd = open(conf, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP);
-+      if (fd < 0) {
-+              pr_debug("Can't open `%s': %m\n", conf);
-+              return -EINVAL;
-+      }
-+
-+      close(fd);
-+      return 0;
-+}
-+
-+int main(int argc, char **argv)
-+{
-+      char *base_name;
-+
-+      set_logger_app_name("ksmbd.tools");
-+
-+      if (!*argv)
-+              return EXIT_FAILURE;
-+
-+      base_name = strrchr(*argv, '/');
-+      base_name = base_name ? base_name + 1 : *argv;
-+
-+      if (!strcmp(base_name, "ksmbd.addshare"))
-+              return addshare_main(argc, argv);
-+      if (!strcmp(base_name, "ksmbd.adduser"))
-+              return adduser_main(argc, argv);
-+      if (!strcmp(base_name, "ksmbd.control"))
-+              return control_main(argc, argv);
-+      if (!strcmp(base_name, "ksmbd.mountd"))
-+              return mountd_main(argc, argv);
-+
-+      pr_err("Unknown base name: %s\n", base_name);
-+      return EXIT_FAILURE;
-+}
---- a/lib/asn1.c
-+++ /dev/null
-@@ -1,391 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
-- * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
-- *
-- * Copyright (c) 2000 RP Internet (www.rpi.net.au).
-- */
--
--/*****************************************************************************
-- *
-- * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
-- *
-- *****************************************************************************/
--#include <stdlib.h>
--#include <limits.h>
--#include <string.h>
--#include <errno.h>
--#include <glib.h>
--
--#include "asn1.h"
--
--void
--asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
--{
--      ctx->begin = buf;
--      ctx->end = buf + len;
--      ctx->pointer = buf;
--      ctx->error = ASN1_ERR_NOERROR;
--}
--
--static unsigned char
--asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
--{
--      if (ctx->pointer >= ctx->end) {
--              ctx->error = ASN1_ERR_DEC_EMPTY;
--              return 0;
--      }
--      *ch = *(ctx->pointer)++;
--      return 1;
--}
--
--static unsigned char
--asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
--{
--      unsigned char ch;
--
--      *tag = 0;
--
--      do {
--              if (!asn1_octet_decode(ctx, &ch))
--                      return 0;
--              *tag <<= 7;
--              *tag |= ch & 0x7F;
--      } while ((ch & 0x80) == 0x80);
--      return 1;
--}
--
--static unsigned char
--asn1_id_decode(struct asn1_ctx *ctx,
--             unsigned int *cls, unsigned int *con, unsigned int *tag)
--{
--      unsigned char ch;
--
--      if (!asn1_octet_decode(ctx, &ch))
--              return 0;
--
--      *cls = (ch & 0xC0) >> 6;
--      *con = (ch & 0x20) >> 5;
--      *tag = (ch & 0x1F);
--
--      if (*tag == 0x1F) {
--              if (!asn1_tag_decode(ctx, tag))
--                      return 0;
--      }
--      return 1;
--}
--
--static unsigned char
--asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
--{
--      unsigned char ch, cnt;
--
--      if (!asn1_octet_decode(ctx, &ch))
--              return 0;
--
--      if (ch == 0x80)
--              *def = 0;
--      else {
--              *def = 1;
--
--              if (ch < 0x80)
--                      *len = ch;
--              else {
--                      cnt = (unsigned char) (ch & 0x7F);
--                      *len = 0;
--
--                      while (cnt > 0) {
--                              if (!asn1_octet_decode(ctx, &ch))
--                                      return 0;
--                              *len <<= 8;
--                              *len |= ch;
--                              cnt--;
--                      }
--              }
--      }
--
--      /* don't trust len bigger than ctx buffer */
--      if (*len > ctx->end - ctx->pointer)
--              return 0;
--
--      return 1;
--}
--
--unsigned char
--asn1_header_decode(struct asn1_ctx *ctx,
--                 unsigned char **eoc,
--                 unsigned int *cls, unsigned int *con, unsigned int *tag)
--{
--      unsigned int def = 0;
--      unsigned int len = 0;
--
--      if (!asn1_id_decode(ctx, cls, con, tag))
--              return 0;
--
--      if (!asn1_length_decode(ctx, &def, &len))
--              return 0;
--
--      /* primitive shall be definite, indefinite shall be constructed */
--      if (*con == ASN1_PRI && !def)
--              return 0;
--
--      if (def)
--              *eoc = ctx->pointer + len;
--      else
--              *eoc = NULL;
--      return 1;
--}
--
--static unsigned char
--asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
--{
--      unsigned char ch;
--
--      if (eoc == NULL) {
--              if (!asn1_octet_decode(ctx, &ch))
--                      return 0;
--
--              if (ch != 0x00) {
--                      ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
--                      return 0;
--              }
--
--              if (!asn1_octet_decode(ctx, &ch))
--                      return 0;
--
--              if (ch != 0x00) {
--                      ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
--                      return 0;
--              }
--              return 1;
--      }
--
--      if (ctx->pointer != eoc) {
--              ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
--              return 0;
--      }
--      return 1;
--}
--
--unsigned char
--asn1_octets_decode(struct asn1_ctx *ctx,
--                 unsigned char *eoc,
--                 unsigned char **octets, unsigned int *len)
--{
--      unsigned char *ptr;
--
--      *len = 0;
--
--      *octets = malloc(eoc - ctx->pointer);
--      if (*octets == NULL)
--              return 0;
--
--      ptr = *octets;
--      while (ctx->pointer < eoc) {
--              if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
--                      free(*octets);
--                      *octets = NULL;
--                      return 0;
--              }
--              (*len)++;
--      }
--      return 1;
--}
--
--unsigned char asn1_read(struct asn1_ctx *ctx,
--              unsigned char **buf, unsigned int len)
--{
--      *buf = NULL;
--      if (ctx->end - ctx->pointer < len) {
--              ctx->error = ASN1_ERR_DEC_EMPTY;
--              return 0;
--      }
--
--      *buf = malloc(len);
--      if (!*buf)
--              return 0;
--      memcpy(*buf, ctx->pointer, len);
--      ctx->pointer += len;
--      return 1;
--}
--
--static unsigned char
--asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
--{
--      unsigned char ch;
--
--      *subid = 0;
--
--      do {
--              if (!asn1_octet_decode(ctx, &ch))
--                      return 0;
--
--              *subid <<= 7;
--              *subid |= ch & 0x7F;
--      } while ((ch & 0x80) == 0x80);
--      return 1;
--}
--
--int
--asn1_oid_decode(struct asn1_ctx *ctx,
--              unsigned char *eoc, unsigned long **oid, unsigned int *len)
--{
--      unsigned long subid;
--      unsigned int size;
--      unsigned long *optr;
--
--      size = eoc - ctx->pointer + 1;
--
--      /* first subid actually encodes first two subids */
--      if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
--              return 0;
--
--      *oid = g_try_malloc0_n(size, sizeof(unsigned long));
--      if (*oid == NULL)
--              return 0;
--
--      optr = *oid;
--
--      if (!asn1_subid_decode(ctx, &subid)) {
--              g_free(*oid);
--              *oid = NULL;
--              return 0;
--      }
--
--      if (subid < 40) {
--              optr[0] = 0;
--              optr[1] = subid;
--      } else if (subid < 80) {
--              optr[0] = 1;
--              optr[1] = subid - 40;
--      } else {
--              optr[0] = 2;
--              optr[1] = subid - 80;
--      }
--
--      *len = 2;
--      optr += 2;
--
--      while (ctx->pointer < eoc) {
--              if (++(*len) > size) {
--                      ctx->error = ASN1_ERR_DEC_BADVALUE;
--                      g_free(*oid);
--                      *oid = NULL;
--                      return 0;
--              }
--
--              if (!asn1_subid_decode(ctx, optr++)) {
--                      g_free(*oid);
--                      *oid = NULL;
--                      return 0;
--              }
--      }
--      return 1;
--}
--
--/* return the size of @depth-nested headers + payload */
--int asn1_header_len(unsigned int payload_len, int depth)
--{
--      unsigned int len;
--      int i;
--
--      len = payload_len;
--      for (i = 0; i < depth; i++) {
--              /* length */
--              if (len >= (1 << 24))
--                      len += 5;
--              else if (len >= (1 << 16))
--                      len += 4;
--              else if (len >= (1 << 8))
--                      len += 3;
--              else if (len >= (1 << 7))
--                      len += 2;
--              else
--                      len += 1;
--              /* 1-byte header */
--              len += 1;
--      }
--      return len;
--}
--
--int asn1_oid_encode(const unsigned long *in_oid, int in_len,
--                      unsigned char **out_oid, int *out_len)
--{
--      unsigned char *oid;
--      unsigned long id;
--      int i;
--
--      *out_oid = g_try_malloc0_n(in_len, 5);
--      if (*out_oid == NULL)
--              return -ENOMEM;
--
--      oid = *out_oid;
--      *oid++ = (unsigned char)(40 * in_oid[0] + in_oid[1]);
--      for (i = 2; i < in_len; i++) {
--              id = in_oid[i];
--              if (id >= (1 << 28))
--                      *oid++ = (0x80 | ((id>>28) & 0x7F));
--              if (id >= (1 << 21))
--                      *oid++ = (0x80 | ((id>>21) & 0x7F));
--              if (id >= (1 << 14))
--                      *oid++ = (0x80 | ((id>>14) & 0x7F));
--              if (id >= (1 << 7))
--                      *oid++ = (0x80 | ((id>>7) & 0x7F));
--              *oid++ = id & 0x7F;
--      }
--      *out_len = (int)(oid - *out_oid);
--      return 0;
--}
--
--/*
-- * @len is the sum of all sizes of header, length and payload.
-- * it will be decreased by the sum of sizes of header and length.
-- */
--int asn1_header_encode(unsigned char **buf,
--                      unsigned int cls, unsigned int con, unsigned int tag,
--                      unsigned int *len)
--{
--      unsigned char *loc;
--      unsigned int r_len;
--
--      /* at least, 1-byte header + 1-byte length is needed. */
--      if (*len < 2)
--              return -EINVAL;
--
--      loc = *buf;
--      r_len = *len;
--
--      *loc++ = ((cls & 0x3) << 6) | ((con & 0x1) << 5) | (tag & 0x1F);
--      r_len -= 1;
--
--      if (r_len - 1 < (1 << 7)) {
--              r_len -= 1;
--              *loc++ = (unsigned char)(r_len & 0x7F);
--      } else if (r_len - 2 < (1 << 8)) {
--              r_len -= 2;
--              *loc++ = 0x81;
--              *loc++ = (unsigned char)(r_len & 0xFF);
--      } else if (r_len - 3 < (1 << 16)) {
--              r_len -= 3;
--              *loc++ = 0x82;
--              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
--              *loc++ = (unsigned char)(r_len & 0xFF);
--      } else if (r_len - 4 < (1 << 24)) {
--              r_len -= 4;
--              *loc++ = 0x83;
--              *loc++ = (unsigned char)((r_len>>16) & 0xFF);
--              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
--              *loc++ = (unsigned char)(r_len & 0xFF);
--      } else {
--              r_len -= 5;
--              *loc++ = 0x84;
--              *loc++ = (unsigned char)((r_len>>24) & 0xFF);
--              *loc++ = (unsigned char)((r_len>>16) & 0xFF);
--              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
--              *loc++ = (unsigned char)(r_len & 0xFF);
--      }
--
--      *buf = loc;
--      *len = r_len;
--      return 0;
--}
---- a/lib/management/spnego_mech.h
-+++ /dev/null
-@@ -1,48 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-or-later */
--/*
-- *   Copyright (C) 2020 LG Electronics
-- *
-- *   linux-cifsd-devel@lists.sourceforge.net
-- */
--
--#ifndef _SPNEGO_MECH_H_
--#define _SPNEGO_MECH_H_
--
--enum {
--      SPNEGO_MECH_MSKRB5      = 0,
--      SPNEGO_MECH_KRB5,
--      SPNEGO_MAX_MECHS,
--};
--
--struct spnego_mech_ctx;
--
--typedef int (*spnego_encode_t)(char *in_blob, int in_len,
--                              const unsigned long *oid, int oid_len,
--                              char **out_blob, int *out_len);
--
--struct spnego_mech_operations {
--      int (*setup)(struct spnego_mech_ctx *mech_ctx);
--      void (*cleanup)(struct spnego_mech_ctx *mech_ctx);
--      int (*handle_authen)(struct spnego_mech_ctx *mech_ctx,
--                              char *in_blob, unsigned int in_len,
--                              struct ksmbd_spnego_auth_out *auth_out,
--                              spnego_encode_t encode);
--};
--
--struct spnego_mech_ctx {
--      const unsigned long     *oid;
--      int                     oid_len;
--      void                    *private;
--      union {
--              struct {
--                      void *keytab_name;
--                      void *service_name;
--              } krb5;
--      } params;
--      struct spnego_mech_operations *ops;
--};
--
--extern struct spnego_mech_operations spnego_krb5_operations;
--extern struct spnego_mech_operations spnego_mskrb5_operations;
--
--#endif
---- /dev/null
-+++ b/tools/asn1.c
-@@ -0,0 +1,391 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
-+ * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
-+ *
-+ * Copyright (c) 2000 RP Internet (www.rpi.net.au).
-+ */
-+
-+/*****************************************************************************
-+ *
-+ * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
-+ *
-+ *****************************************************************************/
-+#include <stdlib.h>
-+#include <limits.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <glib.h>
-+
-+#include "asn1.h"
-+
-+void
-+asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
-+{
-+      ctx->begin = buf;
-+      ctx->end = buf + len;
-+      ctx->pointer = buf;
-+      ctx->error = ASN1_ERR_NOERROR;
-+}
-+
-+static unsigned char
-+asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
-+{
-+      if (ctx->pointer >= ctx->end) {
-+              ctx->error = ASN1_ERR_DEC_EMPTY;
-+              return 0;
-+      }
-+      *ch = *(ctx->pointer)++;
-+      return 1;
-+}
-+
-+static unsigned char
-+asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
-+{
-+      unsigned char ch;
-+
-+      *tag = 0;
-+
-+      do {
-+              if (!asn1_octet_decode(ctx, &ch))
-+                      return 0;
-+              *tag <<= 7;
-+              *tag |= ch & 0x7F;
-+      } while ((ch & 0x80) == 0x80);
-+      return 1;
-+}
-+
-+static unsigned char
-+asn1_id_decode(struct asn1_ctx *ctx,
-+             unsigned int *cls, unsigned int *con, unsigned int *tag)
-+{
-+      unsigned char ch;
-+
-+      if (!asn1_octet_decode(ctx, &ch))
-+              return 0;
-+
-+      *cls = (ch & 0xC0) >> 6;
-+      *con = (ch & 0x20) >> 5;
-+      *tag = (ch & 0x1F);
-+
-+      if (*tag == 0x1F) {
-+              if (!asn1_tag_decode(ctx, tag))
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+static unsigned char
-+asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
-+{
-+      unsigned char ch, cnt;
-+
-+      if (!asn1_octet_decode(ctx, &ch))
-+              return 0;
-+
-+      if (ch == 0x80)
-+              *def = 0;
-+      else {
-+              *def = 1;
-+
-+              if (ch < 0x80)
-+                      *len = ch;
-+              else {
-+                      cnt = (unsigned char) (ch & 0x7F);
-+                      *len = 0;
-+
-+                      while (cnt > 0) {
-+                              if (!asn1_octet_decode(ctx, &ch))
-+                                      return 0;
-+                              *len <<= 8;
-+                              *len |= ch;
-+                              cnt--;
-+                      }
-+              }
-+      }
-+
-+      /* don't trust len bigger than ctx buffer */
-+      if (*len > ctx->end - ctx->pointer)
-+              return 0;
-+
-+      return 1;
-+}
-+
-+unsigned char
-+asn1_header_decode(struct asn1_ctx *ctx,
-+                 unsigned char **eoc,
-+                 unsigned int *cls, unsigned int *con, unsigned int *tag)
-+{
-+      unsigned int def = 0;
-+      unsigned int len = 0;
-+
-+      if (!asn1_id_decode(ctx, cls, con, tag))
-+              return 0;
-+
-+      if (!asn1_length_decode(ctx, &def, &len))
-+              return 0;
-+
-+      /* primitive shall be definite, indefinite shall be constructed */
-+      if (*con == ASN1_PRI && !def)
-+              return 0;
-+
-+      if (def)
-+              *eoc = ctx->pointer + len;
-+      else
-+              *eoc = NULL;
-+      return 1;
-+}
-+
-+static unsigned char
-+asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
-+{
-+      unsigned char ch;
-+
-+      if (eoc == NULL) {
-+              if (!asn1_octet_decode(ctx, &ch))
-+                      return 0;
-+
-+              if (ch != 0x00) {
-+                      ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
-+                      return 0;
-+              }
-+
-+              if (!asn1_octet_decode(ctx, &ch))
-+                      return 0;
-+
-+              if (ch != 0x00) {
-+                      ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
-+                      return 0;
-+              }
-+              return 1;
-+      }
-+
-+      if (ctx->pointer != eoc) {
-+              ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
-+              return 0;
-+      }
-+      return 1;
-+}
-+
-+unsigned char
-+asn1_octets_decode(struct asn1_ctx *ctx,
-+                 unsigned char *eoc,
-+                 unsigned char **octets, unsigned int *len)
-+{
-+      unsigned char *ptr;
-+
-+      *len = 0;
-+
-+      *octets = malloc(eoc - ctx->pointer);
-+      if (*octets == NULL)
-+              return 0;
-+
-+      ptr = *octets;
-+      while (ctx->pointer < eoc) {
-+              if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
-+                      free(*octets);
-+                      *octets = NULL;
-+                      return 0;
-+              }
-+              (*len)++;
-+      }
-+      return 1;
-+}
-+
-+unsigned char asn1_read(struct asn1_ctx *ctx,
-+              unsigned char **buf, unsigned int len)
-+{
-+      *buf = NULL;
-+      if (ctx->end - ctx->pointer < len) {
-+              ctx->error = ASN1_ERR_DEC_EMPTY;
-+              return 0;
-+      }
-+
-+      *buf = malloc(len);
-+      if (!*buf)
-+              return 0;
-+      memcpy(*buf, ctx->pointer, len);
-+      ctx->pointer += len;
-+      return 1;
-+}
-+
-+static unsigned char
-+asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
-+{
-+      unsigned char ch;
-+
-+      *subid = 0;
-+
-+      do {
-+              if (!asn1_octet_decode(ctx, &ch))
-+                      return 0;
-+
-+              *subid <<= 7;
-+              *subid |= ch & 0x7F;
-+      } while ((ch & 0x80) == 0x80);
-+      return 1;
-+}
-+
-+int
-+asn1_oid_decode(struct asn1_ctx *ctx,
-+              unsigned char *eoc, unsigned long **oid, unsigned int *len)
-+{
-+      unsigned long subid;
-+      unsigned int size;
-+      unsigned long *optr;
-+
-+      size = eoc - ctx->pointer + 1;
-+
-+      /* first subid actually encodes first two subids */
-+      if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
-+              return 0;
-+
-+      *oid = g_try_malloc0_n(size, sizeof(unsigned long));
-+      if (*oid == NULL)
-+              return 0;
-+
-+      optr = *oid;
-+
-+      if (!asn1_subid_decode(ctx, &subid)) {
-+              g_free(*oid);
-+              *oid = NULL;
-+              return 0;
-+      }
-+
-+      if (subid < 40) {
-+              optr[0] = 0;
-+              optr[1] = subid;
-+      } else if (subid < 80) {
-+              optr[0] = 1;
-+              optr[1] = subid - 40;
-+      } else {
-+              optr[0] = 2;
-+              optr[1] = subid - 80;
-+      }
-+
-+      *len = 2;
-+      optr += 2;
-+
-+      while (ctx->pointer < eoc) {
-+              if (++(*len) > size) {
-+                      ctx->error = ASN1_ERR_DEC_BADVALUE;
-+                      g_free(*oid);
-+                      *oid = NULL;
-+                      return 0;
-+              }
-+
-+              if (!asn1_subid_decode(ctx, optr++)) {
-+                      g_free(*oid);
-+                      *oid = NULL;
-+                      return 0;
-+              }
-+      }
-+      return 1;
-+}
-+
-+/* return the size of @depth-nested headers + payload */
-+int asn1_header_len(unsigned int payload_len, int depth)
-+{
-+      unsigned int len;
-+      int i;
-+
-+      len = payload_len;
-+      for (i = 0; i < depth; i++) {
-+              /* length */
-+              if (len >= (1 << 24))
-+                      len += 5;
-+              else if (len >= (1 << 16))
-+                      len += 4;
-+              else if (len >= (1 << 8))
-+                      len += 3;
-+              else if (len >= (1 << 7))
-+                      len += 2;
-+              else
-+                      len += 1;
-+              /* 1-byte header */
-+              len += 1;
-+      }
-+      return len;
-+}
-+
-+int asn1_oid_encode(const unsigned long *in_oid, int in_len,
-+                      unsigned char **out_oid, int *out_len)
-+{
-+      unsigned char *oid;
-+      unsigned long id;
-+      int i;
-+
-+      *out_oid = g_try_malloc0_n(in_len, 5);
-+      if (*out_oid == NULL)
-+              return -ENOMEM;
-+
-+      oid = *out_oid;
-+      *oid++ = (unsigned char)(40 * in_oid[0] + in_oid[1]);
-+      for (i = 2; i < in_len; i++) {
-+              id = in_oid[i];
-+              if (id >= (1 << 28))
-+                      *oid++ = (0x80 | ((id>>28) & 0x7F));
-+              if (id >= (1 << 21))
-+                      *oid++ = (0x80 | ((id>>21) & 0x7F));
-+              if (id >= (1 << 14))
-+                      *oid++ = (0x80 | ((id>>14) & 0x7F));
-+              if (id >= (1 << 7))
-+                      *oid++ = (0x80 | ((id>>7) & 0x7F));
-+              *oid++ = id & 0x7F;
-+      }
-+      *out_len = (int)(oid - *out_oid);
-+      return 0;
-+}
-+
-+/*
-+ * @len is the sum of all sizes of header, length and payload.
-+ * it will be decreased by the sum of sizes of header and length.
-+ */
-+int asn1_header_encode(unsigned char **buf,
-+                      unsigned int cls, unsigned int con, unsigned int tag,
-+                      unsigned int *len)
-+{
-+      unsigned char *loc;
-+      unsigned int r_len;
-+
-+      /* at least, 1-byte header + 1-byte length is needed. */
-+      if (*len < 2)
-+              return -EINVAL;
-+
-+      loc = *buf;
-+      r_len = *len;
-+
-+      *loc++ = ((cls & 0x3) << 6) | ((con & 0x1) << 5) | (tag & 0x1F);
-+      r_len -= 1;
-+
-+      if (r_len - 1 < (1 << 7)) {
-+              r_len -= 1;
-+              *loc++ = (unsigned char)(r_len & 0x7F);
-+      } else if (r_len - 2 < (1 << 8)) {
-+              r_len -= 2;
-+              *loc++ = 0x81;
-+              *loc++ = (unsigned char)(r_len & 0xFF);
-+      } else if (r_len - 3 < (1 << 16)) {
-+              r_len -= 3;
-+              *loc++ = 0x82;
-+              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
-+              *loc++ = (unsigned char)(r_len & 0xFF);
-+      } else if (r_len - 4 < (1 << 24)) {
-+              r_len -= 4;
-+              *loc++ = 0x83;
-+              *loc++ = (unsigned char)((r_len>>16) & 0xFF);
-+              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
-+              *loc++ = (unsigned char)(r_len & 0xFF);
-+      } else {
-+              r_len -= 5;
-+              *loc++ = 0x84;
-+              *loc++ = (unsigned char)((r_len>>24) & 0xFF);
-+              *loc++ = (unsigned char)((r_len>>16) & 0xFF);
-+              *loc++ = (unsigned char)((r_len>>8) & 0xFF);
-+              *loc++ = (unsigned char)(r_len & 0xFF);
-+      }
-+
-+      *buf = loc;
-+      *len = r_len;
-+      return 0;
-+}
---- /dev/null
-+++ b/tools/management/spnego_mech.h
-@@ -0,0 +1,48 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ *   Copyright (C) 2020 LG Electronics
-+ *
-+ *   linux-cifsd-devel@lists.sourceforge.net
-+ */
-+
-+#ifndef _SPNEGO_MECH_H_
-+#define _SPNEGO_MECH_H_
-+
-+enum {
-+      SPNEGO_MECH_MSKRB5      = 0,
-+      SPNEGO_MECH_KRB5,
-+      SPNEGO_MAX_MECHS,
-+};
-+
-+struct spnego_mech_ctx;
-+
-+typedef int (*spnego_encode_t)(char *in_blob, int in_len,
-+                              const unsigned long *oid, int oid_len,
-+                              char **out_blob, int *out_len);
-+
-+struct spnego_mech_operations {
-+      int (*setup)(struct spnego_mech_ctx *mech_ctx);
-+      void (*cleanup)(struct spnego_mech_ctx *mech_ctx);
-+      int (*handle_authen)(struct spnego_mech_ctx *mech_ctx,
-+                              char *in_blob, unsigned int in_len,
-+                              struct ksmbd_spnego_auth_out *auth_out,
-+                              spnego_encode_t encode);
-+};
-+
-+struct spnego_mech_ctx {
-+      const unsigned long     *oid;
-+      int                     oid_len;
-+      void                    *private;
-+      union {
-+              struct {
-+                      void *keytab_name;
-+                      void *service_name;
-+              } krb5;
-+      } params;
-+      struct spnego_mech_operations *ops;
-+};
-+
-+extern struct spnego_mech_operations spnego_krb5_operations;
-+extern struct spnego_mech_operations spnego_mskrb5_operations;
-+
-+#endif
index 5d4c2a08c2e93da1cf2879e80f9f02e76a964c06..6373f309c5fd63a1ac6fe977d9a7245fd5053afe 100644 (file)
@@ -8,16 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=miniupnpd
-
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/miniupnp/miniupnp.git
-PKG_SOURCE_DATE:=2022-08-31
-PKG_SOURCE_VERSION:=68c8ec508a421f4f4af67a63e3eb6f497d2531e1
-PKG_MIRROR_HASH:=68a3170ec73149c4cf4855b1ce6e031557cc12bff85a58421bb94785daaf225d
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)/miniupnpd
-
+PKG_VERSION:=2.3.3
 PKG_RELEASE:=1
 
+PKG_SOURCE_URL:=https://miniupnp.tuxfamily.org/files
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=6fd7019f936ff88c41e7c822f46f10b51bd72d665978f6586483de75b30c36bf
+
 PKG_MAINTAINER:=
 PKG_LICENSE:=BSD-3-Clause
 PKG_LICENSE_FILES:=LICENSE
@@ -29,9 +26,6 @@ PKG_BUILD_PARALLEL:=1
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/version.mk
 
-TAR_OPTIONS+= --strip-components 1
-TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS)
-
 define Package/miniupnpd/Default
   SECTION:=net
   CATEGORY:=Network
index 6cbd6f7383e19486683602857d1c8f0403a2929c..e27988733d8db6827709cfb446f71b3ff337bf0b 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=modemmanager
-PKG_SOURCE_VERSION:=1.20.2
+PKG_SOURCE_VERSION:=1.20.6
 PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
-PKG_MIRROR_HASH:=f138effc693456c5040ec22e17c0a8b41143c3b17b62437462995c297a9150dc
+PKG_MIRROR_HASH:=e90103e2e42bb826bbbac83937a9a69f50348cd6ce0d8da655a12b65494ce7c9
 
 PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
 PKG_LICENSE:=GPL-2.0-or-later
index 561557203fbf3f888ff732744f92acc3be8f3401..6f0a0d716fc45eeae856c2dfa344d31f0a15fdb4 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=netbird
-PKG_VERSION:=0.12.0
+PKG_VERSION:=0.14.2
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/netbirdio/netbird/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=c88b65bb9358e5a6f9c34882e77a3414b02d4c5ac13b76fb2e60b952af6a18d7
+PKG_HASH:=8ffef4569572b9eb93891e881cb7b3b9ba98b5596f3ffda3b433b32e364adb56
 
 PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
 PKG_LICENSE:=BSD-3-Clause
index 85a913ed4ed880fdb9618a646a290124239bb3e4..6695acc659e1a143f56fa575118be365d0ced3b1 100644 (file)
@@ -16,10 +16,9 @@ PKG_INSTALL:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gitlab.com/netify.ai/public/netify-agent.git
-PKG_SOURCE_DATE:=2022-11-03
-PKG_SOURCE_VERSION:=v4.2.2
-#PKG_SOURCE_VERSION:=e8d649e170ad3f85017115ea5414ade5f297e9c5
-PKG_MIRROR_HASH:=34a9f89aa88f666e6f9e6e8fcbfaa94b02cfc4ce6e76c521377af9492d12a90d
+PKG_SOURCE_DATE:=2023-03-03
+PKG_SOURCE_VERSION:=v4.4.1
+PKG_MIRROR_HASH:=aa3522b6d86e113943abacd50b235738e6452991a36864ec70f5db5b7bec6d13
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -49,11 +48,10 @@ define Package/netifyd/conffiles
 /etc/netify.d/agent.uuid
 /etc/netify.d/serial.uuid
 /etc/netify.d/site.uuid
-/etc/netify.d/netify-categories.json
 endef
 
 TARGET_CFLAGS+=-ffunction-sections -fdata-sections -Wno-psabi
-TARGET_CXXFLAGS+=-ffunction-sections -fdata-sections -Wno-psabi
+TARGET_CXXFLAGS+=-std=c++11 -ffunction-sections -fdata-sections -Wno-psabi
 TARGET_LDFLAGS+=-Wl,--gc-sections
 
 CONFIGURE_ARGS+= \
@@ -74,10 +72,6 @@ CONFIGURE_ARGS+= \
        --without-libcurl-zlib
 endif
 
-define Build/Configure
-       (cd $(PKG_BUILD_DIR); ./autogen.sh)
-       $(call Build/Configure/Default)
-endef
 
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include/netifyd
@@ -86,6 +80,8 @@ define Build/InstallDev
        $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/pcap-compat/*.h $(1)/usr/include/netifyd/pcap-compat
        $(INSTALL_DIR) $(1)/usr/include/netifyd/nlohmann
        $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/nlohmann/*.hpp $(1)/usr/include/netifyd/nlohmann
+       $(INSTALL_DIR) $(1)/usr/include/netifyd/radix
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/radix/*.hpp $(1)/usr/include/netifyd/radix
        $(INSTALL_DIR) $(1)/usr/include/ndpi
        $(CP) $(PKG_INSTALL_DIR)/usr/include/ndpi/*.h $(1)/usr/include/ndpi
        $(INSTALL_DIR) $(1)/usr/lib
index 5be05462f962cc0d760564930559d518489b0385..b976c1d118261d4e772387beebf9587d51dd6ab1 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pdns-recursor
-PKG_VERSION:=4.8.2
+PKG_VERSION:=4.8.3
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/
-PKG_HASH:=4382d3e84f13401685772779dfede6cbc8157ecf6763fa7fdb1dd33ee3f79ac7
+PKG_HASH:=37b91a5458c54411f4e38e2d1263ecf41e751e43c5fd66e813100d9978f02505
 
 PKG_MAINTAINER:=Peter van Dijk <peter.van.dijk@powerdns.com>
 PKG_LICENCE:=GPL-2.0-only
index 77cc23f30287d7d2b70398eea02211efae26fe1a..6ed983a2d6d28191d30481fb924909bc2220c404 100644 (file)
@@ -2,8 +2,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=samba
-PKG_VERSION:=4.17.2
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_VERSION:=4.17.5
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:= \
@@ -13,7 +13,7 @@ PKG_SOURCE_URL:= \
                http://www.nic.funet.fi/index/samba/pub/samba/stable/ \
                http://samba.mirror.bit.nl/samba/ftp/stable/ \
                https://download.samba.org/pub/samba/stable/
-PKG_HASH:=e55ddf4d5178f8c84316abf53c5edd7b35399e3b7d86bcb81b75261c827bb3b8
+PKG_HASH:=ebb7880d474ffc09d73b5fc77bcbd657f6235910337331a9c24d7f69ca11442b
 
 PKG_LICENSE:=GPL-3.0-only
 PKG_LICENSE_FILES:=COPYING
index de1395217c0a7284b6dc5e69a04690a4f5425fe2..db846b9048ce208efefc597f140e5a8cf8506127 100644 (file)
@@ -1,6 +1,6 @@
 --- a/source4/lib/messaging/messaging.c
 +++ b/source4/lib/messaging/messaging.c
-@@ -514,7 +514,7 @@ static struct imessaging_context *imessa
+@@ -525,7 +525,7 @@ static struct imessaging_context *imessa
                goto fail;
        }
  
index bb4852502ea97ed8950162c6bb60f14b5112c795..15169eacb8945fa858ec15f2228acc8367833bdc 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=simple-adblock
 PKG_VERSION:=1.9.4
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
 PKG_LICENSE:=GPL-3.0-or-later
 
index 46518c6ee2078ca2a2de2414f6dcdc91b96b7f58..7949156aa7e3cb84930da73af34e1a70b2bd78a0 100644 (file)
@@ -64,6 +64,10 @@ config simple-adblock 'config'
 # block-list too big for most routers
 #      list blocked_hosts_url 'https://cdn.jsdelivr.net/gh/StevenBlack/hosts/hosts'
 
+# File size: 2.0M
+# block-list too big for most routers
+#      list blocked_domains_url https://cdn.jsdelivr.net/gh/bongochong/CombinedPrivacyBlockLists/NoFormatting/cpbl-ctld.txt
+
 # File size: 3.1M
 # block-list too big for most routers
 #      list blocked_hosts_url 'https://hostsfile.mine.nu/Hosts'
index 1522569abbc4f86f2e67502c3356ed32fc12c7a9..87fdfdef761d0fce4a3c799f0c564a3bb4efc946 100644 (file)
@@ -88,9 +88,6 @@ outputCache=
 awk='awk'
 load_environment_flag=
 
-. /lib/functions/network.sh
-. /usr/share/libubox/jshn.sh
-
 debug() { local i j; for i in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; }
 
 uci_add_list_if_new() {
@@ -1562,6 +1559,8 @@ stop_service() { load_validate_config 'config' adb_stop "'$*'"; }
 version() { echo "$PKG_VERSION"; }
 
 load_validate_config() {
+       . /lib/functions/network.sh
+       . /usr/share/libubox/jshn.sh
        local enabled
        local force_dns
        local force_dns_port
index 921f599cc1a9ea93613440fffdf4e01026431ae9..7103e36e12df5ae213a767ec4dcb33c86a3df06e 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sing-box
-PKG_VERSION:=1.1.5
+PKG_VERSION:=1.1.6
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=a1e642362f41bd0e362cd9c8d2f0d29d2eca6a55a948677f6f03cfb81c4f0657
+PKG_HASH:=2fdf93fd49c9375cd14b2fe2e2163cbad4b65d0cfa422c592855e7810036ef56
 
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_LICENSE_FILES:=LICENSE
@@ -27,7 +27,7 @@ define Package/sing-box
   SECTION:=net
   CATEGORY:=Network
   URL:=https://sing-box.sagernet.org
-  DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +kmod-tun
+  DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +kmod-inet-diag +kmod-tun
   USERID:=sing-box=5566:sing-box=5566
 endef
 
@@ -42,7 +42,6 @@ define Package/sing-box/config
 
                config SINGBOX_WITH_ACME
                        bool "Build with ACME TLS certificate issuer support"
-                       default n
 
                config SINGBOX_WITH_CLASH_API
                        bool "Build with Clash API support"
@@ -50,15 +49,12 @@ define Package/sing-box/config
 
                config SINGBOX_WITH_ECH
                        bool "Build with TLS ECH extension support for TLS outbound"
-                       default n
 
                config SINGBOX_WITH_EMBEDDED_TOR
                        bool "Build with embedded Tor support"
-                       default n
 
                config SINGBOX_WITH_GRPC
                        bool "Build with standard gRPC support"
-                       default n
 
                config SINGBOX_WITH_GVISOR
                        bool "Build with gVisor support"
@@ -66,7 +62,6 @@ define Package/sing-box/config
 
                config SINGBOX_WITH_LWIP
                        bool "Build with LWIP Tun stack support"
-                       default n
 
                config SINGBOX_WITH_QUIC
                        bool "Build with QUIC support"
@@ -74,7 +69,6 @@ define Package/sing-box/config
 
                config SINGBOX_WITH_SHADOWSOCKSR
                        bool "Build with ShadowsocksR support"
-                       default n
 
                config SINGBOX_WITH_UTLS
                        bool "Build with uTLS support for TLS outbound"
@@ -82,7 +76,6 @@ define Package/sing-box/config
 
                config SINGBOX_WITH_V2RAY_API
                        bool "Build with V2Ray API support"
-                       default n
 
                config SINGBOX_WITH_WIREGUARD
                        bool "Build with WireGuard support"
index 9ba0318715930efd710f3c17cb47b15401c06ee6..2c989ccb33742b71614d8bcd2efe2e444c01bd75 100644 (file)
@@ -6,12 +6,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=snort3
-PKG_VERSION:=3.1.53.0
+PKG_VERSION:=3.1.56.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/snort3/snort3/archive/refs/tags/
-PKG_HASH:=e76429903cc56353ab21c0f4c0ec495054ba82f56d8d94943930bc0c3165be4c
+PKG_HASH:=b757705e1ee2a560b94791b3f474fe1c562c98049ebb0c807e8f612c7c38032d
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 PKG_LICENSE:=GPL-2.0-only
index c5ffe3dece9c2e2277ccaeac4edece090d8ad3dc..f45a7f5fa211305deaa2ddcb633c01eb633ee062 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tmate-ssh-server
 PKG_VERSION:=511fd2bd852464e76824279609a34ee93fe148a4
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/tmate-io/tmate-ssh-server/tar.gz/$(PKG_VERSION)?
diff --git a/net/tmate-ssh-server/patches/010-msgpack-c.patch b/net/tmate-ssh-server/patches/010-msgpack-c.patch
new file mode 100644 (file)
index 0000000..f18fcd5
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -193,7 +193,7 @@ fi
+ PKG_CHECK_MODULES(
+   MSGPACK,
+-  msgpack >= 1.2.0,
++  msgpack-c >= 1.2.0,
+   [
+     CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS"
+     LIBS="$MSGPACK_LIBS $LIBS"
index 0ab28a0ba0674f198aa3c0f02302231559863a3b..ee3c0b588d3aa4821c7e292012ed28a109773ab3 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tmate
 PKG_VERSION:=2.4.0
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/tmate-io/tmate/tar.gz/$(PKG_VERSION)?
diff --git a/net/tmate/patches/020-msgpack-c.patch b/net/tmate/patches/020-msgpack-c.patch
new file mode 100644 (file)
index 0000000..5d0cec6
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -201,7 +201,7 @@ fi
+ PKG_CHECK_MODULES(
+   MSGPACK,
+-  msgpack >= 1.1.0,
++  msgpack-c >= 1.1.0,
+   [
+     CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS"
+     LIBS="$MSGPACK_LIBS $LIBS"
index 4626c1b9650c0b26cfceb3c0ac1cdcc54b232403..dc95537c210060ce6faa3017cea530648f234051 100644 (file)
@@ -8,20 +8,20 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=transmission
-PKG_VERSION:=3.00
-PKG_RELEASE:=19
+PKG_VERSION:=4.0.1
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=@GITHUB/transmission/transmission-releases/master
-PKG_HASH:=9144652fe742f7f7dd6657716e378da60b751aaeda8bef8344b3eefc4db255f2
+PKG_SOURCE_URL:=https://github.com/transmission/transmission/releases/download/$(PKG_VERSION)/
+PKG_HASH:=8fc5aef23638c983406f6a3ee9918369e4cdc84e3228bd2fb3d01dd55cdad900
 
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=GPL-2.0-or-later
 PKG_LICENSE_FILES:=COPYING
 PKG_CPE_ID:=cpe:/a:transmissionbt:transmission
 
-PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
+PKG_BUILD_DEPENDS:=libb64 node/host
 PKG_BUILD_PARALLEL:=1
 PKG_CONFIG_DEPENDS:= \
        CONFIG_LIBCURL_GNUTLS \
@@ -31,6 +31,7 @@ PKG_CONFIG_DEPENDS:= \
        CONFIG_LIBCURL_NOSSL
 
 include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
 include $(INCLUDE_DIR)/package-seccomp.mk
 
 define Package/transmission/template
@@ -39,7 +40,10 @@ define Package/transmission/template
   CATEGORY:=Network
   TITLE:=BitTorrent client
   URL:=https://www.transmissionbt.com
-  DEPENDS:=+libcurl +libevent2 +libminiupnpc +libnatpmp +libpthread +librt +zlib +LIBCURL_NOSSL:libmbedtls +LIBCURL_GNUTLS:libmbedtls
+  DEPENDS:=+libatomic +libcurl +libdeflate +libdht +libevent2 \
+          +libevent2-pthreads +libminiupnpc +libnatpmp +libpthread +libpsl \
+          +librt +libutp +zlib +LIBCURL_NOSSL:libmbedtls \
+          +LIBCURL_GNUTLS:libmbedtls
 endef
 
 define Package/transmission-daemon
@@ -87,23 +91,40 @@ define Package/transmission-daemon/conffiles
 /etc/config/transmission
 endef
 
-TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
+TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto -DHAVE_SIZE_T -latomic
 TARGET_LDFLAGS += -Wl,--gc-sections -Wl,--as-needed
 
-CONFIGURE_ARGS += \
-       --enable-cli \
-       --enable-daemon \
-       --enable-external-natpmp \
-       --enable-largefile \
-       --enable-lightweight \
-       --without-gtk \
-       --without-kqueue \
-       --without-systemd-daemon \
-       $(if $(CONFIG_LIBCURL_NOSSL),--with-crypto=polarssl) \
-       $(if $(CONFIG_LIBCURL_GNUTLS),--with-crypto=polarssl) \
-       $(if $(CONFIG_LIBCURL_MBEDTLS),--with-crypto=polarssl) \
-       $(if $(CONFIG_LIBCURL_OPENSSL),--with-crypto=openssl) \
-       $(if $(CONFIG_LIBCURL_WOLFSSL),--with-crypto=cyassl)
+CMAKE_OPTIONS += \
+       -DENABLE_CLI:BOOL=YES \
+       -DENABLE_GTK:BOOL=NO \
+       -DENABLE_QT:BOOL=NO \
+       -DENABLE_MAC:BOOL=NO \
+       -DENABLE_TESTS:BOOL=NO \
+       -DENABLE_NLS:BOOL=NO \
+       -DENABLE_UTP:BOOL=YES \
+       -DRUN_CLANG_TIDY:BOOL=NO \
+       -DUSE_SYSTEM_EVENT2:BOOL=YES \
+       -DUSE_SYSTEM_DEFLATE:BOOL=YES \
+       -DUSE_SYSTEM_DHT:BOOL=YES \
+       -DUSE_SYSTEM_MINIUPNPC:BOOL=YES \
+       -DUSE_SYSTEM_NATPMP:BOOL=YES \
+       -DUSE_SYSTEM_UTP:BOOL=YES \
+       -DUSE_SYSTEM_B64:BOOL=YES \
+       -DUSE_SYSTEM_PSL:BOOL=YES \
+       -DWITH_INOTIFY:BOOL=YES \
+       -DWITH_KQUEUE:BOOL=NO \
+       -DWITH_SYSTEMD:BOOL=NO \
+       -DB64_INCLUDE_DIR=$(STAGING_DIR)/usr/include \
+       -DB64_LIBRARY=$(STAGING_DIR)/usr/lib/libb64.a \
+       -DDHT_INCLUDE_DIR=$(STAGING_DIR)/usr/include \
+       -DDHT_LIBRARY=$(STAGING_DIR)/usr/lib/libdht.so \
+       -DUTP_INCLUDE_DIR=$(STAGING_DIR)/usr/include \
+       -DUTP_LIBRARY=$(STAGING_DIR)/usr/lib/libutp.so \
+       $(if $(CONFIG_LIBCURL_NOSSL),-DWITH_CRYPTO=mbedtls) \
+       $(if $(CONFIG_LIBCURL_GNUTLS),-DWITH_CRYPTO=mbedtls) \
+       $(if $(CONFIG_LIBCURL_MBEDTLS),-DWITH_CRYPTO=mbedtls) \
+       $(if $(CONFIG_LIBCURL_OPENSSL),-DWITH_CRYPTO=openssl) \
+       $(if $(CONFIG_LIBCURL_WOLFSSL),-DWITH_CRYPTO=wolfssl)
 
 define Package/transmission-daemon/install
        $(INSTALL_DIR) $(1)/usr/bin
@@ -133,7 +154,7 @@ endef
 
 define Package/transmission-web/install
        $(INSTALL_DIR) $(1)/usr/share/transmission
-       $(CP) $(PKG_INSTALL_DIR)/usr/share/transmission/web $(1)/usr/share/transmission/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/transmission/public_html $(1)/usr/share/transmission/
 endef
 
 $(eval $(call BuildPackage,transmission-daemon))
index b652d325744b8eaf756f4eed9a79a7be7da7838b..f1fc456ecc7129ff68007285d10be068ab27fd1b 100644 (file)
@@ -17,6 +17,7 @@
                                "epoll_create1",
                                "epoll_ctl",
                                "epoll_pwait",
+                               "eventfd2",
                                "exit",
                                "exit_group",
                                "faccessat",
@@ -87,6 +88,7 @@
                                "sendto",
                                "setsockopt",
                                "shutdown",
+                               "signalfd4",
                                "sigreturn",
                                "socket",
                                "socketpair",
index a6bc00f01bb0bd86fd4db8aed268bc92ad323524..a1673087f000516b8c10166feb0b71b4d14c9e1c 100644 (file)
@@ -170,7 +170,7 @@ transmission() {
        procd_add_jail_mount_rw "$download_dir"
        [ "$incomplete_dir_enabled" = "1" ] && procd_add_jail_mount_rw "$incomplete_dir"
        [ "$watch_dir_enabled" = "1" ] && procd_add_jail_mount_rw "$watch_dir"
-       web_home="${web_home:-/usr/share/transmission/web}"
+       web_home="${web_home:-/usr/share/transmission/public_html}"
        [ -d "$web_home" ] && procd_add_jail_mount "$web_home"
        [ -f "$ca_bundle_file" ] && procd_add_jail_mount "$ca_bundle_file"
        procd_close_instance
diff --git a/net/transmission/patches/001-apply-dscp-to-udp-sockets.patch b/net/transmission/patches/001-apply-dscp-to-udp-sockets.patch
deleted file mode 100644 (file)
index a3fd634..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From 98da2afa58b7bdf5350de16fd99905ddb04e1b0d Mon Sep 17 00:00:00 2001
-From: Dan Walters <dan@walters.io>
-Date: Sun, 13 Oct 2019 10:08:36 -0500
-Subject: [PATCH] Apply the configured peer socket TOS to UDP sockets, not just
- TCP.
-
----
- libtransmission/session.c |  2 ++
- libtransmission/tr-udp.c  | 20 ++++++++++++++++++++
- libtransmission/tr-udp.h  |  1 +
- 3 files changed, 23 insertions(+)
-
---- a/libtransmission/session.c
-+++ b/libtransmission/session.c
-@@ -2274,6 +2274,8 @@ static void toggle_utp(void* data)
-     tr_udpSetSocketBuffers(session);
-+    tr_udpSetSocketTOS(session);
-+
-     /* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an
-        explanation. */
- }
---- a/libtransmission/tr-udp.c
-+++ b/libtransmission/tr-udp.c
-@@ -125,6 +125,24 @@ void tr_udpSetSocketBuffers(tr_session*
-     }
- }
-+void tr_udpSetSocketTOS(tr_session* session)
-+{
-+    if (session->peerSocketTOS == 0)
-+    {
-+        return;
-+    }
-+
-+    if (session->udp_socket != TR_BAD_SOCKET)
-+    {
-+        tr_netSetTOS(session->udp_socket, session->peerSocketTOS, TR_AF_INET);
-+    }
-+
-+    if (session->udp6_socket != TR_BAD_SOCKET)
-+    {
-+        tr_netSetTOS(session->udp6_socket, session->peerSocketTOS, TR_AF_INET6);
-+    }
-+}
-+
- /* BEP-32 has a rather nice explanation of why we need to bind to one
-    IPv6 address, if I may say so myself. */
-@@ -363,6 +381,8 @@ ipv6:
-     tr_udpSetSocketBuffers(ss);
-+    tr_udpSetSocketTOS(ss);
-+
-     if (ss->isDHTEnabled)
-     {
-         tr_dhtInit(ss);
---- a/libtransmission/tr-udp.h
-+++ b/libtransmission/tr-udp.h
-@@ -30,5 +30,6 @@ THE SOFTWARE.
- void tr_udpInit(tr_session*);
- void tr_udpUninit(tr_session*);
- void tr_udpSetSocketBuffers(tr_session*);
-+void tr_udpSetSocketTOS(tr_session*);
- bool tau_handle_message(tr_session* session, uint8_t const* msg, size_t msglen);
diff --git a/net/transmission/patches/010-no-intltool.patch b/net/transmission/patches/010-no-intltool.patch
deleted file mode 100644 (file)
index ba59092..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -555,9 +555,6 @@ dnl it should be safe to re-edit 0.40 ba
- use_nls=no
- if test "x$enable_nls" = "xyes" ; then
-     use_nls=yes
--    m4_ifdef([IT_PROG_INTLTOOL],
--             [IT_PROG_INTLTOOL([0.35.0],[no-xml])],
--             [AC_MSG_ERROR("--enable-nls requires intltool to be installed.")])
-     AC_CHECK_HEADERS([libintl.h])
-     GETTEXT_PACKAGE=transmission-gtk
-     AC_SUBST(GETTEXT_PACKAGE)
diff --git a/net/transmission/patches/020-mbedcrypto.patch b/net/transmission/patches/020-mbedcrypto.patch
deleted file mode 100644 (file)
index 18c33f5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -152,8 +152,8 @@ AS_IF([test "x$want_crypto" = "xauto" -o
-     )
- ])
- AS_IF([test "x$want_crypto" = "xauto" -o "x$want_crypto" = "xpolarssl"], [
--    PKG_CHECK_MODULES(MBEDTLS, [mbedtls >= $POLARSSL_MINIMUM],
--        [want_crypto="polarssl"; CRYPTO_PKG="polarssl"; CRYPTO_CFLAGS="$MBEDTLS_CFLAGS"; CRYPTO_LIBS="$MBEDTLS_LIBS"; POLARSSL_IS_MBEDTLS=yes],
-+    AC_CHECK_LIB(mbedcrypto, mbedtls_strerror,
-+        [want_crypto="polarssl"; CRYPTO_PKG="polarssl"; CRYPTO_LIBS="-lmbedcrypto"; POLARSSL_IS_MBEDTLS=yes],
-         [AC_CHECK_HEADER([polarssl/version.h],
-             [AC_EGREP_CPP([version_ok], [#include <polarssl/version.h>
-                                          #if defined (POLARSSL_VERSION_NUMBER) && POLARSSL_VERSION_NUMBER >= $POLARSSL_MINIMUM
diff --git a/net/transmission/patches/030-wolfssl.patch b/net/transmission/patches/030-wolfssl.patch
deleted file mode 100644 (file)
index 53e1393..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-From 82b5d4028885d75adba9b66d43aeb11592e64914 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Wed, 13 Oct 2021 18:16:55 -0700
-Subject: [PATCH] fix runtime with wolfSSL and fastmath
-
-wolfSSL's fastmath support requires options.h to be included before
-anything else. Otherwise bad codepaths get taken and a crash occurs
-during DH initialization.
-
-Signed-off-by: Rosen Penev <rosenp@gmail.com>
----
- libtransmission/crypto-utils-cyassl.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/libtransmission/crypto-utils-cyassl.c
-+++ b/libtransmission/crypto-utils-cyassl.c
-@@ -19,6 +19,7 @@
- #define API_VERSION_HEX LIBCYASSL_VERSION_HEX
- #endif
-+#include API_HEADER(options.h)
- #include API_HEADER_CRYPT(arc4.h)
- #include API_HEADER_CRYPT(dh.h)
- #include API_HEADER_CRYPT(error-crypt.h)
diff --git a/net/transmission/patches/080-disable-webseeding.patch b/net/transmission/patches/080-disable-webseeding.patch
deleted file mode 100644 (file)
index f63d78d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/libtransmission/webseed.c
-+++ b/libtransmission/webseed.c
-@@ -510,8 +510,6 @@ static void webseed_timer_func(evutil_so
-         ++w->retry_tickcount;
-     }
--    on_idle(w);
--
-     tr_timerAddMsec(w->timer, TR_IDLE_TIMER_MSEC);
- }
index f3854fb809ffeaef5e1dacd44bd8f985bd166140..8f120d944147a9c6ca451ac43857019c3588b375 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=udp-broadcast-relay-redux
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=2
 PKG_LICENSE:=GPL-2.0
 
 PKG_SOURCE_PROTO:=git
index aa35f554622874e09a61166374f596aa426a3239..6694215885ee46f4fa646feec8b0278b1384de6f 100644 (file)
@@ -58,7 +58,7 @@ udp_broadcast_relay_redux_instance() {
         procd_append_param command "-t" "$dest_override"
     fi
 
-    procd_add_jail ubr-${PIDCOUNT}
+    procd_add_jail ubr-${PIDCOUNT} cgroupsns
     procd_close_instance
 }
 
index 18b81d15c00b0d2c345af04f6fd8bf1af67559b2..3787374c457760a47ef63ac3fd60a0a03a65ee86 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=v2rayA
 PKG_VERSION:=1.5.9.1698.1
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
@@ -37,13 +37,7 @@ define Package/v2raya
   SUBMENU:=Web Servers/Proxies
   DEPENDS:=$(GO_ARCH_DEPENDS) \
     +ca-bundle \
-    +iptables \
-    +IPV6:ip6tables \
-    +iptables-mod-conntrack-extra \
-    +iptables-mod-extra \
-    +iptables-mod-filter \
-    +iptables-mod-tproxy \
-    +kmod-ipt-nat6 \
+    +kmod-nft-tproxy \
     +xray-core
   URL:=https://v2raya.org
 endef
index d9ff36581afd00efffb29da1dbd080bb98a47b09..131131cf81a88e1e312f361ea5f747ab914ebb19 100644 (file)
@@ -10,7 +10,11 @@ config v2raya 'config'
 
        # Make sure your IPv6 network works fine before you turn it on.
        # Optional values: auto, on, off.
-       option ipv6_support 'auto'
+       option ipv6_support 'on'
+
+       # Experimental feature. Make sure you have installed nftables.
+       # Optional values: auto, on, off.
+       option nftables_support 'on'
 
        # Optional values: trace, debug, info, warn or error
        option log_level 'info'
index 4120e90ffd0d133dd8d3591da8a0a6f1cb638f96..2b77fa5dcdcdba7ee55b6b1dfa29c9226f58baf3 100755 (executable)
@@ -42,7 +42,8 @@ start_service() {
 
        append_env_arg "config" "address" "0.0.0.0:2017"
        append_env_arg "config" "config" "/etc/v2raya"
-       append_env_arg "config" "ipv6_support" "auto"
+       append_env_arg "config" "ipv6_support" "on"
+       append_env_arg "config" "nftables_support" "on"
        append_env_arg "config" "log_level" "info"
        append_env_arg "config" "log_file" "/var/log/v2raya/v2raya.log"
        append_env_arg "config" "log_max_days" "3"
diff --git a/net/v2raya/patches/019-fix-simple-obfs.patch b/net/v2raya/patches/019-fix-simple-obfs.patch
new file mode 100644 (file)
index 0000000..e76b49c
--- /dev/null
@@ -0,0 +1,88 @@
+From 58a6cf270e43ec3eaeef7d1c65de76278dd6d349 Mon Sep 17 00:00:00 2001
+From: mzz2017 <2017@duck.com>
+Date: Mon, 13 Feb 2023 14:42:07 +0800
+Subject: [PATCH] fix: simple-obfs
+
+---
+ service/pkg/plugin/simpleobfs/http.go | 8 +++++++-
+ service/pkg/plugin/simpleobfs/tls.go  | 7 +++++++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+--- a/pkg/plugin/simpleobfs/http.go
++++ b/pkg/plugin/simpleobfs/http.go
+@@ -12,6 +12,7 @@ import (
+       "net"
+       "net/http"
+       "strings"
++      "sync"
+ )
+ // HTTPObfs is shadowsocks http simple-obfs implementation
+@@ -24,9 +25,13 @@ type HTTPObfs struct {
+       offset        int
+       firstRequest  bool
+       firstResponse bool
++      rMu           sync.Mutex
++      wMu           sync.Mutex
+ }
+ func (ho *HTTPObfs) Read(b []byte) (int, error) {
++      ho.rMu.Lock()
++      defer ho.rMu.Unlock()
+       if ho.buf != nil {
+               n := copy(b, ho.buf[ho.offset:])
+               ho.offset += n
+@@ -64,6 +69,8 @@ func (ho *HTTPObfs) Read(b []byte) (int,
+ }
+ func (ho *HTTPObfs) Write(b []byte) (int, error) {
++      ho.wMu.Lock()
++      defer ho.wMu.Unlock()
+       if ho.firstRequest {
+               randBytes := make([]byte, 16)
+               rand.Read(randBytes)
+@@ -71,7 +78,6 @@ func (ho *HTTPObfs) Write(b []byte) (int
+               req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%54, rand.Int()%2))
+               req.Header.Set("Upgrade", "websocket")
+               req.Header.Set("Connection", "Upgrade")
+-              req.Host = ho.host
+               if ho.port != "80" {
+                       req.Host = fmt.Sprintf("%s:%s", ho.host, ho.port)
+               }
+--- a/pkg/plugin/simpleobfs/tls.go
++++ b/pkg/plugin/simpleobfs/tls.go
+@@ -8,6 +8,7 @@ import (
+       "io"
+       "math/rand"
+       "net"
++      "sync"
+       "time"
+ )
+@@ -26,6 +27,8 @@ type TLSObfs struct {
+       remain        int
+       firstRequest  bool
+       firstResponse bool
++      rMu           sync.Mutex
++      wMu           sync.Mutex
+ }
+ func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
+@@ -54,6 +57,8 @@ func (to *TLSObfs) read(b []byte, discar
+ }
+ func (to *TLSObfs) Read(b []byte) (int, error) {
++      to.rMu.Lock()
++      defer to.rMu.Unlock()
+       if to.remain > 0 {
+               length := to.remain
+               if length > len(b) {
+@@ -77,6 +82,8 @@ func (to *TLSObfs) Read(b []byte) (int,
+       return to.read(b, 3)
+ }
+ func (to *TLSObfs) Write(b []byte) (int, error) {
++      to.wMu.Lock()
++      defer to.wMu.Unlock()
+       length := len(b)
+       for i := 0; i < length; i += chunkSize {
+               end := i + chunkSize
diff --git a/net/v2raya/patches/020-feat-add-nftables-support.patch b/net/v2raya/patches/020-feat-add-nftables-support.patch
new file mode 100644 (file)
index 0000000..50ef49b
--- /dev/null
@@ -0,0 +1,624 @@
+From d10cf52839e848870df0ea852d9a818ac03e7aa3 Mon Sep 17 00:00:00 2001
+From: cubercsl <2014cais01@gmail.com>
+Date: Thu, 19 Jan 2023 16:43:30 +0800
+Subject: [PATCH 1/5] feat: add nftables support
+
+fix: use iptables-nft if nftables-support is on
+fix: save nft to V2RAYA_CONFIG
+fix: tproxy for ipv6
+chore: small change in table format
+---
+ service/conf/environmentConfig.go     |   1 +
+ service/core/iptables/dropSpoofing.go |   4 +-
+ service/core/iptables/iptables.go     |   7 +-
+ service/core/iptables/redirect.go     | 142 +++++++++++++++++--
+ service/core/iptables/tproxy.go       | 195 +++++++++++++++++++++++++-
+ service/core/iptables/utils.go        |  23 ++-
+ service/core/iptables/watcher.go      |   1 +
+ service/core/v2ray/asset/asset.go     |  17 ++-
+ service/core/v2ray/transparent.go     |   9 +-
+ 9 files changed, 367 insertions(+), 32 deletions(-)
+
+--- a/conf/environmentConfig.go
++++ b/conf/environmentConfig.go
+@@ -24,6 +24,7 @@ type Params struct {
+       WebDir                  string   `id:"webdir" desc:"v2rayA web files directory. use embedded files if not specify."`
+       VlessGrpcInboundCertKey []string `id:"vless-grpc-inbound-cert-key" desc:"Specify the certification path instead of automatically generating a self-signed certificate. Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key"`
+       IPV6Support             string   `id:"ipv6-support" default:"auto" desc:"Optional values: auto, on, off. Make sure your IPv6 network works fine before you turn it on."`
++      NFTablesSupport         string   `id:"nftables-support" default:"off" desc:"Optional values: auto, on, off. Experimental feature. Make sure you have installed nftables."`
+       PassCheckRoot           bool     `desc:"Skip privilege checking. Use it only when you cannot start v2raya but confirm you have root privilege"`
+       ResetPassword           bool     `id:"reset-password"`
+       LogLevel                string   `id:"log-level" default:"info" desc:"Optional values: trace, debug, info, warn or error"`
+--- a/core/iptables/dropSpoofing.go
++++ b/core/iptables/dropSpoofing.go
+@@ -34,7 +34,7 @@ ip6tables -w 2 -I FORWARD -j DROP_SPOOFI
+ `
+       }
+       return Setter{
+-              Cmds:      commands,
++              Cmds: commands,
+       }
+ }
+@@ -54,6 +54,6 @@ ip6tables -w 2 -X DROP_SPOOFING
+ `
+       }
+       return Setter{
+-              Cmds:      commands,
++              Cmds: commands,
+       }
+ }
+--- a/core/iptables/iptables.go
++++ b/core/iptables/iptables.go
+@@ -1,11 +1,12 @@
+ package iptables
+ import (
+-      "github.com/v2rayA/v2rayA/common"
+-      "github.com/v2rayA/v2rayA/common/cmds"
+       "strings"
+       "sync"
+       "time"
++
++      "github.com/v2rayA/v2rayA/common"
++      "github.com/v2rayA/v2rayA/common/cmds"
+ )
+ // http://briteming.hatenablog.com/entry/2019/06/18/175518
+@@ -56,6 +57,10 @@ func (c Setter) Run(stopAtError bool) er
+       if common.IsDocker() {
+               commands = strings.ReplaceAll(commands, "iptables", "iptables-legacy")
+               commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-legacy")
++      } else if (!cmds.IsCommandValid("iptables") || IsNFTablesSupported()) &&
++              cmds.IsCommandValid("iptables-nft") {
++              commands = strings.ReplaceAll(commands, "iptables", "iptables-nft")
++              commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-nft")
+       }
+       var errs []error
+       if c.PreFunc != nil {
+--- a/core/iptables/redirect.go
++++ b/core/iptables/redirect.go
+@@ -2,15 +2,34 @@ package iptables
+ import (
+       "fmt"
+-      "github.com/v2rayA/v2rayA/common/cmds"
++      "os"
+       "strings"
++
++      "github.com/v2rayA/v2rayA/common/cmds"
++      "github.com/v2rayA/v2rayA/core/v2ray/asset"
+ )
+-type redirect struct{}
++type redirect interface {
++      AddIPWhitelist(cidr string)
++      RemoveIPWhitelist(cidr string)
++      GetSetupCommands() Setter
++      GetCleanCommands() Setter
++}
++
++type legacyRedirect struct{}
++type nftRedirect struct{}
+ var Redirect redirect
+-func (r *redirect) AddIPWhitelist(cidr string) {
++func init() {
++      if IsNFTablesSupported() {
++              Redirect = &nftRedirect{}
++      } else {
++              Redirect = &legacyRedirect{}
++      }
++}
++
++func (r *legacyRedirect) AddIPWhitelist(cidr string) {
+       // avoid duplication
+       r.RemoveIPWhitelist(cidr)
+       var commands string
+@@ -22,13 +41,13 @@ func (r *redirect) AddIPWhitelist(cidr s
+       cmds.ExecCommands(commands, false)
+ }
+-func (r *redirect) RemoveIPWhitelist(cidr string) {
++func (r *legacyRedirect) RemoveIPWhitelist(cidr string) {
+       var commands string
+       commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr)
+       cmds.ExecCommands(commands, false)
+ }
+-func (r *redirect) GetSetupCommands() Setter {
++func (r *legacyRedirect) GetSetupCommands() Setter {
+       commands := `
+ iptables -w 2 -t nat -N TP_OUT
+ iptables -w 2 -t nat -N TP_PRE
+@@ -84,11 +103,11 @@ ip6tables -w 2 -t nat -A TP_OUT -j TP_RU
+ `
+       }
+       return Setter{
+-              Cmds:      commands,
++              Cmds: commands,
+       }
+ }
+-func (r *redirect) GetCleanCommands() Setter {
++func (r *legacyRedirect) GetCleanCommands() Setter {
+       commands := `
+ iptables -w 2 -t nat -F TP_OUT
+ iptables -w 2 -t nat -D OUTPUT -p tcp -j TP_OUT
+@@ -112,6 +131,113 @@ ip6tables -w 2 -t nat -X TP_RULE
+ `
+       }
+       return Setter{
+-              Cmds:      commands,
++              Cmds: commands,
++      }
++}
++
++func (t *nftRedirect) AddIPWhitelist(cidr string) {
++      command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr)
++      if !strings.Contains(cidr, ".") {
++              command = strings.Replace(command, "interface", "interface6", 1)
++      }
++      cmds.ExecCommands(command, false)
++}
++
++func (t *nftRedirect) RemoveIPWhitelist(cidr string) {
++      command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr)
++      if !strings.Contains(cidr, ".") {
++              command = strings.Replace(command, "interface", "interface6", 1)
+       }
++      cmds.ExecCommands(command, false)
++}
++
++func (r *nftRedirect) GetSetupCommands() Setter {
++      // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns
++      table := `
++table inet v2raya {
++    set whitelist {
++        type ipv4_addr
++        flags interval
++        auto-merge
++        elements = {
++            0.0.0.0/32,
++            10.0.0.0/8,
++            100.64.0.0/10,
++            127.0.0.0/8,
++            169.254.0.0/16,
++            172.16.0.0/12,
++            192.0.0.0/24,
++            192.0.2.0/24,
++            192.88.99.0/24,
++            192.168.0.0/16,
++            198.51.100.0/24,
++            203.0.113.0/24,
++            224.0.0.0/4,
++            240.0.0.0/4
++        }
++    }
++
++    set whitelist6 {
++        type ipv6_addr
++        flags interval
++        auto-merge
++        elements = {
++            ::/128,
++            ::1/128,
++            64:ff9b::/96,
++            100::/64,
++            2001::/32,
++            2001:20::/28,
++            fe80::/10,
++            ff00::/8
++        }
++    }
++
++    set interface {
++        type ipv4_addr
++        flags interval
++        auto-merge
++    }
++
++    set interface6 {
++        type ipv6_addr
++        flags interval
++        auto-merge
++    }
++
++    chain tp_rule {
++        ip daddr @whitelist return
++        ip daddr @interface return
++        ip6 daddr @whitelist6 return
++        ip6 daddr @interface6 return
++        meta mark & 0x80 == 0x80 return
++        meta l4proto tcp redirect to :32345
++    }
++
++    chain tp_pre {
++        type nat hook prerouting priority dstnat - 5
++        meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule
++    }
++
++    chain tp_out {
++        type nat hook output priority -105
++        meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule
++    }
++}
++`
++      if !IsIPv6Supported() {
++              table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4")
++      }
++
++      nftablesConf := asset.GetNFTablesConfigPath()
++      os.WriteFile(nftablesConf, []byte(table), 0644)
++
++      command := `nft -f ` + nftablesConf
++
++      return Setter{Cmds: command}
++}
++
++func (r *nftRedirect) GetCleanCommands() Setter {
++      command := `nft delete table inet v2raya`
++      return Setter{Cmds: command}
+ }
+--- a/core/iptables/tproxy.go
++++ b/core/iptables/tproxy.go
+@@ -2,18 +2,36 @@ package iptables
+ import (
+       "fmt"
++      "os"
++      "strings"
++
+       "github.com/v2rayA/v2rayA/common/cmds"
++      "github.com/v2rayA/v2rayA/core/v2ray/asset"
+       "github.com/v2rayA/v2rayA/db/configure"
+-      "strings"
+ )
+-type tproxy struct {
+-      watcher *LocalIPWatcher
++type tproxy interface {
++      AddIPWhitelist(cidr string)
++      RemoveIPWhitelist(cidr string)
++      GetSetupCommands() Setter
++      GetCleanCommands() Setter
+ }
++type legacyTproxy struct{}
++
++type nftTproxy struct{}
++
+ var Tproxy tproxy
+-func (t *tproxy) AddIPWhitelist(cidr string) {
++func init() {
++      if IsNFTablesSupported() {
++              Tproxy = &nftTproxy{}
++      } else {
++              Tproxy = &legacyTproxy{}
++      }
++}
++
++func (t *legacyTproxy) AddIPWhitelist(cidr string) {
+       // avoid duplication
+       t.RemoveIPWhitelist(cidr)
+       pos := 7
+@@ -30,7 +48,7 @@ func (t *tproxy) AddIPWhitelist(cidr str
+       cmds.ExecCommands(commands, false)
+ }
+-func (t *tproxy) RemoveIPWhitelist(cidr string) {
++func (t *legacyTproxy) RemoveIPWhitelist(cidr string) {
+       var commands string
+       commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr)
+       if !strings.Contains(cidr, ".") {
+@@ -40,7 +58,7 @@ func (t *tproxy) RemoveIPWhitelist(cidr
+       cmds.ExecCommands(commands, false)
+ }
+-func (t *tproxy) GetSetupCommands() Setter {
++func (t *legacyTproxy) GetSetupCommands() Setter {
+       commands := `
+ ip rule add fwmark 0x40/0xc0 table 100
+ ip route add local 0.0.0.0/0 dev lo table 100
+@@ -158,7 +176,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C
+       }
+ }
+-func (t *tproxy) GetCleanCommands() Setter {
++func (t *legacyTproxy) GetCleanCommands() Setter {
+       commands := `
+ ip rule del fwmark 0x40/0xc0 table 100 
+ ip route del local 0.0.0.0/0 dev lo table 100
+@@ -195,3 +213,166 @@ ip6tables -w 2 -t mangle -X TP_MARK
+               Cmds:      commands,
+       }
+ }
++
++func (t *nftTproxy) AddIPWhitelist(cidr string) {
++      command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr)
++      if !strings.Contains(cidr, ".") {
++              command = strings.Replace(command, "interface", "interface6", 1)
++      }
++      cmds.ExecCommands(command, false)
++}
++
++func (t *nftTproxy) RemoveIPWhitelist(cidr string) {
++      command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr)
++      if !strings.Contains(cidr, ".") {
++              command = strings.Replace(command, "interface", "interface6", 1)
++      }
++      cmds.ExecCommands(command, false)
++}
++
++func (t *nftTproxy) GetSetupCommands() Setter {
++      // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns
++      table := `
++table inet v2raya {
++    set whitelist {
++        type ipv4_addr
++        flags interval
++        auto-merge
++        elements = {
++            0.0.0.0/32,
++            10.0.0.0/8,
++            100.64.0.0/10,
++            127.0.0.0/8,
++            169.254.0.0/16,
++            172.16.0.0/12,
++            192.0.0.0/24,
++            192.0.2.0/24,
++            192.88.99.0/24,
++            192.168.0.0/16,
++            198.51.100.0/24,
++            203.0.113.0/24,
++            224.0.0.0/4,
++            240.0.0.0/4
++        }
++    }
++
++    set whitelist6 {
++        type ipv6_addr
++        flags interval
++        auto-merge
++        elements = {
++            ::/128,
++            ::1/128,
++            64:ff9b::/96,
++            100::/64,
++            2001::/32,
++            2001:20::/28,
++            fe80::/10,
++            ff00::/8
++        }
++    }
++
++    set interface {
++        type ipv4_addr
++        flags interval
++        auto-merge
++    }
++
++    set interface6 {
++        type ipv6_addr
++        flags interval
++        auto-merge
++    }
++
++    chain tp_out {
++        meta mark & 0x80 == 0x80 return
++        meta l4proto { tcp, udp } fib saddr type local fib daddr type != local jump tp_rule
++    }
++
++    chain tp_pre {
++        iifname "lo" mark & 0xc0 != 0x40 return
++        meta l4proto { tcp, udp } fib saddr type != local fib daddr type != local jump tp_rule
++        meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip to 127.0.0.1:32345
++        meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip6 to [::1]:32345
++    }
++
++    chain output {
++        type route hook output priority mangle - 5; policy accept;
++        meta nfproto { ipv4, ipv6 } jump tp_out
++    }
++
++    chain prerouting {
++        type filter hook prerouting priority mangle - 5; policy accept;
++        meta nfproto { ipv4, ipv6 } jump tp_pre
++    }
++
++    chain tp_rule {
++        meta mark set ct mark
++        meta mark & 0xc0 == 0x40 return
++        iifname "docker*" return
++        iifname "veth*" return
++        iifname "wg*" return
++        iifname "ppp*" return
++        # anti-pollution
++        ip daddr @interface return
++        ip daddr @whitelist return
++        ip6 daddr @interface6 return
++        ip6 daddr @whitelist6 return
++        jump tp_mark
++    }
++
++    chain tp_mark {
++        tcp flags & (fin | syn | rst | ack) == syn meta mark set mark | 0x40
++        meta l4proto udp ct state new meta mark set mark | 0x40
++        ct mark set mark
++    }
++}
++`
++      if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed {
++              table = strings.ReplaceAll(table, "# anti-pollution", `
++        meta l4proto { tcp, udp } th dport 53 jump tp_mark
++        meta mark & 0xc0 == 0x40 return
++              `)
++      }
++
++      if !IsIPv6Supported() {
++              // drop ipv6 packets hooks
++              table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4")
++      }
++
++      nftablesConf := asset.GetNFTablesConfigPath()
++      os.WriteFile(nftablesConf, []byte(table), 0644)
++
++      command := `
++ip rule add fwmark 0x40/0xc0 table 100
++ip route add local 0.0.0.0/0 dev lo table 100
++`
++      if IsIPv6Supported() {
++              command += `
++ip -6 rule add fwmark 0x40/0xc0 table 100
++ip -6 route add local ::/0 dev lo table 100
++`
++      }
++
++      command += `nft -f ` + nftablesConf
++      return Setter{Cmds: command}
++}
++
++func (t *nftTproxy) GetCleanCommands() Setter {
++      command := `
++ip rule del fwmark 0x40/0xc0 table 100
++ip route del local 0.0.0.0/0 dev lo table 100
++`
++      if IsIPv6Supported() {
++              command += `
++ip -6 rule del fwmark 0x40/0xc0 table 100
++ip -6 route del local ::/0 dev lo table 100
++              `
++      }
++
++      command += `nft delete table inet v2raya`
++      if !IsIPv6Supported() {
++              command = strings.Replace(command, "inet", "ip", 1)
++      }
++      return Setter{Cmds: command}
++}
+--- a/core/iptables/utils.go
++++ b/core/iptables/utils.go
+@@ -1,12 +1,13 @@
+ package iptables
+ import (
++      "net"
++      "strconv"
++
+       "github.com/v2rayA/v2rayA/common"
+       "github.com/v2rayA/v2rayA/common/cmds"
+       "github.com/v2rayA/v2rayA/conf"
+       "golang.org/x/net/nettest"
+-      "net"
+-      "strconv"
+ )
+ func IPNet2CIDR(ipnet *net.IPNet) string {
+@@ -44,3 +45,21 @@ func IsIPv6Supported() bool {
+       }
+       return cmds.IsCommandValid("ip6tables")
+ }
++
++func IsNFTablesSupported() bool {
++
++      switch conf.GetEnvironmentConfig().NFTablesSupport {
++      // Warning:
++      // This is an experimental feature for nftables support.
++      // The default value is "off" for now but may be changed to "auto" in the future
++      case "on":
++              return true
++      case "off":
++              return false
++      default:
++      }
++      if common.IsDocker() {
++              return false
++      }
++      return cmds.IsCommandValid("nft")
++}
+--- a/core/iptables/watcher.go
++++ b/core/iptables/watcher.go
+@@ -10,6 +10,7 @@ type LocalIPWatcher struct {
+       cidrPool    map[string]struct{}
+       AddedFunc   func(cidr string)
+       RemovedFunc func(cidr string)
++      UpdateFunc  func(cidrs []string)
+ }
+ func NewLocalIPWatcher(interval time.Duration, AddedFunc func(cidr string), RemovedFunc func(cidr string)) *LocalIPWatcher {
+--- a/core/v2ray/asset/asset.go
++++ b/core/v2ray/asset/asset.go
+@@ -3,12 +3,6 @@ package asset
+ import (
+       "errors"
+       "fmt"
+-      "github.com/adrg/xdg"
+-      "github.com/muhammadmuzzammil1998/jsonc"
+-      "github.com/v2rayA/v2rayA/common/files"
+-      "github.com/v2rayA/v2rayA/conf"
+-      "github.com/v2rayA/v2rayA/core/v2ray/where"
+-      "github.com/v2rayA/v2rayA/pkg/util/log"
+       "io"
+       "io/fs"
+       "net/http"
+@@ -17,6 +11,13 @@ import (
+       "path/filepath"
+       "runtime"
+       "time"
++
++      "github.com/adrg/xdg"
++      "github.com/muhammadmuzzammil1998/jsonc"
++      "github.com/v2rayA/v2rayA/common/files"
++      "github.com/v2rayA/v2rayA/conf"
++      "github.com/v2rayA/v2rayA/core/v2ray/where"
++      "github.com/v2rayA/v2rayA/pkg/util/log"
+ )
+ func GetV2rayLocationAssetOverride() string {
+@@ -140,6 +141,10 @@ func GetV2rayConfigDirPath() (p string)
+       return conf.GetEnvironmentConfig().V2rayConfigDirectory
+ }
++func GetNFTablesConfigPath() (p string) {
++      return path.Join(conf.GetEnvironmentConfig().Config, "v2raya.nft")
++}
++
+ func Download(url string, to string) (err error) {
+       log.Info("Downloading %v to %v", url, to)
+       c := http.Client{Timeout: 90 * time.Second}
+--- a/core/v2ray/transparent.go
++++ b/core/v2ray/transparent.go
+@@ -2,13 +2,14 @@ package v2ray
+ import (
+       "fmt"
++      "strings"
++      "time"
++
+       "github.com/v2rayA/v2rayA/conf"
+       "github.com/v2rayA/v2rayA/core/iptables"
+       "github.com/v2rayA/v2rayA/core/specialMode"
+       "github.com/v2rayA/v2rayA/db/configure"
+       "github.com/v2rayA/v2rayA/pkg/util/log"
+-      "strings"
+-      "time"
+ )
+ func deleteTransparentProxyRules() {
+@@ -45,12 +46,12 @@ func writeTransparentProxyRules() (err e
+                       }
+                       return fmt.Errorf("not support \"tproxy\" mode of transparent proxy: %w", err)
+               }
+-              iptables.SetWatcher(&iptables.Tproxy)
++              iptables.SetWatcher(iptables.Tproxy)
+       case configure.TransparentRedirect:
+               if err = iptables.Redirect.GetSetupCommands().Run(true); err != nil {
+                       return fmt.Errorf("not support \"redirect\" mode of transparent proxy: %w", err)
+               }
+-              iptables.SetWatcher(&iptables.Redirect)
++              iptables.SetWatcher(iptables.Redirect)
+       case configure.TransparentSystemProxy:
+               if err = iptables.SystemProxy.GetSetupCommands().Run(true); err != nil {
+                       return fmt.Errorf("not support \"system proxy\" mode of transparent proxy: %w", err)
index c78c97554cd1df2b1ca9870a56e7e2a3cf404001..48a149a485b0ee4285a33044d13f002aedfaf398 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=conmon
-PKG_VERSION:=2.1.6
+PKG_VERSION:=2.1.7
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/containers/$(PKG_NAME)/archive/v$(PKG_VERSION)
-PKG_HASH:=340453f7aac43e6a1f9a5efe31f24471f8a7a997a849ad6d1ff3fb530a9e2874
+PKG_HASH:=7d0f9a2f7cb8a76c51990128ac837aaf0cc89950b6ef9972e94417aa9cf901fe
 
 PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
 PKG_LICENSE:=Apache-2.0
index 0a3113c4720a49d720aa4dba2fc8d0615c14b642..dc7c13eebded72115c0c20e4d5399050a77e243d 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=coremark
-PKG_SOURCE_DATE:=2022-07-27
-PKG_SOURCE_VERSION:=eefc986ebd3452d6adde22eafaff3e5c859f29e4
+PKG_SOURCE_DATE:=2023-01-25
+PKG_SOURCE_VERSION:=d5fad6bd094899101a4e5fd53af7298160ced6ab
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/eembc/coremark/tar.gz/$(PKG_SOURCE_VERSION)?
-PKG_HASH:=a5964bf215786d65d08941b6f9a9a4f4e50524f5391fa3826db2994c47d5e7f3
+PKG_HASH:=76f3b98fc940d277521023dc6e106551ef4a2180fa4c3da8cd5bf933aa494ef2
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
 
 PKG_MAINTAINER:=Lim Guo Wei <limguowei@gmail.com> \
index 644bd25f8dd21da586a49fdf4d9e09f7360ae711..8bd5e00800057f061cf027738ef693657ac8e9db 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=lolcat
-PKG_VERSION:=1.2
+PKG_VERSION:=1.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/jaseg/lolcat/tar.gz/refs/tags/v$(PKG_VERSION)?
-PKG_HASH:=b6e1a0e24479fbdd4eb907531339e2cafc0c00b78d19caf70e8377b8b7546331
+PKG_HASH:=6ea43ee2b2bb2f15fc91812b72ebcdaa883052853ed8f055b6f8b38637bda909
 
 PKG_MAINTAINER:=Rui Salvaterra <rsalvaterra@gmail.com>
 PKG_LICENSE:=WTFPL
index 52bcea5abc5f1aba5a19ca49b19e1aa1792bca73..f3042be77d6c93209430cc0883d26b2f07a09152 100644 (file)
@@ -12,9 +12,9 @@ PKG_FIXUP:=autoreconf
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/lunn/mv88e6xxx_dump
-PKG_MIRROR_HASH:=2f1bce89212a10be89e106398ccc2f7eedcc1a7299bf8a1a05b3baf061f779f5
-PKG_SOURCE_DATE:=2022.03.29
-PKG_SOURCE_VERSION:=a3f713f99e0004d17d9282e0cb253505b9ca35b6
+PKG_MIRROR_HASH:=cee56d21347496ca38a15d7572dbd2b0db32dfbfbb19a8ce679b9095f7b5a247
+PKG_SOURCE_DATE:=2023.03.08
+PKG_SOURCE_VERSION:=b4c5247ee8bb5512fb80081503aae183b35ed3c6
 
 PKG_MAINTAINER:=Etienne Champetier <champetier.etienne@gmail.com>
 PKG_LICENSE:=GPL-2.0-only
diff --git a/utils/ripgrep/Makefile b/utils/ripgrep/Makefile
new file mode 100644 (file)
index 0000000..fe449bc
--- /dev/null
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato and Donald Hoskins
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ripgrep
+PKG_VERSION:=13.0.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/BurntSushi/ripgrep/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=0fb17aaf285b3eee8ddab17b833af1e190d73de317ff9648751ab0660d763ed2
+
+PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
+PKG_LICENSE:=MIT Unlicense
+PKG_LICENSE_FILES:=LICENSE-MIT UNLICENSE
+
+PKG_BUILD_DEPENDS:=rust/host
+
+include ../../lang/rust/rust-package.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Build/Compile
+       $(call Build/Compile/Cargo,, --features 'pcre2')
+endef
+
+define Package/ripgrep
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=ripgrep (rg) regex grep
+  DEPENDS:=$(RUST_ARCH_DEPENDS) +libpcre2
+  URL:=https://github.com/BurntSushi/ripgrep
+endef
+
+define Package/ripgrep/description
+  ripgrep (rg) recursively searches directories for a regex pattern
+  while respecting your gitignore
+endef
+
+define Package/ripgrep/install
+       $(INSTALL_DIR) $(1)/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/target/$(RUSTC_TARGET_ARCH)/stripped/rg $(1)/bin/rg
+endef
+
+$(eval $(call BuildPackage,ripgrep))