diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 03c37b19..dfa3c216 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -43,6 +43,12 @@ */ #define MAX_PEER_ADDRSTRLEN 46 +/** + * Max length of buffer containing an instance name used to + * tag sessions for discrimination on reconnection. + **/ +#define MAX_XRDP_INSTANCE_NAMELEN 80 + /** * Size of buffer including terminator for a socket description, as * returned by g_sck_get_peer_description() diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index 28615665..4664bdd7 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -235,6 +235,8 @@ Alternatively combine one-or-more of the following options \fBD\fR - Sessions are separated by initial display size .HP 4 \fBI\fR - Sessions are separated by IP address +.HP 4 +\fBN\fR - Sessions are separated by an instance name specified on startup .RE .IP diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index 8c4dddf5..d6765c22 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -28,6 +28,15 @@ The options to be specified in the \fB[Globals]\fR section are the following: Specify the port(s) that xrdp should listen on. More instructions and examples can be found within xrdp.ini itself. +.TP +\fBinstance_name\fR=\fI\fR +Specify an arbitrary name for the xrdp instance that can be used to +identify sessions that this xrdp instance started, or which were +spun up with the same name using \fBxrdp-sesrun\fR. When using the +\fBN\fR policy in \fBsesman.ini\fR these sessions are kept distinct +and can be reconnected to by connecting to the respective \fBxrdp\fR +instance. + .TP \fBvmconnect\fR=\fI[true|false]\fR (Hyper-V VMs only). Enables a wider support of security protocols when a diff --git a/libipm/eicp.c b/libipm/eicp.c index efb021c4..9d5c378c 100644 --- a/libipm/eicp.c +++ b/libipm/eicp.c @@ -279,19 +279,21 @@ eicp_send_create_session_request(struct trans *trans, unsigned short height, unsigned char bpp, const char *shell, - const char *directory) + const char *directory, + const char *instance_name) { return libipm_msg_out_simple_send( trans, (int)E_EICP_CREATE_SESSION_REQUEST, - "uyqqyss", + "uyqqysss", display, type, width, height, bpp, shell, - directory); + directory, + instance_name); } /*****************************************************************************/ @@ -304,7 +306,8 @@ eicp_get_create_session_request(struct trans *trans, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory) + const char **directory, + const char **instance_name) { /* Intermediate values */ uint32_t i_display; @@ -315,14 +318,15 @@ eicp_get_create_session_request(struct trans *trans, int rv = libipm_msg_in_parse( trans, - "uyqqyss", + "uyqqysss", &i_display, &i_type, &i_width, &i_height, &i_bpp, shell, - directory); + directory, + instance_name); if (rv == 0) { diff --git a/libipm/eicp.h b/libipm/eicp.h index 392a6907..93e88373 100644 --- a/libipm/eicp.h +++ b/libipm/eicp.h @@ -279,6 +279,7 @@ eicp_send_logout_request(struct trans *trans); * @param bpp Session bits-per-pixel (ignored for Xorg sessions) * @param shell User program to run. May be "" * @param directory Directory to run the program in. May be "" + * @param instance_name Name of xrdp instance. May be "" * @return != 0 for error * * The UID for the session must have been set by a previous call. @@ -298,7 +299,8 @@ eicp_send_create_session_request(struct trans *trans, unsigned short height, unsigned char bpp, const char *shell, - const char *directory); + const char *directory, + const char *instance_name); /** @@ -312,6 +314,7 @@ eicp_send_create_session_request(struct trans *trans, * @param[out] bpp Session bits-per-pixel (ignored for Xorg sessions) * @param[out] shell User program to run. May be "" * @param[out] directory Directory to run the program in. May be "" + * @param[out] instance_name Name of xrdp instance. May be "" * @return != 0 for error * * Returned string pointers are valid until scp_msg_in_reset() is @@ -325,7 +328,8 @@ eicp_get_create_session_request(struct trans *trans, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory); + const char **directory, + const char **instance_name); /** * Send an E_EICP_CREATE_SESSION_RESPONSE diff --git a/libipm/ercp.c b/libipm/ercp.c index a96f5170..b7648fef 100644 --- a/libipm/ercp.c +++ b/libipm/ercp.c @@ -155,14 +155,15 @@ ercp_send_session_announce_event(struct trans *trans, unsigned char bpp, const struct guid *guid, const char *start_ip_addr, - time_t start_time) + time_t start_time, + const char *instance_name) { struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; return libipm_msg_out_simple_send( trans, (int)E_ERCP_SESSION_ANNOUNCE_EVENT, - "uiyqqyBsx", + "uiyqqyBsxs", display, uid, type, @@ -171,7 +172,8 @@ ercp_send_session_announce_event(struct trans *trans, bpp, &guid_descriptor, start_ip_addr, - (int64_t)start_time); + (int64_t)start_time, + instance_name); } /*****************************************************************************/ @@ -186,7 +188,8 @@ ercp_get_session_announce_event(struct trans *trans, unsigned char *bpp, struct guid *guid, const char **start_ip_addr, - time_t *start_time) + time_t *start_time, + const char **instance_name) { /* Intermediate values */ uint32_t i_display; @@ -201,7 +204,7 @@ ercp_get_session_announce_event(struct trans *trans, int rv = libipm_msg_in_parse( trans, - "uiyqqyBsx", + "uiyqqyBsxs", &i_display, &i_uid, &i_type, @@ -210,7 +213,8 @@ ercp_get_session_announce_event(struct trans *trans, &i_bpp, &guid_descriptor, start_ip_addr, - &i_start_time); + &i_start_time, + instance_name); if (rv == 0) { diff --git a/libipm/ercp.h b/libipm/ercp.h index 08f6d53d..3d6b201e 100644 --- a/libipm/ercp.h +++ b/libipm/ercp.h @@ -172,7 +172,8 @@ ercp_msg_in_reset(struct trans *trans); * @param guid Session GUID * @param start_ip_addr Starting IP address of client * @param start_time Session start time - * @return != 0 for error + * @param instance_name Name of xrdp instance + * * @return != 0 for error */ int ercp_send_session_announce_event(struct trans *trans, @@ -184,7 +185,8 @@ ercp_send_session_announce_event(struct trans *trans, unsigned char bpp, const struct guid *guid, const char *start_ip_addr, - time_t start_time); + time_t start_time, + const char *instance_name); /** @@ -202,6 +204,7 @@ ercp_send_session_announce_event(struct trans *trans, * @param[out] guid Session GUID * @param[out] start_ip_addr Starting IP address of client * @param[out] start_time Session start time + * @param[out] instance_name Name of xrdp instance * @return != 0 for error */ int @@ -214,7 +217,8 @@ ercp_get_session_announce_event(struct trans *trans, unsigned char *bpp, struct guid *guid, const char **start_ip_addr, - time_t *start_time); + time_t *start_time, + const char **instance_name); /** diff --git a/libipm/scp.c b/libipm/scp.c index df992417..cb96e034 100644 --- a/libipm/scp.c +++ b/libipm/scp.c @@ -419,18 +419,20 @@ scp_send_create_session_request(struct trans *trans, unsigned short height, unsigned char bpp, const char *shell, - const char *directory) + const char *directory, + const char *instance_name) { return libipm_msg_out_simple_send( trans, (int)E_SCP_CREATE_SESSION_REQUEST, - "yqqyss", + "yqqysss", type, width, height, bpp, shell, - directory); + directory, + instance_name); } /*****************************************************************************/ @@ -442,7 +444,8 @@ scp_get_create_session_request(struct trans *trans, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory) + const char **directory, + const char **instance_name) { /* Intermediate values */ uint8_t i_type; @@ -452,13 +455,14 @@ scp_get_create_session_request(struct trans *trans, int rv = libipm_msg_in_parse( trans, - "yqqyss", + "yqqysss", &i_type, &i_width, &i_height, &i_bpp, shell, - directory); + directory, + instance_name); if (rv == 0) { @@ -743,7 +747,7 @@ scp_send_list_sessions_response( rv = libipm_msg_out_simple_send( trans, (int)E_SCP_LIST_SESSIONS_RESPONSE, - "iiuyqqyxisssx", + "iiuyqqyxisssxs", status, info->sid, info->display, @@ -756,7 +760,8 @@ scp_send_list_sessions_response( info->start_ip_addr, info->client_ip, info->client_name, - (int64_t)info->last_connect_disconnect); + (int64_t)info->last_connect_disconnect, + info->xrdp_instance_name); } return rv; @@ -797,10 +802,11 @@ scp_get_list_sessions_response( char *i_client_ip; char *i_client_name; int64_t i_last_connect_disconnect; + char *i_instance_name; rv = libipm_msg_in_parse( trans, - "iuyqqyxisssx", + "iuyqqyxisssxs", &i_sid, &i_display, &i_type, @@ -812,7 +818,8 @@ scp_get_list_sessions_response( &i_start_ip_addr, &i_client_ip, &i_client_name, - &i_last_connect_disconnect); + &i_last_connect_disconnect, + &i_instance_name); if (rv == 0) { @@ -821,7 +828,8 @@ scp_get_list_sessions_response( unsigned int len = sizeof(struct scp_session_info) + g_strlen(i_start_ip_addr) + 1 + g_strlen(i_client_ip) + 1 + - g_strlen(i_client_name) + 1; + g_strlen(i_client_name) + 1 + + g_strlen(i_instance_name) + 1; if ((p = (struct scp_session_info *)g_malloc(len, 1)) == NULL) { *status = E_SCP_LS_NO_MEMORY; @@ -851,6 +859,7 @@ scp_get_list_sessions_response( COPY_STRING(p->client_ip, i_client_ip); COPY_STRING(p->client_name, i_client_name); p->last_connect_disconnect = i_last_connect_disconnect; + COPY_STRING(p->xrdp_instance_name, i_instance_name); #undef COPY_STRING } } diff --git a/libipm/scp.h b/libipm/scp.h index a0179c64..a9e86b49 100644 --- a/libipm/scp.h +++ b/libipm/scp.h @@ -344,6 +344,7 @@ scp_send_logout_request(struct trans *trans); * @param bpp Session bits-per-pixel (ignored for Xorg sessions) * @param shell User program to run. May be "" * @param directory Directory to run the program in. May be "" + * @param instance_name Name of xrdp instance. May be "" * @return != 0 for error * * Server replies with E_SCP_CREATE_SESSION_RESPONSE @@ -355,7 +356,8 @@ scp_send_create_session_request(struct trans *trans, unsigned short height, unsigned char bpp, const char *shell, - const char *directory); + const char *directory, + const char *instance_name); /** @@ -368,6 +370,7 @@ scp_send_create_session_request(struct trans *trans, * @param[out] bpp Session bits-per-pixel (ignored for Xorg sessions) * @param[out] shell User program to run. May be "" * @param[out] directory Directory to run the program in. May be "" + * @param[out] instance_name Name of xrdp instance. May be "" * @return != 0 for error * * Returned string pointers are valid until scp_msg_in_reset() is @@ -380,7 +383,8 @@ scp_get_create_session_request(struct trans *trans, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory); + const char **directory, + const char **instance_name); /** * Send an E_SCP_CREATE_SESSION_RESPONSE (SCP server) diff --git a/libipm/scp_application_types.h b/libipm/scp_application_types.h index 4b724411..c6ad8aaa 100644 --- a/libipm/scp_application_types.h +++ b/libipm/scp_application_types.h @@ -61,7 +61,8 @@ struct scp_session_info char *start_ip_addr; ///< IP address of starting client char *client_ip; ///< Current client IP char *client_name; ///< Current client name - time_t last_connect_disconnect; ///< Time of last client connect/disconnect + time_t last_connect_disconnect; ///< Time of last client connect/disconnect} + char *xrdp_instance_name; ///< Name of xrdp instance }; /** diff --git a/sesman/ercp_process.c b/sesman/ercp_process.c index cc273437..da42f1d7 100644 --- a/sesman/ercp_process.c +++ b/sesman/ercp_process.c @@ -43,6 +43,7 @@ process_session_announce_event(struct session_item *si) { int rv; const char *start_ip_addr; + const char *instance_name; unsigned int display; rv = ercp_get_session_announce_event(si->sesexec_trans, @@ -54,7 +55,8 @@ process_session_announce_event(struct session_item *si) &si->bpp, &si->guid, &start_ip_addr, - &si->start_time); + &si->start_time, + &instance_name); if (rv == 0) { // We may already know the display we sent sesexec. If we do, @@ -71,6 +73,8 @@ process_session_announce_event(struct session_item *si) { snprintf(si->start_ip_addr, sizeof(si->start_ip_addr), "%s", start_ip_addr); + snprintf(si->xrdp_instance_name, sizeof(si->xrdp_instance_name), + "%s", instance_name); si->display = display; si->state = E_SESSION_RUNNING; diff --git a/sesman/libsesman/sesman_config.c b/sesman/libsesman/sesman_config.c index b90a32df..215aa2da 100644 --- a/sesman/libsesman/sesman_config.c +++ b/sesman/libsesman/sesman_config.c @@ -95,6 +95,7 @@ static const struct bitmask_char policy_bits[] = { SESMAN_CFG_SESS_POLICY_B, 'B' }, { SESMAN_CFG_SESS_POLICY_D, 'D' }, { SESMAN_CFG_SESS_POLICY_I, 'I' }, + { SESMAN_CFG_SESS_POLICY_N, 'N' }, BITMASK_CHAR_END_OF_LIST }; diff --git a/sesman/libsesman/sesman_config.h b/sesman/libsesman/sesman_config.h index 9df48b4f..fa6349ca 100644 --- a/sesman/libsesman/sesman_config.h +++ b/sesman/libsesman/sesman_config.h @@ -42,7 +42,8 @@ enum SESMAN_CFG_SESS_POLICY_BITS SESMAN_CFG_SESS_POLICY_U = (1 << 2), SESMAN_CFG_SESS_POLICY_B = (1 << 3), SESMAN_CFG_SESS_POLICY_D = (1 << 4), - SESMAN_CFG_SESS_POLICY_I = (1 << 5) + SESMAN_CFG_SESS_POLICY_I = (1 << 5), + SESMAN_CFG_SESS_POLICY_N = (1 << 6) }; /** diff --git a/sesman/scp_list.h b/sesman/scp_list.h index e560096f..32907ccf 100644 --- a/sesman/scp_list.h +++ b/sesman/scp_list.h @@ -84,6 +84,7 @@ struct scp_list_item uid_t uid; ///< User char *username; ///< Username from UID (at time of logon) char start_ip_addr[MAX_PEER_ADDRSTRLEN]; + char xrdp_instance_name[MAX_XRDP_INSTANCE_NAMELEN]; ///< Instance name associated with session int is_admin; int create_session_in_progress; ///< Already handling a create_session /// Display allocated for session. This is always valid (>= 0) diff --git a/sesman/scp_process.c b/sesman/scp_process.c index 40b0e820..c6ec60fc 100644 --- a/sesman/scp_process.c +++ b/sesman/scp_process.c @@ -439,6 +439,7 @@ process_create_session_request(struct scp_list_item *sli) unsigned char bpp; const char *shell; const char *directory; + const char *instance_name; struct guid guid; int display = -1; @@ -450,7 +451,8 @@ process_create_session_request(struct scp_list_item *sli) rv = scp_get_create_session_request(sli->client_trans, &type, &width, &height, - &bpp, &shell, &directory); + &bpp, &shell, &directory, + &instance_name); if (rv == 0) { @@ -469,7 +471,7 @@ process_create_session_request(struct scp_list_item *sli) sli->peername, sli->username); s_item = session_list_get_bydata(sli->uid, type, width, height, - bpp, sli->start_ip_addr); + bpp, sli->start_ip_addr, instance_name); if (s_item != NULL) { // Found an existing session @@ -532,7 +534,8 @@ process_create_session_request(struct scp_list_item *sli) sli->sesexec_trans, display, type, width, height, - bpp, shell, directory); + bpp, shell, directory, + instance_name); if (eicp_stat != 0) { diff --git a/sesman/sesexec/eicp_server.c b/sesman/sesexec/eicp_server.c index 9f75ca36..b9fa6384 100644 --- a/sesman/sesexec/eicp_server.c +++ b/sesman/sesexec/eicp_server.c @@ -150,7 +150,8 @@ handle_create_session_request(struct trans *self) status = eicp_get_create_session_request( self, &sp.display, &sp.type, &sp.width, &sp.height, - &sp.bpp, &sp.shell, &sp.directory); + &sp.bpp, &sp.shell, &sp.directory, + &sp.instance_name); if (status == 0) { enum scp_screate_status scp_status = E_SCP_SCREATE_OK; @@ -185,7 +186,8 @@ handle_create_session_request(struct trans *self) sp.bpp, &sp.guid, g_login_info->ip_addr, - session_get_start_time(g_session_data))) != 0) + session_get_start_time(g_session_data), + sp.instance_name)) != 0) { // We failed to tell sesman about the new session. This // probably means sesman has exited in the time between diff --git a/sesman/sesexec/sesexec_discover.c b/sesman/sesexec/sesexec_discover.c index 955d6167..27b35733 100644 --- a/sesman/sesexec/sesexec_discover.c +++ b/sesman/sesexec/sesexec_discover.c @@ -100,7 +100,8 @@ discover_trans_conn_in(struct trans *trans, struct trans *new_trans) sp->bpp, &sp->guid, g_login_info->ip_addr, - session_get_start_time(g_session_data)); + session_get_start_time(g_session_data), + sp->instance_name); // Tell semsan about the last client connect or disconnect if (g_ccp_trans != NULL) diff --git a/sesman/sesexec/session.c b/sesman/sesexec/session.c index de1b99bc..2841552a 100644 --- a/sesman/sesexec/session.c +++ b/sesman/sesexec/session.c @@ -85,6 +85,7 @@ session_data_new(const struct session_parameters *sp) // What string length do we need? string_length += g_strlen(sp->shell) + 1; string_length += g_strlen(sp->directory) + 1; + string_length += g_strlen(sp->instance_name) + 1; struct session_data *sd = (struct session_data *)g_malloc(sizeof(*sd) + string_length, 0); @@ -113,6 +114,7 @@ session_data_new(const struct session_parameters *sp) COPY_STRING(sd->params.shell, sp->shell); COPY_STRING(sd->params.directory, sp->directory); + COPY_STRING(sd->params.instance_name, sp->instance_name); #undef COPY_STRING } diff --git a/sesman/sesexec/session.h b/sesman/sesexec/session.h index 3ad6181f..43808989 100644 --- a/sesman/sesexec/session.h +++ b/sesman/sesexec/session.h @@ -49,6 +49,7 @@ struct session_parameters struct guid guid; const char *shell; // Must not be NULL const char *directory; // Must not be NULL + const char *instance_name; //Must not be NULL }; diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index 653e8861..28e9b0db 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -124,6 +124,7 @@ IdleTimeLimit=0 ; B Sessions are separated by bits-per-pixel ; D Sessions are separated by initial display size ; I Sessions are separated by IP address +; N Sessions are separated by xrdp instance name ; ; The options U and B are always active, and cannot be de-selected. ; diff --git a/sesman/session_list.c b/sesman/session_list.c index 073b8b23..fd11aa5a 100644 --- a/sesman/session_list.c +++ b/sesman/session_list.c @@ -184,7 +184,8 @@ session_list_get_bydata(uid_t uid, unsigned short width, unsigned short height, unsigned char bpp, - const char *ip_addr) + const char *ip_addr, + const char *instance_name) { char policy_str[64]; int policy = g_cfg->sess.policy; @@ -195,6 +196,11 @@ session_list_get_bydata(uid_t uid, ip_addr = ""; } + if (instance_name == NULL) + { + instance_name = ""; + } + if ((policy & SESMAN_CFG_SESS_POLICY_DEFAULT) != 0) { /* Before xrdp v0.9.14, the default @@ -206,11 +212,11 @@ session_list_get_bydata(uid_t uid, config_output_policy_string(policy, policy_str, sizeof(policy_str)); LOG(LOG_LEVEL_DEBUG, - "%s: search policy=%s type=%s U=%d B=%d D=(%dx%d) I=%s", + "%s: search policy=%s type=%s U=%d B=%d D=(%dx%d) I=%s P=%s", __func__, policy_str, SCP_SESSION_TYPE_TO_STR(type), uid, bpp, width, height, - ip_addr); + ip_addr, instance_name); /* 'Separate' policy never matches */ if (policy & SESMAN_CFG_SESS_POLICY_SEPARATE) @@ -229,13 +235,13 @@ session_list_get_bydata(uid_t uid, } LOG(LOG_LEVEL_DEBUG, - "%s: try %p type=%s U=%d B=%d D=(%dx%d) I=%s", + "%s: try %p type=%s U=%d B=%d D=(%dx%d) I=%s N=%s", __func__, si, SCP_SESSION_TYPE_TO_STR(si->type), si->uid, si->bpp, si->start_width, si->start_height, - si->start_ip_addr); + si->start_ip_addr, si->xrdp_instance_name); if (si->type != type) { @@ -274,6 +280,14 @@ session_list_get_bydata(uid_t uid, continue; } + if ((policy & SESMAN_CFG_SESS_POLICY_N) && + g_strcmp(si->xrdp_instance_name, instance_name) != 0) + { + LOG(LOG_LEVEL_DEBUG, + "%s: Instance names don't match for 'N' policy", __func__); + continue; + } + LOG(LOG_LEVEL_DEBUG, "%s: Got match, display=%d", __func__, si->display); return si; @@ -348,11 +362,13 @@ session_list_get_byuid(const uid_t *uid, unsigned int *cnt, unsigned int flags) sess[index].client_ip = g_strdup(si->client_ip); sess[index].client_name = g_strdup(si->client_name); sess[index].last_connect_disconnect = si->last_connect_disconnect; + sess[index].xrdp_instance_name = g_strdup(si->xrdp_instance_name); /* Check for string allocation failures */ if (sess[index].start_ip_addr == NULL || sess[index].client_ip == NULL || - sess[index].client_name == NULL) + sess[index].client_name == NULL || + sess[index].xrdp_instance_name == NULL) { free_session_info_list(sess, *cnt); (*cnt) = 0; @@ -397,6 +413,7 @@ free_session_info_list(struct scp_session_info *sesslist, unsigned int cnt) g_free(sesslist[i].start_ip_addr); g_free(sesslist[i].client_ip); g_free(sesslist[i].client_name); + g_free(sesslist[i].xrdp_instance_name); } } diff --git a/sesman/session_list.h b/sesman/session_list.h index d077a758..744983ff 100644 --- a/sesman/session_list.h +++ b/sesman/session_list.h @@ -71,6 +71,8 @@ struct session_item char client_ip[MAX_PEER_ADDRSTRLEN]; char client_name[INFO_CLIENT_NAME_BYTES_UTF8]; time_t last_connect_disconnect; + char xrdp_instance_name[MAX_XRDP_INSTANCE_NAMELEN]; + /* allow a tag to be specified to distinguish sessions */ }; /** @@ -140,7 +142,8 @@ session_list_get_bydata(uid_t uid, unsigned short width, unsigned short height, unsigned char bpp, - const char *ip_addr); + const char *ip_addr, + const char *instance_name); /** * @brief retrieves session descriptions diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 18e02335..7213bd36 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -166,6 +166,10 @@ print_session(const struct scp_session_info *s) (s->last_connect_disconnect == 0) ? "-\n" : ctime(&s->last_connect_disconnect)); } + if (s->xrdp_instance_name[0] != '\0') + { + printf("\txrdp instance name: %s\n", s->xrdp_instance_name); + } g_free(username); } diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index 3f1ff2ab..1e7564c5 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -103,6 +103,7 @@ struct session_params const char *ip_addr; const char *username; + const char *instance_name; char password[MAX_PASSWORD_LEN + 1]; }; @@ -181,6 +182,7 @@ usage(void) g_printf(" -t Default:%s\n", DEFAULT_SESSION_TYPE); g_printf(" -D Default: $HOME\n" " -S Default: Defined window manager\n" + " -N Default: Empty\n" " -p TESTING ONLY - DO NOT USE IN PRODUCTION\n" " -F Read password from this file descriptor\n" " -c Alternative sesman.ini file\n"); @@ -189,6 +191,8 @@ usage(void) g_printf("\nIf username is omitted, the current user is used.\n" "If username is provided, password is needed.\n" " Password is prompted for if -p or -F are not specified\n"); + g_printf("\nThe instance name is used to associate the session with an xrdp\n" + "\ndaemon tagged with that particular name.\n"); } @@ -297,11 +301,12 @@ parse_program_args(int argc, char *argv[], struct session_params *sp, sp->directory = ""; sp->shell = ""; sp->ip_addr = ""; + sp->instance_name = ""; sp->username = NULL; sp->password[0] = '\0'; - while ((opt = getopt(argc, argv, "g:b:s:t:D:S:p:F:c:")) != -1) + while ((opt = getopt(argc, argv, "g:b:s:t:D:S:p:F:c:N:")) != -1) { switch (opt) { @@ -367,6 +372,10 @@ parse_program_args(int argc, char *argv[], struct session_params *sp, } break; + case 'N': + sp->instance_name = optarg; + break; + case 'c': *sesman_ini = optarg; break; @@ -491,13 +500,14 @@ send_create_session_request(struct trans *t, const struct session_params *sp) { LOG(LOG_LEVEL_DEBUG, "width:%d height:%d bpp:%d code:%d\n" - "directory:\"%s\" shell:\"%s\"", + "directory:\"%s\" shell:\"%s\" instance_name:\"%s\"", sp->width, sp->height, sp->bpp, sp->session_type, - sp->directory, sp->shell); + sp->directory, sp->shell, sp->instance_name); return scp_send_create_session_request( t, sp->session_type, - sp->width, sp->height, sp->bpp, sp->shell, sp->directory); + sp->width, sp->height, sp->bpp, sp->shell, + sp->directory, sp->instance_name); } /**************************************************************************//** diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index 85fb7380..b414b7b9 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -302,6 +302,12 @@ read_xrdp_ini_startup_params(struct xrdp_startup_params *startup_params) } } + if (g_strcasecmp(name, "instance_name") == 0) + { + strlcpy(startup_params->instance_name, val, + sizeof(startup_params->instance_name) - 1); + } + else if (g_strcasecmp(name, "fork") == 0) { if (fork_override == 0) diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index 9bdefde2..3f392a49 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -22,6 +22,11 @@ fork=true ; port=vsock://: port=3389 +; name of the xrdp instance. This can be set to an arbitrary string +; used to distinguish sessions when the "N" policy is activated. +; Defaults to an empty string. +#instance_name= + ; if used inside a Hyper-V VM through vmconnect and bound on vsock, ; turn this on to enable wider security protocol support. #vmconnect=true diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 0a2be674..b9490d04 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -350,7 +350,8 @@ xrdp_mm_create_session(struct xrdp_mm *self) self->wm->screen->height, xserverbpp, self->wm->client_info->program, - self->wm->client_info->directory); + self->wm->client_info->directory, + self->wm->pro_layer->lis_layer->startup_params->instance_name); } return rv; diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 0578c5bf..1c78cf7d 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -761,6 +761,7 @@ struct xrdp_startup_params /* xrdp_ini is not malloc'd and has at least the same lifetime as main() */ const char *xrdp_ini; char port[1024]; + char instance_name[MAX_XRDP_INSTANCE_NAMELEN]; int kill; int no_daemon; int help;