Introduce instance_name field into xrdp.ini and xrdp-sesrun, along with
the N policy in sesman.ini, allowing xrdp sessions to be tagged with an instance name to enable persistent association with a specific xrdp instance, to allow experiences where users reconnect to specific sessions based on e.g. the xrdp listening port used.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
;
|
||||
|
||||
+23
-6
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -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 <type> Default:%s\n", DEFAULT_SESSION_TYPE);
|
||||
g_printf(" -D <directory> Default: $HOME\n"
|
||||
" -S <shell> Default: Defined window manager\n"
|
||||
" -N <instance-name> Default: Empty\n"
|
||||
" -p <password> TESTING ONLY - DO NOT USE IN PRODUCTION\n"
|
||||
" -F <file-descriptor> Read password from this file descriptor\n"
|
||||
" -c <sesman_ini> 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);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
|
||||
Reference in New Issue
Block a user