From 2f7be3f63491401915fbbca6d9990b59124cf167 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:23:02 +0000 Subject: [PATCH 1/2] Allow a path to be specified for the chansrv log This is useful for NFS-mounted home directories, where hosts may otherwise produce colliding chansrv log file names (cherry picked from commit cfc2e362b47103bc2c786252f331bb26b6ddecb5) --- docs/man/sesman.ini.5.in | 22 +++++++++++++ sesman/chansrv/chansrv.c | 57 ++++++++++++++++++++++----------- sesman/chansrv/chansrv_config.c | 20 +++++++++++- sesman/chansrv/chansrv_config.h | 3 ++ sesman/sesman.ini.in | 5 +++ 5 files changed, 88 insertions(+), 19 deletions(-) diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index 6b45b7120a..b30d7ae8ee 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -409,6 +409,28 @@ Sets the duration(msec). Sound data is not send to client during \fInumber\fR millisecond(s) after close message is sent, when AAC/MP3 is selected. If set to 0, all the data is sent. If not specified, defaults to \fI1000\fR. +.TP +\fBLogFilePath\fR=\fIstring\fR +Directory for storing the chansrv log file +Created if it doesn't exist. +If first character is not a '/', this is relative to $HOME. +.P +.RS +The following substitutions are made in this string:- + %U - Username + %u - Numeric UID + %% - Percent character +.P +This is most useful if you are using NFS-mounted home directories, and +wish to move the chansrv log file to the local disk. + +If this isn't specified, the log file is stored in one of the following +locations :- + - $CHANSRV_LOG_PATH + - $XDG_DATA_HOME/xrdp + - $HOME/.local/share/xrdp +.RE + .SH "SESSIONS VARIABLES" All entries in the \fB[SessionVariables]\fR section are set as environment variables in the user's session. diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index e890febcc2..f19346bc41 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -1694,20 +1694,32 @@ get_log_path(char *path, int bytes) int rv; rv = 1; - log_path = g_getenv("CHANSRV_LOG_PATH"); - if (log_path == 0) + if (g_cfg->log_file_path != NULL && g_cfg->log_file_path[0] != '\0') { - log_path = g_getenv("XDG_DATA_HOME"); - if (log_path != 0) + char uidstr[64]; + char username[64]; + const struct info_string_tag map[] = { - g_snprintf(path, bytes, "%s%s", log_path, "/xrdp"); - if (g_directory_exist(path) || (g_mkdir(path) == 0)) - { - rv = 0; - } + {'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); + } + + (void)g_format_info_string(path, bytes, g_cfg->log_file_path, map); + if (g_directory_exist(path) || (g_mkdir(path) == 0)) + { + rv = 0; } } - else + else if ((log_path = g_getenv("CHANSRV_LOG_PATH")) != 0) { g_snprintf(path, bytes, "%s", log_path); if (g_directory_exist(path) || (g_mkdir(path) == 0)) @@ -1715,6 +1727,16 @@ get_log_path(char *path, int bytes) rv = 0; } } + else if ((log_path = g_getenv("XDG_DATA_HOME")) != 0) + { + g_snprintf(path, bytes, "%s%s", log_path, "/xrdp"); + if (g_directory_exist(path) || (g_mkdir(path) == 0)) + { + rv = 0; + } + } + + // Always fall back to the home directory if (rv != 0) { log_path = g_getenv("HOME"); @@ -1830,14 +1852,6 @@ main(int argc, char **argv) g_init("xrdp-chansrv"); /* os_calls */ g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs)); - log_path[255] = 0; - if (get_log_path(log_path, 255) != 0) - { - g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable"); - main_cleanup(); - return 1; - } - display_text = g_getenv("DISPLAY"); if (display_text == NULL) { @@ -1864,6 +1878,13 @@ main(int argc, char **argv) } config_dump(g_cfg); + if (get_log_path(log_path, sizeof(log_path)) != 0) + { + g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable"); + main_cleanup(); + return 1; + } + pid = g_getpid(); /* starting logging subsystem */ diff --git a/sesman/chansrv/chansrv_config.c b/sesman/chansrv/chansrv_config.c index 76b134a028..6a0f56d249 100644 --- a/sesman/chansrv/chansrv_config.c +++ b/sesman/chansrv/chansrv_config.c @@ -46,6 +46,7 @@ #define DEFAULT_NUM_SILENT_FRAMES_AAC 4 #define DEFAULT_NUM_SILENT_FRAMES_MP3 2 #define DEFAULT_MSEC_DO_NOT_SEND 1000 +#define DEFAULT_LOG_FILE_PATH "" /** * Type used for passing a logging function about */ @@ -243,6 +244,17 @@ read_config_chansrv(log_func_t logmsg, { cfg->msec_do_not_send = strtoul(value, NULL, 0); } + else if (g_strcasecmp(name, "LogFilePath") == 0) + { + g_free(cfg->log_file_path); + cfg->log_file_path = g_strdup(value); + if (cfg->log_file_path == NULL) + { + logmsg(LOG_LEVEL_ERROR, "Can't alloc LogFilePath"); + error = 1; + break; + } + } } return error; @@ -259,9 +271,11 @@ new_config(void) /* Do all the allocations at the beginning, then check them together */ struct config_chansrv *cfg = g_new0(struct config_chansrv, 1); char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME); - if (cfg == NULL || fuse_mount_name == NULL) + char *log_file_path = g_strdup(DEFAULT_LOG_FILE_PATH); + if (cfg == NULL || fuse_mount_name == NULL || log_file_path == NULL) { /* At least one memory allocation failed */ + g_free(log_file_path); g_free(fuse_mount_name); g_free(cfg); cfg = NULL; @@ -279,6 +293,7 @@ new_config(void) cfg->num_silent_frames_aac = DEFAULT_NUM_SILENT_FRAMES_AAC; cfg->num_silent_frames_mp3 = DEFAULT_NUM_SILENT_FRAMES_MP3; cfg->msec_do_not_send = DEFAULT_MSEC_DO_NOT_SEND; + cfg->log_file_path = log_file_path; } return cfg; @@ -375,6 +390,8 @@ config_dump(struct config_chansrv *config) g_writeln(" FileMask: 0%o", config->file_umask); g_writeln(" Nautilus 3 Flist Format: %s", g_bool2text(config->use_nautilus3_flist_format)); + g_writeln(" LogFilePath : %s", + (config->log_file_path) ? config->log_file_path : ""); } /******************************************************************************/ @@ -385,6 +402,7 @@ config_free(struct config_chansrv *cc) { g_free(cc->listen_port); g_free(cc->fuse_mount_name); + g_free(cc->log_file_path); g_free(cc); } } diff --git a/sesman/chansrv/chansrv_config.h b/sesman/chansrv/chansrv_config.h index b438a302be..b089021f11 100644 --- a/sesman/chansrv/chansrv_config.h +++ b/sesman/chansrv/chansrv_config.h @@ -50,6 +50,9 @@ struct config_chansrv unsigned int num_silent_frames_mp3; /** Do net send sound data afer SNDC_CLOSE is sent. unit is millisecond, setting from sesman.ini */ unsigned int msec_do_not_send; + + /** LogFilePath from sesman.ini */ + char *log_file_path; }; diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index 96089a3f1e..660ba37cfb 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -191,6 +191,11 @@ FileUmask=077 #SoundNumSilentFramesAAC=4 #SoundNumSilentFramesMP3=2 #SoundMsecDoNotSend=1000 +; Log file path +; Set this to move the log file away from its default location. You may want +; to do this for (e.g.) NFS-mounted home directories +; See sesman.ini(5) for the format of this parameter +#LogFilePath=/run/user/%u/xrdp [ChansrvLogging] ; Note: one log file is created per display and the LogFile config value From 162153ab6f3f5f62ee2cdc8dc65431d56d7db9cc Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Mon, 16 Dec 2024 10:45:25 +0000 Subject: [PATCH 2/2] Move LogFilePath parameter to [ChansrvLogging] This seems a better fit than having it in the [Chansrv] section. Also fixed a minor logging error relating to the parameter in chansrv_config.c (cherry picked from commit 6d2fd1be8451418f01dfbb203929e2838c1a979f) --- docs/man/sesman.ini.5.in | 50 ++++++++++++++++++--------------- sesman/chansrv/chansrv_config.c | 38 +++++++++++++++++++++++-- sesman/chansrv/chansrv_config.h | 2 +- sesman/sesman.ini.in | 10 +++---- 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index b30d7ae8ee..b73fd880da 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -98,7 +98,33 @@ stdout. Use for debugging only\fR It is ignored in the [ChansrvLogging] section since the channel server creates one log file per display and instead uses the -following log file naming convention \fIxrdp-chansrv.${DISPLAY}.log\fR +following log file naming convention \fIxrdp-chansrv.${DISPLAY}.log\fR. For +details of the chansrv log file location, see \fBLogFilePath\fR. + +.TP +\fBLogFilePath\fR=\fIstring\fR +Directory for storing the chansrv log file. This setting only applies to +chansrv. The sesman log file is always created in \fI@localstatedir@/log\fR. + +Created if it doesn't exist. +If first character is not a '/', this is relative to $HOME, where +chansrv is normally started. + +.RS +The following substitutions are made in this string:- + %U - Username + %u - Numeric UID + %% - Percent character + +This is most useful if you are using NFS-mounted home directories, and +wish to move the chansrv log file to the local disk. + +If this parameter isn't specified, the log file is stored in one of +the following locations :- + - $CHANSRV_LOG_PATH + - $XDG_DATA_HOME/xrdp + - $HOME/.local/share/xrdp +.RE .TP \fBLogLevel\fR=\fIlevel\fR @@ -409,28 +435,6 @@ Sets the duration(msec). Sound data is not send to client during \fInumber\fR millisecond(s) after close message is sent, when AAC/MP3 is selected. If set to 0, all the data is sent. If not specified, defaults to \fI1000\fR. -.TP -\fBLogFilePath\fR=\fIstring\fR -Directory for storing the chansrv log file -Created if it doesn't exist. -If first character is not a '/', this is relative to $HOME. -.P -.RS -The following substitutions are made in this string:- - %U - Username - %u - Numeric UID - %% - Percent character -.P -This is most useful if you are using NFS-mounted home directories, and -wish to move the chansrv log file to the local disk. - -If this isn't specified, the log file is stored in one of the following -locations :- - - $CHANSRV_LOG_PATH - - $XDG_DATA_HOME/xrdp - - $HOME/.local/share/xrdp -.RE - .SH "SESSIONS VARIABLES" All entries in the \fB[SessionVariables]\fR section are set as environment variables in the user's session. diff --git a/sesman/chansrv/chansrv_config.c b/sesman/chansrv/chansrv_config.c index 6a0f56d249..4535b5cc9e 100644 --- a/sesman/chansrv/chansrv_config.c +++ b/sesman/chansrv/chansrv_config.c @@ -244,7 +244,35 @@ read_config_chansrv(log_func_t logmsg, { cfg->msec_do_not_send = strtoul(value, NULL, 0); } - else if (g_strcasecmp(name, "LogFilePath") == 0) + } + + return error; +} + +/***************************************************************************//** + * Reads the config values we need from the [ChansrvLogging] section + * + * @param logmsg Function to use to log messages + * @param names List of definitions in the section + * @params values List of corresponding values for the names + * @params cfg Pointer to structure we're filling in + * + * @return 0 for success + */ +static int +read_config_chansrv_logging(log_func_t logmsg, + struct list *names, struct list *values, + struct config_chansrv *cfg) +{ + int error = 0; + int index; + + for (index = 0; index < names->count; ++index) + { + const char *name = (const char *)list_get_item(names, index); + const char *value = (const char *)list_get_item(values, index); + + if (g_strcasecmp(name, "LogFilePath") == 0) { g_free(cfg->log_file_path); cfg->log_file_path = g_strdup(value); @@ -344,6 +372,12 @@ config_read(int use_logger, const char *sesman_ini) error = read_config_chansrv(logmsg, names, values, cfg); } + if (!error && + file_read_section(fd, "ChansrvLogging", names, values) == 0) + { + error = read_config_chansrv_logging(logmsg, names, values, cfg); + } + list_delete(names); list_delete(values); } @@ -391,7 +425,7 @@ config_dump(struct config_chansrv *config) g_writeln(" Nautilus 3 Flist Format: %s", g_bool2text(config->use_nautilus3_flist_format)); g_writeln(" LogFilePath : %s", - (config->log_file_path) ? config->log_file_path : ""); + (config->log_file_path[0]) ? config->log_file_path : ""); } /******************************************************************************/ diff --git a/sesman/chansrv/chansrv_config.h b/sesman/chansrv/chansrv_config.h index b089021f11..621e036fb8 100644 --- a/sesman/chansrv/chansrv_config.h +++ b/sesman/chansrv/chansrv_config.h @@ -51,7 +51,7 @@ struct config_chansrv /** Do net send sound data afer SNDC_CLOSE is sent. unit is millisecond, setting from sesman.ini */ unsigned int msec_do_not_send; - /** LogFilePath from sesman.ini */ + /** LogFilePath from sesman.ini ([ChansrvLogging]) */ char *log_file_path; }; diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index 660ba37cfb..cd49a148ec 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -191,11 +191,6 @@ FileUmask=077 #SoundNumSilentFramesAAC=4 #SoundNumSilentFramesMP3=2 #SoundMsecDoNotSend=1000 -; Log file path -; Set this to move the log file away from its default location. You may want -; to do this for (e.g.) NFS-mounted home directories -; See sesman.ini(5) for the format of this parameter -#LogFilePath=/run/user/%u/xrdp [ChansrvLogging] ; Note: one log file is created per display and the LogFile config value @@ -209,6 +204,11 @@ EnableSyslog=true #EnableConsole=false #ConsoleLevel=INFO #EnableProcessId=false +; Log file path +; Set this to move the log file away from its default location. You may want +; to do this for (e.g.) NFS-mounted home directories +; See sesman.ini(5) for the format of this parameter +#LogFilePath=/run/user/%u/xrdp [ChansrvLoggingPerLogger] ; Note: per logger configuration is only used if xrdp is built with