From 33a0900b61a62fa2ac6d6dd27c3a86a4d26d1f98 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Thu, 20 Jul 2023 08:35:03 +0900
Subject: [PATCH] ksmbd-tools: add a crossmnt parameter in smb.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch add a new 'crossmnt' parameter in smb.conf to allow path
lookup to cross a mountpoint to the root of a different filesystem.
e.g. if there is sda1 directory in ksmbd share and sda1 directory is
mounted as external devices(e.g. usb), currently files in sda1 is not
visiable from client. User can control path lookup for cross mount
points using this parameter.

Acked-by: Atte Heikkilä <atteh.mailbox@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 include/linux/ksmbd_server.h | 3 ++-
 include/management/share.h   | 1 +
 ksmbd.conf.5.in              | 5 +++++
 ksmbd.conf.example           | 1 +
 lib/management/share.c     | 9 +++++++++
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/include/linux/ksmbd_server.h b/include/linux/ksmbd_server.h
index 64099f263d1b..22224145b4c7 100644
--- a/include/linux/ksmbd_server.h
+++ b/include/linux/ksmbd_server.h
@@ -238,7 +238,8 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_SHARE_FLAG_STREAMS		(1 << 11)
 #define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS	(1 << 12)
 #define KSMBD_SHARE_FLAG_ACL_XATTR		(1 << 13)
-#define KSMBD_SHARE_FLAG_UPDATE		(1 << 14)
+#define KSMBD_SHARE_FLAG_UPDATE			(1 << 14)
+#define KSMBD_SHARE_FLAG_CROSSMNT		(1 << 15)
 
 /*
  * Tree connect request flags.
diff --git a/include/management/share.h b/include/management/share.h
index d6ed0a65ece1..5e2079919f55 100644
--- a/include/management/share.h
+++ b/include/management/share.h
@@ -117,6 +117,7 @@ enum KSMBD_SHARE_CONF {
 	KSMBD_SHARE_CONF_FOLLOW_SYMLINKS,
 	KSMBD_SHARE_CONF_VFS_OBJECTS,
 	KSMBD_SHARE_CONF_WRITABLE,
+	KSMBD_SHARE_CONF_CROSSMNT			= 30,
 	KSMBD_SHARE_CONF_MAX
 };
 
diff --git a/ksmbd.conf.5.in b/ksmbd.conf.5.in
index 6fd2bf7ab159..9f6bd9323186 100644
--- a/ksmbd.conf.5.in
+++ b/ksmbd.conf.5.in
@@ -346,6 +346,11 @@ Synonym for \fBwriteable\fP.
 Inverted synonym for \fBread only\fP.
 
 Default: \fBwriteable = no\fR
+.TP
+\fBcrossmnt\fR (S)
+Allow path lookup to cross a mountpoint to the root of a different filesystem.
+
+Default: \fBcrossmnt = yes\fR
 .SH COPYRIGHT
 Copyright \(co 2015-2022 ksmbd-tools contributors.
 License GPLv2: GNU GPL version 2 <https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html>.
diff --git a/ksmbd.conf.example b/ksmbd.conf.example
index c7e70afbb21b..389d49e3ed25 100644
--- a/ksmbd.conf.example
+++ b/ksmbd.conf.example
@@ -54,6 +54,7 @@
 	vfs objects = 
 	write list = 
 	writeable = no
+	crossmnt = yes
 
 [example]
 	; share parameter overrides for `example' share
diff --git a/lib/management/share.c b/lib/management/share.c
index 3af3f48fb9d2..403120d9be64 100644
--- a/lib/management/share.c
+++ b/lib/management/share.c
@@ -57,6 +57,7 @@ char *KSMBD_SHARE_CONF[KSMBD_SHARE_CONF_MAX] = {
 	"follow symlinks",
 	"vfs objects",
 	"writable",
+	"crossmnt",				/* 30 */
 };
 
 static GHashTable	*shares_table;
@@ -633,6 +634,13 @@ static void process_group_kv(gpointer _k, gpointer _v, gpointer user_data)
 		}
 	}
 
+	if (shm_share_config(k, KSMBD_SHARE_CONF_CROSSMNT)) {
+		if (cp_get_group_kv_bool(v))
+			set_share_flag(share, KSMBD_SHARE_FLAG_CROSSMNT);
+		else
+			clear_share_flag(share, KSMBD_SHARE_FLAG_CROSSMNT);
+		return;
+	}
 }
 
 static void fixup_missing_fields(struct ksmbd_share *share)
@@ -660,6 +668,7 @@ static void init_share_from_group(struct ksmbd_share *share,
 	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);
+	set_share_flag(share, KSMBD_SHARE_FLAG_CROSSMNT);
 
 	if (!g_ascii_strcasecmp(share->name, "ipc$"))
 		set_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
-- 
2.34.1

