diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index b0c6a4a2..35a3a2ad 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -210,6 +210,72 @@ scp_session_set_password(struct SCP_SESSION* s, char* str) return 0; } +/*******************************************************************/ +int +scp_session_set_domain(struct SCP_SESSION* s, char* str) +{ + if (0 == str) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); + return 1; + } + if (0 != s->domain) + { + g_free(s->domain); + } + s->domain = g_strdup(str); + if (0 == s->domain) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); + return 1; + } + return 0; +} + +/*******************************************************************/ +int +scp_session_set_program(struct SCP_SESSION* s, char* str) +{ + if (0 == str) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); + return 1; + } + if (0 != s->program) + { + g_free(s->program); + } + s->program = g_strdup(str); + if (0 == s->program) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); + return 1; + } + return 0; +} + +/*******************************************************************/ +int +scp_session_set_directory(struct SCP_SESSION* s, char* str) +{ + if (0 == str) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); + return 1; + } + if (0 != s->directory) + { + g_free(s->directory); + } + s->directory = g_strdup(str); + if (0 == s->directory) + { + log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); + return 1; + } + return 0; +} + /*******************************************************************/ int scp_session_set_hostname(struct SCP_SESSION* s, char* str) @@ -334,6 +400,24 @@ scp_session_destroy(struct SCP_SESSION* s) s->hostname = 0; } + if (s->domain) + { + g_free(s->domain); + s->domain = 0; + } + + if (s->program) + { + g_free(s->program); + s->program = 0; + } + + if (s->directory) + { + g_free(s->directory); + s->directory = 0; + } + if (s->errstr) { g_free(s->errstr); diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index f30710e3..713f80cc 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -68,6 +68,15 @@ scp_session_set_username(struct SCP_SESSION* s, char* str); int scp_session_set_password(struct SCP_SESSION* s, char* str); +int +scp_session_set_domain(struct SCP_SESSION* s, char* str); + +int +scp_session_set_program(struct SCP_SESSION* s, char* str); + +int +scp_session_set_directory(struct SCP_SESSION* s, char* str); + int scp_session_set_hostname(struct SCP_SESSION* s, char* str); diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 5cd86b96..cb31ca88 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -83,6 +83,9 @@ struct SCP_SESSION SCP_DISPLAY display; char* errstr; struct SCP_MNG_DATA* mng; + char* domain; + char* program; + char* directory; }; struct SCP_DISCONNECTED_SESSION diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index 6611242a..861bf1ce 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -33,7 +33,8 @@ extern struct log_config* s_log; /* client API */ /******************************************************************************/ -enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +enum SCP_CLIENT_STATES_E +scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { tui32 version; tui32 size; @@ -139,7 +140,8 @@ enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SE /* server API */ /******************************************************************************/ -enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) +enum SCP_SERVER_STATES_E +scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) { tui32 version = 0; tui32 size; @@ -151,8 +153,9 @@ enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SES if (!skipVchk) { LOG_DBG(s_log, "[v0:%d] starting connection", __LINE__); - if (0==scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { + c->in_s->end = c->in_s->data + 8; in_uint32_be(c->in_s, version); if (version != 0) { @@ -170,17 +173,18 @@ enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SES in_uint32_be(c->in_s, size); init_stream(c->in_s, 8196); - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size-8)) + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); in_uint16_be(c->in_s, code); if (code == 0 || code == 10) { - session = scp_session_create(); + session = scp_session_create(); if (0 == session) { log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); @@ -228,6 +232,39 @@ enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SES /* bpp */ in_uint16_be(c->in_s, sz); scp_session_set_bpp(session, (tui8)sz); + if (s_check_rem(c->in_s, 2)) + { + /* reading domain */ + in_uint16_be(c->in_s, sz); + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_domain(session, buf); + } + } + if (s_check_rem(c->in_s, 2)) + { + /* reading program */ + in_uint16_be(c->in_s, sz); + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_program(session, buf); + } + } + if (s_check_rem(c->in_s, 2)) + { + /* reading directory */ + in_uint16_be(c->in_s, sz); + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_directory(session, buf); + } + } } else { @@ -240,7 +277,8 @@ enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SES } /******************************************************************************/ -enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d) +enum SCP_SERVER_STATES_E +scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d) { out_uint32_be(c->out_s, 0); /* version */ out_uint32_be(c->out_s, 14); /* size */ @@ -260,7 +298,8 @@ enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_ } /******************************************************************************/ -enum SCP_SERVER_STATES_E scp_v0s_deny_connection(struct SCP_CONNECTION* c) +enum SCP_SERVER_STATES_E +scp_v0s_deny_connection(struct SCP_CONNECTION* c) { out_uint32_be(c->out_s, 0); /* version */ out_uint32_be(c->out_s, 14); /* size */ diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c index 25af2d33..80ed7360 100644 --- a/sesman/libscp/libscp_v1s_mng.c +++ b/sesman/libscp/libscp_v1s_mng.c @@ -36,7 +36,8 @@ static enum SCP_SERVER_STATES_E _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); /* server API */ -enum SCP_SERVER_STATES_E scp_v1s_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +enum SCP_SERVER_STATES_E +scp_v1s_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) { struct SCP_SESSION* session; tui32 ipaddr; diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index 918badc9..ddd5f30f 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -57,14 +57,16 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) if (SCP_SESSION_TYPE_XVNC == s->type) { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(s->width, s->height, s->bpp, s->username, s->password, - data, SESMAN_SESSION_TYPE_XVNC); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory); } else { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(s->width, s->height, s->bpp, s->username, s->password, - data, SESMAN_SESSION_TYPE_XRDP); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory); } } else diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index 49a23af8..fd7eb275 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -112,13 +112,15 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session..."); display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XVNC); + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory); } else { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session..."); display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XRDP); + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory); } e = scp_v1s_connect_new_session(c, display); diff --git a/sesman/session.c b/sesman/session.c index 29caeac4..92224a17 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -42,6 +42,9 @@ static int g_sync_height; static int g_sync_bpp; static char* g_sync_username; static char* g_sync_password; +static char* g_sync_domain; +static char* g_sync_program; +static char* g_sync_directory; static tbus g_sync_data; static tui8 g_sync_type; static int g_sync_result; @@ -256,7 +259,8 @@ session_get_aval_display_from_chain(void) /* called with the main thread */ static int APP_CC session_start_fork(int width, int height, int bpp, char* username, - char* password, tbus data, tui8 type) + char* password, tbus data, tui8 type, char* domain, + char* program, char* directory) { int display; int pid; @@ -340,6 +344,23 @@ session_start_fork(int width, int height, int bpp, char* username, if (x_server_running(display)) { auth_set_env(data); + if (directory != 0) + { + if (directory[0] != 0) + { + g_set_current_dir(directory); + } + } + if (program != 0) + { + if (program[0] != 0) + { + g_execlp3(program, program, 0); + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, + "error starting program %s for user %s - pid %d", + program, username, g_getpid()); + } + } /* try to execute user window manager if enabled */ if (g_cfg->enable_user_wm) { @@ -521,7 +542,8 @@ session_start_fork(int width, int height, int bpp, char* username, and wait till done */ int DEFAULT_CC session_start(int width, int height, int bpp, char* username, char* password, - long data, unsigned char type) + long data, tui8 type, char* domain, char* program, + char* directory) { int display; @@ -533,6 +555,9 @@ session_start(int width, int height, int bpp, char* username, char* password, g_sync_bpp = bpp; g_sync_username = username; g_sync_password = password; + g_sync_domain = domain; + g_sync_program = program; + g_sync_directory = directory; g_sync_data = data; g_sync_type = type; /* set event for main thread to see */ @@ -553,7 +578,8 @@ session_sync_start(void) { g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, g_sync_username, g_sync_password, - g_sync_data, g_sync_type); + g_sync_data, g_sync_type, g_sync_domain, + g_sync_program, g_sync_directory); lock_sync_sem_release(); return 0; } diff --git a/sesman/session.h b/sesman/session.h index c434a104..adc4b083 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -103,7 +103,8 @@ session_get_bydata(char* name, int width, int height, int bpp); */ int DEFAULT_CC session_start(int width, int height, int bpp, char* username, char* password, - tbus data, tui8 type); + long data, tui8 type, char* domain, char* program, + char* directory); /** * diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index e6c4e4d2..bfdfc4f0 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -249,6 +249,18 @@ xrdp_mm_send_login(struct xrdp_mm* self) out_uint16_be(s, self->wm->screen->width); out_uint16_be(s, self->wm->screen->height); out_uint16_be(s, self->wm->screen->bpp); + /* send domain */ + index = g_strlen(self->wm->client_info->domain); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->domain, index); + /* send program / shell */ + index = g_strlen(self->wm->client_info->program); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->program, index); + /* send directory */ + index = g_strlen(self->wm->client_info->directory); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->directory, index); s_mark_end(s); s_pop_layer(s, channel_hdr); out_uint32_be(s, 0); /* version */