diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am index 4b0154fac..70fdde361 100644 --- a/sesman/chansrv/Makefile.am +++ b/sesman/chansrv/Makefile.am @@ -10,7 +10,8 @@ AM_CPPFLAGS = \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \ -I$(top_srcdir)/sesman/libsesman \ - -I$(top_srcdir)/common + -I$(top_srcdir)/common \ + -I$(top_srcdir)/libipm CHANSRV_EXTRA_LIBS = diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 2cd8cf0ae..e890febcc 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -45,6 +45,9 @@ #include "xrdp_sockets.h" #include "audin.h" +#include "scp.h" +#include "scp_sync.h" + #include "ms-rdpbcgr.h" #define MAX_PATH 260 @@ -1763,6 +1766,54 @@ run_exec(void) return 0; } +/*****************************************************************************/ +/** + * Make sure XRDP_SOCKET_PATH exists + * + * We can't do anything without XRDP_SOCKET_PATH existing. + * + * Normally this is done by sesman before chansrv starts. If we're running + * standalone however (i.e. with x11vnc) this won't be done. We don't have the + * privilege to create the directory, so we have to ask sesman to do it + * for us. + */ +static int +chansrv_create_xrdp_socket_path(void) +{ + char xrdp_socket_path[XRDP_SOCKETS_MAXPATH]; + int rv = 1; + + /* Use our UID to qualify XRDP_SOCKET_PATH */ + g_snprintf(xrdp_socket_path, sizeof(xrdp_socket_path), + XRDP_SOCKET_PATH, g_getuid()); + + if (g_directory_exist(xrdp_socket_path)) + { + rv = 0; + } + else + { + LOG(LOG_LEVEL_INFO, "%s doesn't exist - asking sesman to create it", + xrdp_socket_path); + + struct trans *t = NULL; + + if (!(t = scp_connect(g_cfg->listen_port, "xrdp-chansrv", g_is_term))) + { + LOG(LOG_LEVEL_ERROR, "Can't connect to sesman"); + } + else if (scp_sync_uds_login_request(t) == 0 && + scp_sync_create_sockdir_request(t) == 0) + { + rv = 0; + (void)scp_send_close_connection_request(t); + } + trans_delete(t); + } + + return rv; +} + /*****************************************************************************/ int main(int argc, char **argv) @@ -1855,6 +1906,13 @@ main(int argc, char **argv) } LOG_DEVEL(LOG_LEVEL_INFO, "main: app started pid %d(0x%8.8x)", pid, pid); + + if (chansrv_create_xrdp_socket_path() != 0) + { + main_cleanup(); + return 1; + } + /* set up signal handler */ g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ diff --git a/sesman/chansrv/chansrv_config.c b/sesman/chansrv/chansrv_config.c index 57a106728..1d37b380a 100644 --- a/sesman/chansrv/chansrv_config.c +++ b/sesman/chansrv/chansrv_config.c @@ -72,6 +72,61 @@ log_to_stdout(const enum logLevels lvl, const char *msg, ...) return LOG_STARTUP_OK; } +/***************************************************************************//** + * Reads the config values we need from the [Globals] 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_globals(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); + + char unrecognised[256]; + if (g_strcasecmp(name, "ListenPort") == 0) + { + char *listen_port = strdup(value); + if (listen_port == NULL) + { + LOG(LOG_LEVEL_WARNING, + "Can't allocate config memory for ListenPort"); + } + else + { + g_free(cfg->listen_port); + cfg->listen_port = listen_port; + } + } + if (g_strcasecmp(name, "RestrictInboundClipboard") == 0) + { + cfg->restrict_inbound_clipboard = + sesman_clip_restrict_string_to_bitmask( + value, unrecognised, sizeof(unrecognised)); + if (unrecognised[0] != '\0') + { + LOG(LOG_LEVEL_WARNING, + "Unrecognised tokens parsing 'RestrictInboundClipboard' %s", + unrecognised); + } + } + } + + return error; +} + /***************************************************************************//** * Reads the config values we need from the [Security] section * @@ -208,6 +263,7 @@ new_config(void) } else { + cfg->listen_port = NULL; cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT; cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD; cfg->restrict_inbound_clipboard = DEFAULT_RESTRICT_INBOUND_CLIPBOARD; @@ -252,6 +308,11 @@ config_read(int use_logger, const char *sesman_ini) names->auto_free = 1; values->auto_free = 1; + if (!error && file_read_section(fd, "Globals", names, values) == 0) + { + error = read_config_globals(logmsg, names, values, cfg); + } + if (!error && file_read_section(fd, "Security", names, values) == 0) { error = read_config_security(logmsg, names, values, cfg); @@ -282,9 +343,12 @@ config_read(int use_logger, const char *sesman_ini) void config_dump(struct config_chansrv *config) { + char buf[256]; + g_writeln("Global configuration:"); + g_writeln(" xrdp-sesman ListenPort: %s", + (config->listen_port) ? config->listen_port : ""); - char buf[256]; g_writeln("\nSecurity configuration:"); sesman_clip_restrict_mask_to_string( config->restrict_outbound_clipboard, @@ -311,6 +375,7 @@ config_free(struct config_chansrv *cc) { if (cc != NULL) { + g_free(cc->listen_port); g_free(cc->fuse_mount_name); g_free(cc); } diff --git a/sesman/chansrv/chansrv_config.h b/sesman/chansrv/chansrv_config.h index 7a5fbe4c9..58bd6cbea 100644 --- a/sesman/chansrv/chansrv_config.h +++ b/sesman/chansrv/chansrv_config.h @@ -23,6 +23,9 @@ struct config_chansrv { + /** sesman listening port */ + char *listen_port; + /** Whether the FUSE mount is enabled or not */ int enable_fuse_mount;