From 142d0628fae8e3c51557e28b446c87eaa5aa0497 Mon Sep 17 00:00:00 2001 From: Constantin Kulikov Date: Sun, 5 Jan 2025 19:21:21 +0300 Subject: [PATCH] Add sesman.ini FuseMountNameColonCharReplacement option (cherry picked from commit 151c555fc0bc3e08df7a3d977671b6756a750f5e) --- docs/man/sesman.ini.5.in | 9 ++++++++ sesman/chansrv/chansrv_config.c | 22 +++++++++++++++++++ sesman/chansrv/chansrv_config.h | 2 ++ sesman/chansrv/chansrv_fuse.c | 39 +++++++++++++++++++++++++++++++-- sesman/sesman.ini.in | 1 + 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index 31681603f5..ce386ebad2 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -380,6 +380,15 @@ the user). drive. To fix this, consult the docs for your chosen desktop. .RE +.TP +\fBFuseMountNameColonCharReplacement\fR=\fIstring\fR +Character to replace colon in redirected drive mount point names. +If not specified no colon will not be replaced. +If empty then colon will be replaced by null character. +If longer than one character, only first character used. +Only last colon replaced. +.RE + .TP \fBFuseDirectIO\fR=\fI[false|true]\fR Defaults to \fIfalse\fR. Set to \fItrue\fR to disable page caching in diff --git a/sesman/chansrv/chansrv_config.c b/sesman/chansrv/chansrv_config.c index 4535b5cc9e..14bd43b291 100644 --- a/sesman/chansrv/chansrv_config.c +++ b/sesman/chansrv/chansrv_config.c @@ -40,6 +40,7 @@ #define DEFAULT_RESTRICT_INBOUND_CLIPBOARD 0 #define DEFAULT_ENABLE_FUSE_MOUNT 1 #define DEFAULT_FUSE_MOUNT_NAME "xrdp-client" +#define DEFAULT_FUSE_MOUNT_NAME_COLON_CHAR_REPLACEMENT ':' #define DEFAULT_FUSE_DIRECT_IO 0 #define DEFAULT_FILE_UMASK 077 #define DEFAULT_USE_NAUTILUS3_FLIST_FORMAT 0 @@ -220,6 +221,25 @@ read_config_chansrv(log_func_t logmsg, break; } } + else if (g_strcasecmp(name, "FuseMountNameColonCharReplacement") == 0) + { + size_t vallen = g_strlen(value); + if (vallen < 1) + { + cfg->fuse_mount_name_colon_char_replacement = '\0'; + } + else + { + if (vallen > 1) + { + logmsg(LOG_LEVEL_WARNING, "FuseMountNameColonCharReplacement " + "must be 1 character length, now it is '%s'." + "Only first char will be used!", + value); + } + cfg->fuse_mount_name_colon_char_replacement = value[0]; + } + } else if (g_strcasecmp(name, "FuseDirectIO") == 0) { cfg->fuse_direct_io = g_text2bool(value); @@ -315,6 +335,7 @@ new_config(void) cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD; cfg->restrict_inbound_clipboard = DEFAULT_RESTRICT_INBOUND_CLIPBOARD; cfg->fuse_mount_name = fuse_mount_name; + cfg->fuse_mount_name_colon_char_replacement = DEFAULT_FUSE_MOUNT_NAME_COLON_CHAR_REPLACEMENT; cfg->fuse_direct_io = DEFAULT_FUSE_DIRECT_IO; cfg->file_umask = DEFAULT_FILE_UMASK; cfg->use_nautilus3_flist_format = DEFAULT_USE_NAUTILUS3_FLIST_FORMAT; @@ -419,6 +440,7 @@ config_dump(struct config_chansrv *config) g_writeln(" EnableFuseMount %s", g_bool2text(config->enable_fuse_mount)); g_writeln(" FuseMountName: %s", config->fuse_mount_name); + g_writeln(" FuseMountNameColonCharReplacement: %c", config->fuse_mount_name_colon_char_replacement); g_writeln(" FuseDirectIO: %s", g_bool2text(config->fuse_direct_io)); g_writeln(" FileMask: 0%o", config->file_umask); diff --git a/sesman/chansrv/chansrv_config.h b/sesman/chansrv/chansrv_config.h index 621e036fb8..031bd487ec 100644 --- a/sesman/chansrv/chansrv_config.h +++ b/sesman/chansrv/chansrv_config.h @@ -39,6 +39,8 @@ struct config_chansrv /** * FuseMountName from sesman.ini */ char *fuse_mount_name; + /** * FuseMountNameColonCharReplacement from sesman.ini */ + char fuse_mount_name_colon_char_replacement; /** FileUmask from sesman.ini */ mode_t file_umask; diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 3c8d7f511f..05f64928a8 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -191,6 +191,36 @@ int xfuse_path_in_xfuse_fs(const char *path) #define XFUSE_ENTRY_TIMEOUT 5.0 +extern struct config_chansrv *g_cfg; /* in chansrv.c */ + + +/* Local utility functions */ + +static inline char * +_fuse_mount_name_colon_char_replace(const char *dirname) +{ + char *newdirname = (char *) dirname; + if (g_cfg->fuse_mount_name_colon_char_replacement != ':') + { + newdirname = g_strdup(dirname); + if (newdirname == NULL) + { + LOG_DEVEL(LOG_LEVEL_ERROR, + "Failed to duplicate fuse mount name string"); + return (char *) dirname; + } + char *colonptr = g_strrchr(newdirname, ':'); + if (colonptr != NULL) + { + *colonptr = g_cfg->fuse_mount_name_colon_char_replacement; + } + } + return newdirname; +} + +/* End of Local utility functions*/ + + /* Type of buffer used for fuse_add_direntry() calls */ struct dirbuf1 { @@ -343,7 +373,6 @@ struct req_list_item int size; }; -extern struct config_chansrv *g_cfg; /* in chansrv.c */ static struct list *g_req_list = 0; static struct xfs_fs *g_xfs; /* an inst of xrdp file system */ @@ -742,7 +771,13 @@ int xfuse_create_share(tui32 device_id, const char *dirname) if (dirname != NULL && strlen(dirname) > 0 && xfuse_init_xrdp_fs() == 0) { - xinode = xfs_add_entry(g_xfs, FUSE_ROOT_ID, dirname, (0777 | S_IFDIR)); + char *newdirname = _fuse_mount_name_colon_char_replace(dirname); + xinode = xfs_add_entry(g_xfs, FUSE_ROOT_ID, newdirname, (0777 | S_IFDIR)); + //free only if _fuse_mount_name_colon_char_replace allocated new string + if (newdirname != dirname) + { + g_free(newdirname); + } if (xinode == NULL) { LOG_DEVEL(LOG_LEVEL_DEBUG, "xfs_add_entry() failed"); diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index cd49a148ec..57a6545613 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -168,6 +168,7 @@ param=96 #FuseMountName=/run/user/%u/thinclient_drives #FuseMountName=/media/thinclient_drives/%U/thinclient_drives FuseMountName=thinclient_drives +#FuseMountNameColonCharReplacement= ; this value allows only the user to access their own mapped drives. ; Make this more permissive (e.g. 022) if required. FileUmask=077