Allow FuseMountName for chansrv to be absolute path
This commit is contained in:
parent
785db575ca
commit
5523847540
@ -54,11 +54,12 @@ libcommon_la_SOURCES = \
|
|||||||
log.h \
|
log.h \
|
||||||
os_calls.c \
|
os_calls.c \
|
||||||
os_calls.h \
|
os_calls.h \
|
||||||
os_calls.h \
|
|
||||||
parse.h \
|
parse.h \
|
||||||
rail.h \
|
rail.h \
|
||||||
ssl_calls.c \
|
ssl_calls.c \
|
||||||
ssl_calls.h \
|
ssl_calls.h \
|
||||||
|
string_calls.c \
|
||||||
|
string_calls.h \
|
||||||
thread_calls.c \
|
thread_calls.c \
|
||||||
thread_calls.h \
|
thread_calls.h \
|
||||||
trans.c \
|
trans.c \
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "os_calls.h"
|
#include "os_calls.h"
|
||||||
#include "thread_calls.h"
|
#include "thread_calls.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
/* Add a define here so that the log.h will hold more information
|
/* Add a define here so that the log.h will hold more information
|
||||||
* when compiled from this C file.
|
* when compiled from this C file.
|
||||||
|
@ -3307,6 +3307,17 @@ g_setsid(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int
|
||||||
|
g_getlogin(char *name, unsigned int len)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
return getlogin_r(name, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
g_setlogin(const char *name)
|
g_setlogin(const char *name)
|
||||||
@ -3760,21 +3771,6 @@ g_save_to_bmp(const char* filename, char* data, int stride_bytes,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* returns boolean */
|
|
||||||
int
|
|
||||||
g_text2bool(const char *s)
|
|
||||||
{
|
|
||||||
if ( (g_atoi(s) != 0) ||
|
|
||||||
(0 == g_strcasecmp(s, "true")) ||
|
|
||||||
(0 == g_strcasecmp(s, "on")) ||
|
|
||||||
(0 == g_strcasecmp(s, "yes")))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* returns pointer or nil on error */
|
/* returns pointer or nil on error */
|
||||||
void *
|
void *
|
||||||
|
@ -162,6 +162,7 @@ int g_getuid(void);
|
|||||||
int g_getgid(void);
|
int g_getgid(void);
|
||||||
int g_setuid(int pid);
|
int g_setuid(int pid);
|
||||||
int g_setsid(void);
|
int g_setsid(void);
|
||||||
|
int g_getlogin(char *name, unsigned int len);
|
||||||
int g_setlogin(const char *name);
|
int g_setlogin(const char *name);
|
||||||
int g_waitchild(void);
|
int g_waitchild(void);
|
||||||
int g_waitpid(int pid);
|
int g_waitpid(int pid);
|
||||||
@ -180,7 +181,6 @@ int g_time2(void);
|
|||||||
int g_time3(void);
|
int g_time3(void);
|
||||||
int g_save_to_bmp(const char* filename, char* data, int stride_bytes,
|
int g_save_to_bmp(const char* filename, char* data, int stride_bytes,
|
||||||
int width, int height, int depth, int bits_per_pixel);
|
int width, int height, int depth, int bits_per_pixel);
|
||||||
int g_text2bool(const char *s);
|
|
||||||
void * g_shmat(int shmid);
|
void * g_shmat(int shmid);
|
||||||
int g_shmdt(const void *shmaddr);
|
int g_shmdt(const void *shmaddr);
|
||||||
int g_gethostname(char *name, int len);
|
int g_gethostname(char *name, int len);
|
||||||
|
136
common/string_calls.c
Normal file
136
common/string_calls.c
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Copyright (C) Jay Sorg 2004-2020
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* generic string handling calls
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
g_format_info_string(char* dest, unsigned int len,
|
||||||
|
const char* format,
|
||||||
|
const struct info_string_tag map[])
|
||||||
|
{
|
||||||
|
unsigned int result = 0;
|
||||||
|
const char *copy_from; /* Data to add to output */
|
||||||
|
unsigned int copy_len; /* Length of above */
|
||||||
|
unsigned int skip; /* Date to skip over in format string */
|
||||||
|
const char *p;
|
||||||
|
const struct info_string_tag *m;
|
||||||
|
|
||||||
|
for ( ; *format != '\0'; format += skip)
|
||||||
|
{
|
||||||
|
if (*format == '%')
|
||||||
|
{
|
||||||
|
char ch= *(format + 1);
|
||||||
|
if (ch== '%')
|
||||||
|
{
|
||||||
|
/* '%%' in format - replace with single '%' */
|
||||||
|
copy_from = format;
|
||||||
|
copy_len= 1;
|
||||||
|
skip = 2;
|
||||||
|
}
|
||||||
|
else if (ch== '\0')
|
||||||
|
{
|
||||||
|
/* Percent at end of string - ignore */
|
||||||
|
copy_from = NULL;
|
||||||
|
copy_len= 0;
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Look up the character in the map, assuming failure */
|
||||||
|
copy_from = NULL;
|
||||||
|
copy_len= 0;
|
||||||
|
skip = 2;
|
||||||
|
|
||||||
|
for (m = map ; m->ch != '\0' ; ++m)
|
||||||
|
{
|
||||||
|
if (ch == m->ch)
|
||||||
|
{
|
||||||
|
copy_from = m->val;
|
||||||
|
copy_len = strlen(copy_from);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((p = strchr(format, '%')) != NULL)
|
||||||
|
{
|
||||||
|
/* Copy up to the next '%' */
|
||||||
|
copy_from = format;
|
||||||
|
copy_len = p - format;
|
||||||
|
skip = copy_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy the rest of the format string */
|
||||||
|
copy_from = format;
|
||||||
|
copy_len = strlen(format);
|
||||||
|
skip = copy_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the result before any truncation */
|
||||||
|
result += copy_len;
|
||||||
|
|
||||||
|
/* Do we have room in the output buffer for any more data? We
|
||||||
|
* must always write a terminator if possible */
|
||||||
|
if (len > 1)
|
||||||
|
{
|
||||||
|
if (copy_len > (len - 1))
|
||||||
|
{
|
||||||
|
copy_len = len - 1;
|
||||||
|
}
|
||||||
|
memcpy(dest, copy_from, copy_len);
|
||||||
|
dest += copy_len;
|
||||||
|
len -= copy_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Room for a terminator? */
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
*dest = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
const char *
|
||||||
|
g_bool2text(int value)
|
||||||
|
{
|
||||||
|
return value ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int
|
||||||
|
g_text2bool(const char *s)
|
||||||
|
{
|
||||||
|
if ( (atoi(s) != 0) ||
|
||||||
|
(0 == strcasecmp(s, "true")) ||
|
||||||
|
(0 == strcasecmp(s, "on")) ||
|
||||||
|
(0 == strcasecmp(s, "yes")))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
81
common/string_calls.h
Normal file
81
common/string_calls.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Copyright (C) Jay Sorg 2004-2020
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* generic string handling calls
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(STRING_CALLS_H)
|
||||||
|
#define STRING_CALLS_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a character to a string value
|
||||||
|
*
|
||||||
|
* This structure is used by g_format_info_string() to specify the
|
||||||
|
* string which chould be output for %'ch', where ch is a character
|
||||||
|
*/
|
||||||
|
struct info_string_tag
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
const char *val;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define INFO_STRING_END_OF_LIST { '\0', NULL }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a format string for general info
|
||||||
|
*
|
||||||
|
* @param[out] dest Destination buffer
|
||||||
|
* @param[in] len Length of buffer, including space for a terminator
|
||||||
|
* @param[in] format Format string to process
|
||||||
|
* @param[in] map Array of struct info_string_tag.
|
||||||
|
*
|
||||||
|
* Where a '%<ch>' is encountered in the format string, the map is scanned
|
||||||
|
* and the corresponding string is copied instead of '%<ch>'.
|
||||||
|
*
|
||||||
|
* '%%' is always replaced with a single '%' in the output. %<ch> strings
|
||||||
|
* not present in the map are ignored.
|
||||||
|
*
|
||||||
|
* The map is terminated with INFO_STRING_END_OF_LIST
|
||||||
|
*
|
||||||
|
* Caller can check for buffer truncation by comparing the result with
|
||||||
|
* the buffer length (as in snprintf())
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
g_format_info_string(char* dest, unsigned int len,
|
||||||
|
const char* format,
|
||||||
|
const struct info_string_tag map[]);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a boolean to a string for output
|
||||||
|
*
|
||||||
|
* @param[in] value Value to convert
|
||||||
|
* @return String representation
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
g_bool2text(int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string to a boolean value
|
||||||
|
*
|
||||||
|
* @param[in] s String to convert
|
||||||
|
* @return machine representation
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
g_text2bool(const char *s);
|
||||||
|
|
||||||
|
#endif
|
@ -246,8 +246,27 @@ Following parameters can be used in the \fB[Chansrv]\fR section.
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBFuseMountName\fR=\fIstring\fR
|
\fBFuseMountName\fR=\fIstring\fR
|
||||||
Directory for drive redirection, relative to the user home directory.
|
Directory for drive redirection.
|
||||||
Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
|
Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
|
||||||
|
If first character is not a '/', this is relative to $HOME.
|
||||||
|
.P
|
||||||
|
.RS
|
||||||
|
If first character is a '/' this is an absolute path. The following
|
||||||
|
substitutions are made in this string:-
|
||||||
|
%U - Username
|
||||||
|
%u - Numeric UID
|
||||||
|
%% - Percent character
|
||||||
|
.P
|
||||||
|
If this format is used:-
|
||||||
|
.HP 3
|
||||||
|
1) The directory path permissions MUST be configured correctly by
|
||||||
|
the system administrator or the system itself - xrdp-chansrv will not
|
||||||
|
do this for you (although it will create the final directories owned by
|
||||||
|
the user).
|
||||||
|
.HP 3
|
||||||
|
2) The desktop may not automatically display a link for the redirected
|
||||||
|
drive. To fix this, consult the docs for your chosen desktop.
|
||||||
|
.RE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBFileUmask\fR=\fImode\fR
|
\fBFileUmask\fR=\fImode\fR
|
||||||
@ -257,6 +276,21 @@ files on your redirected drives. This may not be approprate for all
|
|||||||
environents, and so you can change this value to allow other users to
|
environents, and so you can change this value to allow other users to
|
||||||
access your remote files if required.
|
access your remote files if required.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fBEnableFuseMount\fR=\fI[true|false]\fR
|
||||||
|
Defaults to \fItrue\fR.
|
||||||
|
Set to \fIfalse\fR to disable xrdp-chansrv's use of the FUSE system
|
||||||
|
feature, even if it has been built with this feature enabled.
|
||||||
|
.P
|
||||||
|
.RS
|
||||||
|
Setting this value to \fIfalse\fR will disable the following application
|
||||||
|
features:-
|
||||||
|
.P
|
||||||
|
- drive redirection
|
||||||
|
.P
|
||||||
|
- copying-and-pasting of files
|
||||||
|
.RE
|
||||||
|
|
||||||
.SH "SESSIONS VARIABLES"
|
.SH "SESSIONS VARIABLES"
|
||||||
All entries in the \fB[SessionVariables]\fR section are set as
|
All entries in the \fB[SessionVariables]\fR section are set as
|
||||||
environment variables in the user's session.
|
environment variables in the user's session.
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "ms-rdpbcgr.h"
|
#include "ms-rdpbcgr.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "ssl_calls.h"
|
#include "ssl_calls.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
#if defined(XRDP_NEUTRINORDP)
|
#if defined(XRDP_NEUTRINORDP)
|
||||||
#include <freerdp/codec/rfx.h>
|
#include <freerdp/codec/rfx.h>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "xrdp_rail.h"
|
#include "xrdp_rail.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
#include <freerdp/settings.h>
|
#include <freerdp/settings.h>
|
||||||
|
|
||||||
#if defined(VERSION_STRUCT_RDP_FREERDP)
|
#if defined(VERSION_STRUCT_RDP_FREERDP)
|
||||||
|
@ -31,10 +31,12 @@
|
|||||||
#include "os_calls.h"
|
#include "os_calls.h"
|
||||||
|
|
||||||
#include "chansrv_config.h"
|
#include "chansrv_config.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
/* Default settings */
|
/* Default settings */
|
||||||
#define DEFAULT_USE_UNIX_SOCKET 0
|
#define DEFAULT_USE_UNIX_SOCKET 0
|
||||||
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
|
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
|
||||||
|
#define DEFAULT_ENABLE_FUSE_MOUNT 1
|
||||||
#define DEFAULT_FUSE_MOUNT_NAME "xrdp-client"
|
#define DEFAULT_FUSE_MOUNT_NAME "xrdp-client"
|
||||||
#define DEFAULT_FILE_UMASK 077
|
#define DEFAULT_FILE_UMASK 077
|
||||||
|
|
||||||
@ -155,6 +157,10 @@ read_config_chansrv(log_func_t logmsg,
|
|||||||
const char *name = (const char *)list_get_item(names, index);
|
const char *name = (const char *)list_get_item(names, index);
|
||||||
const char *value = (const char *)list_get_item(values, index);
|
const char *value = (const char *)list_get_item(values, index);
|
||||||
|
|
||||||
|
if (g_strcasecmp(name, "EnableFuseMount") == 0)
|
||||||
|
{
|
||||||
|
cfg->enable_fuse_mount = g_text2bool(value);
|
||||||
|
}
|
||||||
if (g_strcasecmp(name, "FuseMountName") == 0)
|
if (g_strcasecmp(name, "FuseMountName") == 0)
|
||||||
{
|
{
|
||||||
g_free(cfg->fuse_mount_name);
|
g_free(cfg->fuse_mount_name);
|
||||||
@ -196,6 +202,7 @@ new_config(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET;
|
cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET;
|
||||||
|
cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT;
|
||||||
cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
|
cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
|
||||||
cfg->fuse_mount_name = fuse_mount_name;
|
cfg->fuse_mount_name = fuse_mount_name;
|
||||||
cfg->file_umask = DEFAULT_FILE_UMASK;
|
cfg->file_umask = DEFAULT_FILE_UMASK;
|
||||||
@ -271,13 +278,16 @@ void
|
|||||||
config_dump(struct config_chansrv *config)
|
config_dump(struct config_chansrv *config)
|
||||||
{
|
{
|
||||||
g_writeln("Global configuration:");
|
g_writeln("Global configuration:");
|
||||||
g_writeln(" UseUnixSocket (derived): %d", config->use_unix_socket);
|
g_writeln(" UseUnixSocket (derived): %s",
|
||||||
|
g_bool2text(config->use_unix_socket));
|
||||||
|
|
||||||
g_writeln("\nSecurity configuration:");
|
g_writeln("\nSecurity configuration:");
|
||||||
g_writeln(" RestrictOutboundClipboard: %d",
|
g_writeln(" RestrictOutboundClipboard: %s",
|
||||||
config->restrict_outbound_clipboard);
|
g_bool2text(config->restrict_outbound_clipboard));
|
||||||
|
|
||||||
g_writeln("\nChansrv configuration:");
|
g_writeln("\nChansrv configuration:");
|
||||||
|
g_writeln(" EnableFuseMount %s",
|
||||||
|
g_bool2text(config->enable_fuse_mount));
|
||||||
g_writeln(" FuseMountName: %s", config->fuse_mount_name);
|
g_writeln(" FuseMountName: %s", config->fuse_mount_name);
|
||||||
g_writeln(" FileMask: 0%o", config->file_umask);
|
g_writeln(" FileMask: 0%o", config->file_umask);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ struct config_chansrv
|
|||||||
/** Whether to use a UNIX socket for chansrv */
|
/** Whether to use a UNIX socket for chansrv */
|
||||||
int use_unix_socket;
|
int use_unix_socket;
|
||||||
|
|
||||||
|
/** Whether the FUSE mount is enabled or not */
|
||||||
|
int enable_fuse_mount;
|
||||||
|
|
||||||
/** RestrictOutboundClipboard setting from sesman.ini */
|
/** RestrictOutboundClipboard setting from sesman.ini */
|
||||||
int restrict_outbound_clipboard;
|
int restrict_outbound_clipboard;
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ void xfuse_devredir_cb_file_close(struct state_close *fip)
|
|||||||
|
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "os_calls.h"
|
#include "os_calls.h"
|
||||||
|
#include "string_calls.h"
|
||||||
#include "clipboard_file.h"
|
#include "clipboard_file.h"
|
||||||
#include "chansrv_fuse.h"
|
#include "chansrv_fuse.h"
|
||||||
#include "chansrv_xfs.h"
|
#include "chansrv_xfs.h"
|
||||||
@ -392,6 +393,8 @@ static const char *filename_on_device(const char *full_path);
|
|||||||
static void update_inode_file_attributes(const struct file_attr *fattr,
|
static void update_inode_file_attributes(const struct file_attr *fattr,
|
||||||
tui32 change_mask, XFS_INODE *xinode);
|
tui32 change_mask, XFS_INODE *xinode);
|
||||||
static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name);
|
static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name);
|
||||||
|
static unsigned int format_user_info(char *dest, unsigned int len,
|
||||||
|
const char *format);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
@ -446,7 +449,7 @@ xfuse_handle_from_fuse_handle(uint64_t handle)
|
|||||||
/**
|
/**
|
||||||
* Initialize FUSE subsystem
|
* Initialize FUSE subsystem
|
||||||
*
|
*
|
||||||
* @return 0 on success, -1 on failure
|
* @return 0 on success, -1 on failure, 1 for feature disabled
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -458,6 +461,21 @@ xfuse_init(void)
|
|||||||
if (g_xfuse_inited)
|
if (g_xfuse_inited)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "already inited");
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "already inited");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This feature may be disabled */
|
||||||
|
if (!g_cfg->enable_fuse_mount)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only log the 'disabled mounts' message one time
|
||||||
|
*/
|
||||||
|
static int disabled_mounts_msg_shown = 0;
|
||||||
|
if (!disabled_mounts_msg_shown)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "FUSE mounts are disabled by config");
|
||||||
|
disabled_mounts_msg_shown = 1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,13 +487,27 @@ xfuse_init(void)
|
|||||||
|
|
||||||
load_fuse_config();
|
load_fuse_config();
|
||||||
|
|
||||||
/* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */
|
/* define FUSE mount point */
|
||||||
g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_cfg->fuse_mount_name);
|
if (g_cfg->fuse_mount_name[0] == '/')
|
||||||
|
{
|
||||||
|
/* String is an absolute path to the mount point containing
|
||||||
|
* %u or %U characters */
|
||||||
|
format_user_info(g_fuse_root_path, sizeof(g_fuse_root_path),
|
||||||
|
g_cfg->fuse_mount_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* mount_name is relative to $HOME, e.g. ~/xrdp_client,
|
||||||
|
* or ~/thinclient_drives */
|
||||||
|
g_snprintf(g_fuse_root_path, sizeof(g_fuse_root_path), "%s/%s",
|
||||||
|
g_getenv("HOME"), g_cfg->fuse_mount_name);
|
||||||
|
}
|
||||||
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
|
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
|
||||||
|
|
||||||
/* if FUSE mount point does not exist, create it */
|
/* if FUSE mount point does not exist, create it */
|
||||||
if (!g_directory_exist(g_fuse_root_path))
|
if (!g_directory_exist(g_fuse_root_path))
|
||||||
{
|
{
|
||||||
|
(void)g_create_path(g_fuse_root_path);
|
||||||
if (!g_create_dir(g_fuse_root_path))
|
if (!g_create_dir(g_fuse_root_path))
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_ERROR, "mkdir %s failed. If %s is already mounted, you must "
|
LOG_DEVEL(LOG_LEVEL_ERROR, "mkdir %s failed. If %s is already mounted, you must "
|
||||||
@ -748,9 +780,19 @@ xfuse_file_contents_range(int stream_id, const char *data, int data_bytes)
|
|||||||
int
|
int
|
||||||
xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex)
|
xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: filename=%s flags=%d size=%d lindex=%d",
|
LOG_DEVEL(LOG_LEVEL_DEBUG,
|
||||||
|
"entered: filename=%s flags=%d size=%d lindex=%d",
|
||||||
filename, flags, size, lindex);
|
filename, flags, size, lindex);
|
||||||
|
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
if (g_xfs == NULL)
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||||
|
"xfuse_add_clip_dir_item() called with no filesystem")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* add entry to xrdp_fs */
|
/* add entry to xrdp_fs */
|
||||||
XFS_INODE *xinode = xfs_add_entry( g_xfs,
|
XFS_INODE *xinode = xfs_add_entry( g_xfs,
|
||||||
g_clipboard_inum, /* parent inode */
|
g_clipboard_inum, /* parent inode */
|
||||||
@ -758,13 +800,18 @@ xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex)
|
|||||||
(0666 | S_IFREG));
|
(0666 | S_IFREG));
|
||||||
if (xinode == NULL)
|
if (xinode == NULL)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "failed to create file in xrdp filesystem");
|
LOG(LOG_LEVEL_INFO,
|
||||||
return -1;
|
"failed to create file %s in xrdp filesystem", filename);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
xinode->size = size;
|
xinode->size = size;
|
||||||
xinode->lindex = lindex;
|
xinode->lindex = lindex;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2609,4 +2656,30 @@ static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scans a user-provided string substituting %u/%U for UID/username
|
||||||
|
*/
|
||||||
|
static unsigned int format_user_info(char *dest, unsigned int len,
|
||||||
|
const char *format)
|
||||||
|
{
|
||||||
|
char uidstr[64];
|
||||||
|
char username[64];
|
||||||
|
const struct info_string_tag map[] =
|
||||||
|
{
|
||||||
|
{'u', uidstr},
|
||||||
|
{'U', username},
|
||||||
|
INFO_STRING_END_OF_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
int uid = g_getuid();
|
||||||
|
g_snprintf(uidstr, sizeof(uidstr), "%d", uid);
|
||||||
|
if (g_getlogin(username, sizeof(username)) != 0)
|
||||||
|
{
|
||||||
|
/* Fall back to UID */
|
||||||
|
g_strncpy(username, uidstr, sizeof(username) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_format_info_string(dest, len, format, map);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* end else #ifndef XRDP_FUSE */
|
#endif /* end else #ifndef XRDP_FUSE */
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "sesman.h"
|
#include "sesman.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
*
|
*
|
||||||
|
@ -114,11 +114,16 @@ param=-dpi
|
|||||||
param=96
|
param=96
|
||||||
|
|
||||||
[Chansrv]
|
[Chansrv]
|
||||||
; drive redirection, defaults to xrdp_client if not set
|
; drive redirection
|
||||||
|
; See sesman.ini(5) for the format of this parameter
|
||||||
|
#FuseMountName=/run/user/%u/thinclient_drives
|
||||||
|
#FuseMountName=/media/thinclient_drives/%U/thinclient_drives
|
||||||
FuseMountName=thinclient_drives
|
FuseMountName=thinclient_drives
|
||||||
; this value allows only the user to acess their own mapped drives.
|
; this value allows only the user to acess their own mapped drives.
|
||||||
; Make this more permissive (e.g. 022) if required.
|
; Make this more permissive (e.g. 022) if required.
|
||||||
FileUmask=077
|
FileUmask=077
|
||||||
|
; Can be used to disable FUSE functionality - see sesman.ini(5)
|
||||||
|
#EnableFuseMount=false
|
||||||
|
|
||||||
[ChansrvLogging]
|
[ChansrvLogging]
|
||||||
; Note: one log file is created per display and the LogFile config value
|
; Note: one log file is created per display and the LogFile config value
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
/* 'g_process' is protected by the semaphore 'g_process_sem'. One thread sets
|
/* 'g_process' is protected by the semaphore 'g_process_sem'. One thread sets
|
||||||
g_process and waits for the other to process it */
|
g_process and waits for the other to process it */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
#define ASK "ask"
|
#define ASK "ask"
|
||||||
#define ASK_LEN g_strlen(ASK)
|
#define ASK_LEN g_strlen(ASK)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
#ifndef USE_NOPAM
|
#ifndef USE_NOPAM
|
||||||
#if defined(HAVE__PAM_TYPES_H)
|
#if defined(HAVE__PAM_TYPES_H)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "ms-rdpbcgr.h"
|
#include "ms-rdpbcgr.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "string_calls.h"
|
||||||
|
|
||||||
#define LLOG_LEVEL 1
|
#define LLOG_LEVEL 1
|
||||||
#define LLOGLN(_level, _args) \
|
#define LLOGLN(_level, _args) \
|
||||||
|
Loading…
Reference in New Issue
Block a user