diff --git a/docs/man/xrdp-sesman.8.in b/docs/man/xrdp-sesman.8.in index f475d4d4..d90251db 100644 --- a/docs/man/xrdp-sesman.8.in +++ b/docs/man/xrdp-sesman.8.in @@ -4,7 +4,16 @@ xrdp\-sesman \- \fBxrdp\fR(8) session manager .SH "SYNTAX" .B xrdp\-sesman -.RB [ \-\-nodaemon | \-\-kill | \-\-help ] +\-\-kill +.br +.B xrdp\-sesman +\-\-help +.br +.B xrdp\-sesman +\-\-version +.br +.B xrdp\-sesman +[ \-\-nodaemon ] [ --config /path/to/sesman.ini ] .SH "DESCRIPTION" \fBxrdp\-sesman\fR is \fBxrdp\fR(8) session manager. @@ -13,15 +22,28 @@ It manages user sessions by authenticating the user and starting the appropriate .SH "OPTIONS" .TP -\fB\-n\fR, \fB\-\-nodaemon\fR -Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon. -.TP \fB\-k\fR, \fB\-\-kill\fR Kills running \fBxrdp\-sesman\fR daemon. .TP \fB\-h\fR, \fB\-\-help\fR Output help information and exit. - +.TP +\fB\-v\fR, \fB\-\-version\fR +Output version information and exit. +.TP +\fB\-n\fR, \fB\-\-nodaemon\fR +Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon. +.TP +\fB\-c\fR, \fB\-\-config\fR +Specify a path to a different \fIsesman.ini\fR file. This option is intended +to be used primarily for testing or for unusual configurations. +.P +.RS +If you use this option, be aware that you will have to have a +\fB@sysconfdir@/xrdp/sesman.ini\fR in place too, as a few elements of +the system (notably \fBxrdp(8)\fR and \fBxrdp\-chansrv(8)\fR) will want +to read it. +.RE .SH "FILES" @bindir@/xrdp\-sesman .br diff --git a/docs/man/xrdp-sesrun.8.in b/docs/man/xrdp-sesrun.8.in index 0e06f878..4cf2e2b4 100644 --- a/docs/man/xrdp-sesrun.8.in +++ b/docs/man/xrdp-sesrun.8.in @@ -1,10 +1,10 @@ .TH "xrdp\-sesrun" "8" "@PACKAGE_VERSION@" "xrdp team" "" .SH "NAME" -xrdp\-sesrun \- \fBsesman\fR(8) session launcher +xrdp\-sesrun \- \fBxrdp-sesman\fR(8) session launcher .SH "SYNTAX" .B xrdp\-sesrun -.I server username password width height bpp +.I [ -C /path/to/sesman.ini ] server username password width height bpp code .SH "DESCRIPTION" \fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8). @@ -12,6 +12,10 @@ xrdp\-sesrun \- \fBsesman\fR(8) session launcher This is a tool useful for testing, it simply behaves like xrdp when some user logs in a new session and authenticates, thus starting a new session. .SH "OPTIONS" +.TP +.I \-\-config +(Optional) Specify a path to a different \fIsesman.ini\fR file. + .TP .I server Server on which sesman is running @@ -30,11 +34,16 @@ Screen height .TP .I bpp Session color depth +.TP +.I code +Session type (0 for Xvnc, 10 for X11RDP, 20 for Xorg) .SH "FILES" @bindir@/xrdp\-sesman .br @bindir@/xrdp\-sesrun +.br +@sysconfdir@/xrdp/sesman.ini .SH "AUTHORS" Jay Sorg diff --git a/sesman/config.c b/sesman/config.c index c508dfa3..5b53ffd7 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -34,61 +34,17 @@ #include "sesman.h" #include "log.h" - - -/******************************************************************************/ -int -config_read(struct config_sesman *cfg) -{ - int fd; - struct list *sec; - struct list *param_n; - struct list *param_v; - char cfg_file[256]; - - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - - if (-1 == fd) - { - return 1; - } - - g_memset(cfg, 0, sizeof(struct config_sesman)); - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); - param_n = list_create(); - param_n->auto_free = 1; - param_v = list_create(); - param_v->auto_free = 1; - - /* read global config */ - config_read_globals(fd, cfg, param_n, param_v); - - /* read Xvnc/X11rdp/Xorg parameter list */ - config_read_vnc_params(fd, cfg, param_n, param_v); - config_read_rdp_params(fd, cfg, param_n, param_v); - config_read_xorg_params(fd, cfg, param_n, param_v); - - /* read security config */ - config_read_security(fd, &(cfg->sec), param_n, param_v); - - /* read session config */ - config_read_sessions(fd, &(cfg->sess), param_n, param_v); - - config_read_session_variables(fd, cfg, param_n, param_v); - - /* cleanup */ - list_delete(sec); - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return 0; -} - -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [global] configuration section + * @param file configuration file descriptor + * @param cf pointer to a config struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_globals(int file, struct config_sesman *cf, struct list *param_n, struct list *param_v) { @@ -205,8 +161,17 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n, return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Security] configuration section + * @param file configuration file descriptor + * @param sc pointer to a config_security struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_security(int file, struct config_security *sc, struct list *param_n, struct list *param_v) @@ -273,8 +238,17 @@ config_read_security(int file, struct config_security *sc, return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Sessions] configuration section + * @param file configuration file descriptor + * @param ss pointer to a config_sessions struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_sessions(int file, struct config_sessions *se, struct list *param_n, struct list *param_v) { @@ -360,8 +334,17 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n, return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [X11rdp] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -383,8 +366,17 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n, return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Xorg] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_xorg_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -407,8 +399,17 @@ config_read_xorg_params(int file, struct config_sesman *cs, return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Xvnc] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -431,7 +432,7 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n, } /******************************************************************************/ -int +static int config_read_session_variables(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -458,6 +459,67 @@ config_read_session_variables(int file, struct config_sesman *cs, return 0; } +/******************************************************************************/ +struct config_sesman * +config_read(const char *sesman_ini) +{ + struct config_sesman *cfg; + int all_ok = 0; + + if ((cfg = g_new0(struct config_sesman, 1)) != NULL) + { + if ((cfg->sesman_ini = g_strdup(sesman_ini)) != NULL) + { + int fd; + if ((fd = g_file_open(cfg->sesman_ini)) != -1) + { + struct list *sec; + struct list *param_n; + struct list *param_v; + sec = list_create(); + sec->auto_free = 1; + file_read_sections(fd, sec); + param_n = list_create(); + param_n->auto_free = 1; + param_v = list_create(); + param_v->auto_free = 1; + + /* read global config */ + config_read_globals(fd, cfg, param_n, param_v); + + /* read Xvnc/X11rdp/Xorg parameter list */ + config_read_vnc_params(fd, cfg, param_n, param_v); + config_read_rdp_params(fd, cfg, param_n, param_v); + config_read_xorg_params(fd, cfg, param_n, param_v); + + /* read security config */ + config_read_security(fd, &(cfg->sec), param_n, param_v); + + /* read session config */ + config_read_sessions(fd, &(cfg->sess), param_n, param_v); + + config_read_session_variables(fd, cfg, param_n, param_v); + + /* cleanup */ + list_delete(sec); + list_delete(param_v); + list_delete(param_n); + g_file_close(fd); + all_ok = 1; + } + } + } + + if (!all_ok) + { + config_free(cfg); + cfg = NULL; + } + + return cfg; +} + +/******************************************************************************/ void config_dump(struct config_sesman *config) { @@ -468,6 +530,7 @@ config_dump(struct config_sesman *config) sc = &(config->sec); /* Global sesman configuration */ + g_writeln("Filename: %s", config->sesman_ini); g_writeln("Global configuration:"); g_writeln(" ListenAddress: %s", config->listen_address); g_writeln(" ListenPort: %s", config->listen_port); @@ -567,16 +630,21 @@ config_dump(struct config_sesman *config) } } +/******************************************************************************/ void config_free(struct config_sesman *cs) { - g_free(cs->default_wm); - g_free(cs->reconnect_sh); - g_free(cs->auth_file_path); - list_delete(cs->rdp_params); - list_delete(cs->vnc_params); - list_delete(cs->xorg_params); - list_delete(cs->env_names); - list_delete(cs->env_values); - g_free(cs); + if (cs != NULL) + { + g_free(cs->sesman_ini); + g_free(cs->default_wm); + g_free(cs->reconnect_sh); + g_free(cs->auth_file_path); + list_delete(cs->rdp_params); + list_delete(cs->vnc_params); + list_delete(cs->xorg_params); + list_delete(cs->env_names); + list_delete(cs->env_values); + g_free(cs); + } } diff --git a/sesman/config.h b/sesman/config.h index d465687f..4e254489 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -186,6 +186,12 @@ struct config_sessions */ struct config_sesman { + /** + * @var sesman_ini + * @brief File that these parameters are read from + */ + char *sesman_ini; + /** * @var listen_address * @brief Listening address @@ -267,100 +273,15 @@ struct config_sesman /** * * @brief Reads sesman configuration - * @param cfg pointer to configuration object to be replaced - * @return 0 on success, 1 on failure + * @param sesman_ini Name of configuration file to read + * @return configuration on success, NULL on failure + * + * @post pass return value to config_free() to prevent memory leaks * */ -int -config_read(struct config_sesman* cfg); +struct config_sesman* +config_read(const char *sesman_ini); -/** - * - * @brief Reads sesman [global] configuration section - * @param file configuration file descriptor - * @param cf pointer to a config struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_globals(int file, struct config_sesman* cf, - struct list* param_n, struct list* param_v); - -/** - * - * @brief Reads sesman [Security] configuration section - * @param file configuration file descriptor - * @param sc pointer to a config_security struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_security(int file, struct config_security* sc, - struct list* param_n, struct list* param_v); - -/** - * - * @brief Reads sesman [Sessions] configuration section - * @param file configuration file descriptor - * @param ss pointer to a config_sessions struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_sessions(int file, struct config_sessions* ss, - struct list* param_n, struct list* param_v); - -/** - * - * @brief Reads sesman [X11rdp] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -/** - * - * @brief Reads sesman [Xorg] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_xorg_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -/** - * - * @brief Reads sesman [Xvnc] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -int -config_read_session_variables(int file, struct config_sesman *cs, - struct list *param_n, struct list *param_v); /** * * @brief Dumps configuration @@ -370,6 +291,12 @@ config_read_session_variables(int file, struct config_sesman *cs, void config_dump(struct config_sesman *config); +/** + * + * @brief Frees configuration allocated by config_read() + * @param pointer to a config_sesman struct (may be NULL) + * + */ void config_free(struct config_sesman *cs); diff --git a/sesman/sesman.c b/sesman/sesman.c index bd12702b..6713de67 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -28,7 +28,19 @@ #include #endif +#include + #include "sesman.h" +#include "xrdp_configure_options.h" + +struct sesman_startup_params +{ + const char *sesman_ini; + int kill; + int no_daemon; + int help; + int version; +}; int g_sck; int g_pid; @@ -37,8 +49,101 @@ struct config_sesman *g_cfg; /* defined in config.h */ tintptr g_term_event = 0; +/*****************************************************************************/ +/** + * @brief looks for a case-insensitive match of a string in a list + * @param candidate String to match + * @param ... NULL-terminated list of strings to compare the candidate with + * @return !=0 if the candidate is found in the list + */ +static int nocase_matches(const char *candidate, ...) +{ + va_list vl; + const char *member; + int result = 0; + + va_start(vl, candidate); + while ((member = va_arg(vl, const char *)) != NULL) + { + if (g_strcasecmp(candidate, member) == 0) + { + result = 1; + break; + } + } + + va_end(vl); + return result; +} + +/*****************************************************************************/ +/** + * + * @brief Command line argument parser + * @param[in] argc number of command line arguments + * @param[in] argv pointer array of commandline arguments + * @param[out] sesman_startup_params Returned startup parameters + * @return 0 on success, n on nth argument is unknown + * + */ +static int +sesman_process_params(int argc, char **argv, + struct sesman_startup_params *startup_params) +{ + int index; + const char *option; + const char *value; + + index = 1; + + while (index < argc) + { + option = argv[index]; + + if (index + 1 < argc) + { + value = argv[index + 1]; + } + else + { + value = ""; + } + + if (nocase_matches(option, "-help", "--help", "-h", NULL)) + { + startup_params->help = 1; + } + else if (nocase_matches(option, "-kill", "--kill", "-k", NULL)) + { + startup_params->kill = 1; + } + else if (nocase_matches(option, "-nodaemon", "--nodaemon", "-n", + "-nd", "--nd", "-ns", "--ns", NULL)) + { + startup_params->no_daemon = 1; + } + else if (nocase_matches(option, "-v", "--version", NULL)) + { + startup_params->version = 1; + } + else if (nocase_matches(option, "-c", "--config", NULL)) + { + index++; + startup_params->sesman_ini = value; + } + else /* unknown option */ + { + return index; + } + + index++; + } + + return 0; +} + /******************************************************************************/ -int sesman_listen_test(struct config_sesman *cfg) +static int sesman_listen_test(struct config_sesman *cfg) { int error; int sck; @@ -82,7 +187,7 @@ int sesman_listen_test(struct config_sesman *cfg) * @brief Starts sesman main loop * */ -int +static int sesman_main_loop(void) { int in_sck; @@ -177,110 +282,142 @@ sesman_main_loop(void) return rv; } -/******************************************************************************/ -void -print_usage(int retcode) +/*****************************************************************************/ +static void +print_version(void) { - g_printf("xrdp-sesman - xrdp session manager\n\n"); - g_printf("Usage: xrdp-sesman [options]\n"); - g_printf(" -n, --nodaemon run as foreground process\n"); - g_printf(" -k, --kill kill running xrdp-sesman\n"); - g_printf(" -h, --help show this help\n"); - g_deinit(); - g_exit(retcode); + g_writeln("xrdp-sesman %s", PACKAGE_VERSION); + g_writeln(" The xrdp session manager"); + g_writeln(" Copyright (C) 2004-2020 Jay Sorg, " + "Neutrino Labs, and all contributors."); + g_writeln(" See https://github.com/neutrinolabs/xrdp for more information."); + g_writeln("%s", ""); + +#if defined(XRDP_CONFIGURE_OPTIONS) + g_writeln(" Configure options:"); + g_writeln("%s", XRDP_CONFIGURE_OPTIONS); +#endif } +/******************************************************************************/ +static void +print_help(void) +{ + g_printf("Usage: xrdp-sesman [options]\n"); + g_printf(" -k, --kill shut down xrdp-sesman\n"); + g_printf(" -h, --help show help\n"); + g_printf(" -v, --version show version\n"); + g_printf(" -n, --nodaemon don't fork into background\n"); + g_printf(" -c, --config specify new path to sesman.ini\n"); + g_deinit(); +} + +/******************************************************************************/ +static int +kill_running_sesman(const char *pid_file) +{ + int error; + int fd; + int pid; + char pid_s[32] = {0}; + + /* check if sesman is running */ + if (!g_file_exist(pid_file)) + { + g_printf("sesman is not running (pid file not found - %s)\n", pid_file); + g_deinit(); + return 1; + } + + fd = g_file_open(pid_file); + + if (-1 == fd) + { + g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); + return 1; + } + + error = g_file_read(fd, pid_s, sizeof(pid_s) - 1); + + if (-1 == error) + { + g_printf("error reading pid file: %s\n", g_get_strerror()); + g_file_close(fd); + g_deinit(); + return 1; + } + + g_file_close(fd); + pid = g_atoi(pid_s); + + error = g_sigterm(pid); + + if (0 != error) + { + g_printf("error killing sesman: %s\n", g_get_strerror()); + } + else + { + g_file_delete(pid_file); + } + + g_deinit(); + return error; +} /******************************************************************************/ int main(int argc, char **argv) { - int fd; - enum logReturns log_error; int error; - int daemon = 1; - int pid; - char pid_s[32]; + enum logReturns log_error; char text[256]; char pid_file[256]; - char cfg_file[256]; + char default_sesman_ini[256]; + struct sesman_startup_params startup_params = {0}; + int errored_argc; + int daemon; g_init("xrdp-sesman"); g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + g_snprintf(default_sesman_ini, 255, "%s/sesman.ini", XRDP_CFG_PATH); - if (1 == argc) + startup_params.sesman_ini = default_sesman_ini; + + errored_argc = sesman_process_params(argc, argv, &startup_params); + if (errored_argc > 0) { - /* start in daemon mode if no cli options */ - daemon = 1; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || - (0 == g_strcasecmp(argv[1], "-nodaemon")) || - (0 == g_strcasecmp(argv[1], "-n")) || - (0 == g_strcasecmp(argv[1], "-ns")))) - { - /* starts sesman not daemonized */ - g_printf("starting sesman in foreground...\n"); - daemon = 0; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || - (0 == g_strcasecmp(argv[1], "-help")) || - (0 == g_strcasecmp(argv[1], "-h")))) - { - print_usage(0); - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || - (0 == g_strcasecmp(argv[1], "-kill")) || - (0 == g_strcasecmp(argv[1], "-k")))) - { - /* killing running sesman */ - /* check if sesman is running */ - if (!g_file_exist(pid_file)) - { - g_printf("sesman is not running (pid file not found - %s)\n", pid_file); - g_deinit(); - g_exit(1); - } - - fd = g_file_open(pid_file); - - if (-1 == fd) - { - g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); - return 1; - } - - g_memset(pid_s, 0, sizeof(pid_s)); - error = g_file_read(fd, pid_s, 31); - - if (-1 == error) - { - g_printf("error reading pid file: %s\n", g_get_strerror()); - g_file_close(fd); - g_deinit(); - g_exit(error); - } - - g_file_close(fd); - pid = g_atoi(pid_s); - - error = g_sigterm(pid); - - if (0 != error) - { - g_printf("error killing sesman: %s\n", g_get_strerror()); - } - else - { - g_file_delete(pid_file); - } + print_version(); + g_writeln("%s", ""); + print_help(); + g_writeln("%s", ""); + g_writeln("Unknown option: %s", argv[errored_argc]); g_deinit(); - g_exit(error); + g_exit(1); } - else + + if (startup_params.help) { - /* there's something strange on the command line */ - g_printf("Error: invalid command line arguments\n\n"); - print_usage(1); + print_help(); + g_exit(0); + } + + if (startup_params.version) + { + print_version(); + g_exit(0); + } + + + if (startup_params.kill) + { + g_exit(kill_running_sesman(pid_file)); + } + + daemon = !startup_params.no_daemon; + if (!daemon) + { + g_printf("starting sesman in foreground...\n"); } if (g_file_exist(pid_file)) @@ -294,33 +431,23 @@ main(int argc, char **argv) } /* reading config */ - g_cfg = g_new0(struct config_sesman, 1); - - if (0 == g_cfg) + if ((g_cfg = config_read(startup_params.sesman_ini)) == NULL) { - g_printf("error creating config: quitting.\n"); + g_printf("error reading config %s: %s\nquitting.\n", + startup_params.sesman_ini, g_get_strerror()); g_deinit(); g_exit(1); } - //g_cfg->log.fd = -1; /* don't use logging before reading its config */ - if (0 != config_read(g_cfg)) - { - g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); - g_deinit(); - g_exit(1); - } - - /* not to spit on the console, show config summary only when running in foreground */ + /* not to spit on the console, show config summary only when running + * in foreground */ if (!daemon) { config_dump(g_cfg); } - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* starting logging subsystem */ - log_error = log_start(cfg_file, "xrdp-sesman"); + log_error = log_start(startup_params.sesman_ini, "xrdp-sesman"); if (log_error != LOG_STARTUP_OK) { @@ -338,11 +465,13 @@ main(int argc, char **argv) break; } + config_free(g_cfg); g_deinit(); g_exit(1); } LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__); + LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini); LOG(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address); LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port); LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm); @@ -380,15 +509,16 @@ main(int argc, char **argv) /* start of daemonizing code */ if (sesman_listen_test(g_cfg) != 0) { - LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " "possibly address already in use."); + config_free(g_cfg); g_deinit(); g_exit(1); } if (0 != g_fork()) { + config_free(g_cfg); g_deinit(); g_exit(0); } @@ -415,7 +545,8 @@ main(int argc, char **argv) if (daemon) { /* writing pid file */ - fd = g_file_open(pid_file); + char pid_s[32]; + int fd = g_file_open(pid_file); if (-1 == fd) { @@ -423,6 +554,7 @@ main(int argc, char **argv) "error opening pid file[%s]: %s", pid_file, g_get_strerror()); log_end(); + config_free(g_cfg); g_deinit(); g_exit(1); } @@ -468,6 +600,7 @@ main(int argc, char **argv) log_end(); } + config_free(g_cfg); g_deinit(); g_exit(error); return 0; diff --git a/sesman/sig.c b/sesman/sig.c index d4c8435f..3d56298c 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -67,7 +67,6 @@ sig_sesman_reload_cfg(int sig) { int error; struct config_sesman *cfg; - char cfg_file[256]; LOG(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); @@ -77,18 +76,9 @@ sig_sesman_reload_cfg(int sig) return; } - cfg = g_new0(struct config_sesman, 1); - - if (0 == cfg) - { - LOG(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); - return; - } - - if (config_read(cfg) != 0) + if ((cfg = config_read(g_cfg->sesman_ini)) == NULL) { LOG(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); - g_free(cfg); return; } @@ -101,10 +91,8 @@ sig_sesman_reload_cfg(int sig) /* replace old config with newly read one */ g_cfg = cfg; - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* start again logging subsystem */ - error = log_start(cfg_file, "xrdp-sesman"); + error = log_start(g_cfg->sesman_ini, "xrdp-sesman"); if (error != LOG_STARTUP_OK) { diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index 8a132a06..c0fd98b2 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -35,13 +35,13 @@ #define PACKAGE_VERSION "???" #endif -struct config_sesman g_cfg; /* config.h */ +struct config_sesman *g_cfg; /* config.h */ /******************************************************************************/ int main(int argc, char **argv) { - int sck; + int sck = -1; int code; int i; int size; @@ -56,21 +56,38 @@ main(int argc, char **argv) char *username; char *password; long data; + const char *sesman_ini; + char default_sesman_ini[256]; + int status = 1; - if (0 != config_read(&g_cfg)) + /* User specified a different config file? */ + if (argc > 2 && (g_strcmp(argv[1], "-C") == 0)) { - g_printf("sesrun: error reading config. quitting.\n"); - return 1; + sesman_ini = argv[2]; + argv += 2; + argc -= 2; + } + else + { + g_snprintf(default_sesman_ini, 255, "%s/sesman.ini", XRDP_CFG_PATH); + sesman_ini = default_sesman_ini; } - if (argc == 1) + if (argc != 8) { g_printf("xrdp session starter v" PACKAGE_VERSION "\n"); g_printf("\nusage:\n"); - g_printf("sesrun \n"); + g_printf("xrdp-sesrun [-C /path/to/sesman.ini] " + " " + " \n"); g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n"); } - else if (argc == 8) + else if ((g_cfg = config_read(sesman_ini)) == NULL) + { + g_printf("xrdp-sesrun: error reading config %s. quitting.\n", + sesman_ini); + } + else { username = argv[2]; password = argv[3]; @@ -86,10 +103,13 @@ main(int argc, char **argv) sck = g_tcp_socket(); if (sck < 0) { - return 1; + g_printf("socket error\n"); } - - if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) + else if (g_tcp_connect(sck, argv[1], g_cfg->listen_port) != 0) + { + g_printf("connect error\n"); + } + else { s_push_layer(out_s, channel_hdr, 8); out_uint16_be(out_s, session_code); /* code */ @@ -125,20 +145,22 @@ main(int argc, char **argv) in_uint16_be(in_s, data); in_uint16_be(in_s, display); g_printf("ok %d display %d\n", (int)data, display); + status = 0; } } } } } - else - { - g_printf("connect error\n"); - } - g_tcp_close(sck); + if (sck >= 0) + { + g_tcp_close(sck); + } free_stream(in_s); free_stream(out_s); } - return 0; + config_free(g_cfg); + + return status; }