Parameterise the sockdir with the UID of the user
The top level socket directory is now called XRDP_SOCKET_ROOT_PATH. Below that are user-specific directories referred to with the XRDP_SOCKET_PATH macro - this name is hard-coded into xorgxrdp and the audio modules as an environment variable. XRDP_SOCKET_PATH now looks like $XRDP_SOCKET_ROOT_PATH/<uid> XRDP_SOCKET_PATH is only writeable by the user, and readable by the user and the xrdp process.
This commit is contained in:
parent
63235eaafd
commit
675dd77807
@ -21,16 +21,39 @@
|
|||||||
#if !defined(XRDP_SOCKETS_H)
|
#if !defined(XRDP_SOCKETS_H)
|
||||||
#define XRDP_SOCKETS_H
|
#define XRDP_SOCKETS_H
|
||||||
|
|
||||||
/* basename of socket files */
|
/* XRDP_SOCKET_ROOT_PATH must be defined to include this file */
|
||||||
|
#ifdef __cppcheck__
|
||||||
|
/* avoid syntax errors */
|
||||||
|
# define XRDP_SOCKET_ROOT_PATH "/dummy"
|
||||||
|
#elif !defined(XRDP_SOCKET_ROOT_PATH)
|
||||||
|
# error "XRDP_SOCKET_ROOT_PATH must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Buffer size for code for fullpath declarations
|
||||||
|
*
|
||||||
|
* This needs to fit in the sun_path field of a sockaddr_un. POSIX
|
||||||
|
* does not define this size, so the value below is the lower of
|
||||||
|
* the FreeBSD/OpenBSD/NetBSD(104) and Linux(108) values */
|
||||||
|
#define XRDP_SOCKETS_MAXPATH 104
|
||||||
|
|
||||||
|
/* The socketdir is rooted at XRDP_SOCKET_ROOT_PATH. User-specific
|
||||||
|
* sockets live in a user-specific sub-directory of this called
|
||||||
|
* XRDP_SOCKET_PATH. The sub-directory is the UID of the user */
|
||||||
|
#define XRDP_SOCKET_PATH XRDP_SOCKET_ROOT_PATH "/%d"
|
||||||
|
|
||||||
|
/* Sockets in XRDP_SOCKET_ROOT_PATH */
|
||||||
|
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
|
||||||
|
|
||||||
|
/* names of socket files within XRDP_SOCKET_PATH, qualified by
|
||||||
|
* display number */
|
||||||
#define XRDP_CHANSRV_BASE_STR "xrdp_chansrv_socket_%d"
|
#define XRDP_CHANSRV_BASE_STR "xrdp_chansrv_socket_%d"
|
||||||
#define CHANSRV_PORT_OUT_BASE_STR "xrdp_chansrv_audio_out_socket_%d"
|
#define CHANSRV_PORT_OUT_BASE_STR "xrdp_chansrv_audio_out_socket_%d"
|
||||||
#define CHANSRV_PORT_IN_BASE_STR "xrdp_chansrv_audio_in_socket_%d"
|
#define CHANSRV_PORT_IN_BASE_STR "xrdp_chansrv_audio_in_socket_%d"
|
||||||
#define CHANSRV_API_BASE_STR "xrdpapi_%d"
|
#define CHANSRV_API_BASE_STR "xrdpapi_%d"
|
||||||
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d"
|
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d"
|
||||||
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d"
|
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d"
|
||||||
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
|
|
||||||
|
|
||||||
/* fullpath of sockets */
|
/* fullpath declarations */
|
||||||
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR
|
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR
|
||||||
#define CHANSRV_PORT_OUT_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_OUT_BASE_STR
|
#define CHANSRV_PORT_OUT_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_OUT_BASE_STR
|
||||||
#define CHANSRV_PORT_IN_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_IN_BASE_STR
|
#define CHANSRV_PORT_IN_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_IN_BASE_STR
|
||||||
|
@ -312,6 +312,11 @@ to a setuid Xorg executable. However, if a kernel security module (such as
|
|||||||
AppArmor) is used to confine xrdp, \fIno_new_privs\fR may interfere with
|
AppArmor) is used to confine xrdp, \fIno_new_privs\fR may interfere with
|
||||||
transitions between confinement domains.
|
transitions between confinement domains.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fBSessionSockdirGroup\fR=\fIgroup\fR
|
||||||
|
Sets the group owner of the directories containing session sockets. This
|
||||||
|
is normally the GID of the xrdp process so xrdp can connect to user sessions.
|
||||||
|
|
||||||
.SH "X11 SERVER"
|
.SH "X11 SERVER"
|
||||||
Following parameters can be used in the \fB[Xvnc]\fR and
|
Following parameters can be used in the \fB[Xvnc]\fR and
|
||||||
\fB[Xorg]\fR sections.
|
\fB[Xorg]\fR sections.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||||
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
module_LTLIBRARIES = \
|
module_LTLIBRARIES = \
|
||||||
|
25
libipm/scp.c
25
libipm/scp.c
@ -332,14 +332,16 @@ scp_get_sys_login_request(struct trans *trans,
|
|||||||
int
|
int
|
||||||
scp_send_login_response(struct trans *trans,
|
scp_send_login_response(struct trans *trans,
|
||||||
enum scp_login_status login_result,
|
enum scp_login_status login_result,
|
||||||
int server_closed)
|
int server_closed,
|
||||||
|
int uid)
|
||||||
{
|
{
|
||||||
return libipm_msg_out_simple_send(
|
return libipm_msg_out_simple_send(
|
||||||
trans,
|
trans,
|
||||||
(int)E_SCP_LOGIN_RESPONSE,
|
(int)E_SCP_LOGIN_RESPONSE,
|
||||||
"ib",
|
"ibi",
|
||||||
login_result,
|
login_result,
|
||||||
(server_closed != 0)); /* Convert to 0/1 */
|
(server_closed != 0), /* Convert to 0/1 */
|
||||||
|
uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -347,22 +349,33 @@ scp_send_login_response(struct trans *trans,
|
|||||||
int
|
int
|
||||||
scp_get_login_response(struct trans *trans,
|
scp_get_login_response(struct trans *trans,
|
||||||
enum scp_login_status *login_result,
|
enum scp_login_status *login_result,
|
||||||
int *server_closed)
|
int *server_closed,
|
||||||
|
int *uid)
|
||||||
{
|
{
|
||||||
int32_t i_login_result = 0;
|
int32_t i_login_result = 0;
|
||||||
|
int32_t i_uid = 0;
|
||||||
int dummy;
|
int dummy;
|
||||||
|
|
||||||
/* User can pass in NULL for server_closed if they're trying an
|
/* User can pass in NULL for server_closed if they're trying an
|
||||||
* login method like UDS for which all fails are fatal */
|
* login method like UDS for which all fails are fatal. Likewise
|
||||||
|
* they may be uninterested in the uid */
|
||||||
if (server_closed == NULL)
|
if (server_closed == NULL)
|
||||||
{
|
{
|
||||||
server_closed = &dummy;
|
server_closed = &dummy;
|
||||||
}
|
}
|
||||||
|
if (uid == NULL)
|
||||||
|
{
|
||||||
|
uid = &dummy;
|
||||||
|
}
|
||||||
|
|
||||||
int rv = libipm_msg_in_parse(trans, "ib", &i_login_result, server_closed);
|
int rv = libipm_msg_in_parse(trans, "ibi",
|
||||||
|
&i_login_result, server_closed, &i_uid);
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
*login_result = (enum scp_login_status)i_login_result;
|
*login_result = (enum scp_login_status)i_login_result;
|
||||||
|
*uid = i_uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
libipm/scp.h
11
libipm/scp.h
@ -284,12 +284,14 @@ scp_get_sys_login_request(struct trans *trans,
|
|||||||
* @param login_result What happened to the login
|
* @param login_result What happened to the login
|
||||||
* @param server_closed If login fails, whether server has closed connection.
|
* @param server_closed If login fails, whether server has closed connection.
|
||||||
* If not, a retry can be made.
|
* If not, a retry can be made.
|
||||||
|
* @param uid UID for a successful login
|
||||||
* @return != 0 for error
|
* @return != 0 for error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
scp_send_login_response(struct trans *trans,
|
scp_send_login_response(struct trans *trans,
|
||||||
enum scp_login_status login_result,
|
enum scp_login_status login_result,
|
||||||
int server_closed);
|
int server_closed,
|
||||||
|
int uid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an incoming E_SCP_LOGIN_RESPONSE (SCP client)
|
* Parses an incoming E_SCP_LOGIN_RESPONSE (SCP client)
|
||||||
@ -298,12 +300,17 @@ scp_send_login_response(struct trans *trans,
|
|||||||
* @param[out] login_result 0 for success, PAM error code otherwise
|
* @param[out] login_result 0 for success, PAM error code otherwise
|
||||||
* @param[out] server_closed If login fails, whether server has closed
|
* @param[out] server_closed If login fails, whether server has closed
|
||||||
* connection. If not a retry can be made.
|
* connection. If not a retry can be made.
|
||||||
|
* @param[out] uid UID for a successful login
|
||||||
|
*
|
||||||
|
* server_closed and uid can be passed NULL if the caller isn't interested.
|
||||||
|
*
|
||||||
* @return != 0 for error
|
* @return != 0 for error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
scp_get_login_response(struct trans *trans,
|
scp_get_login_response(struct trans *trans,
|
||||||
enum scp_login_status *login_result,
|
enum scp_login_status *login_result,
|
||||||
int *server_closed);
|
int *server_closed,
|
||||||
|
int *uid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an E_SCP_LOGOUT_REQUEST (SCP client)
|
* Send an E_SCP_LOGOUT_REQUEST (SCP client)
|
||||||
|
@ -6,7 +6,7 @@ AM_CPPFLAGS = \
|
|||||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||||
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
||||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||||
-I$(top_srcdir)/sesman/libsesman \
|
-I$(top_srcdir)/sesman/libsesman \
|
||||||
-I$(top_srcdir)/common \
|
-I$(top_srcdir)/common \
|
||||||
|
@ -8,7 +8,7 @@ AM_CPPFLAGS = \
|
|||||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_srcdir)/sesman/libsesman \
|
-I$(top_srcdir)/sesman/libsesman \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
|
@ -1238,7 +1238,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
|
|||||||
static int
|
static int
|
||||||
setup_listen(void)
|
setup_listen(void)
|
||||||
{
|
{
|
||||||
char port[256];
|
char port[XRDP_SOCKETS_MAXPATH];
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (g_lis_trans != 0)
|
if (g_lis_trans != 0)
|
||||||
@ -1248,7 +1248,7 @@ setup_listen(void)
|
|||||||
|
|
||||||
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
|
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
|
||||||
g_lis_trans->is_term = g_is_term;
|
g_lis_trans->is_term = g_is_term;
|
||||||
g_snprintf(port, 255, XRDP_CHANSRV_STR, g_display_num);
|
g_snprintf(port, sizeof(port), XRDP_CHANSRV_STR, g_getuid(), g_display_num);
|
||||||
|
|
||||||
g_lis_trans->trans_conn_in = my_trans_conn_in;
|
g_lis_trans->trans_conn_in = my_trans_conn_in;
|
||||||
error = trans_listen(g_lis_trans, port);
|
error = trans_listen(g_lis_trans, port);
|
||||||
@ -1267,12 +1267,12 @@ setup_listen(void)
|
|||||||
static int
|
static int
|
||||||
setup_api_listen(void)
|
setup_api_listen(void)
|
||||||
{
|
{
|
||||||
char port[256];
|
char port[XRDP_SOCKETS_MAXPATH];
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
|
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
|
||||||
g_api_lis_trans->is_term = g_is_term;
|
g_api_lis_trans->is_term = g_is_term;
|
||||||
g_snprintf(port, 255, CHANSRV_API_STR, g_display_num);
|
g_snprintf(port, sizeof(port), CHANSRV_API_STR, g_getuid(), g_display_num);
|
||||||
g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
|
g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
|
||||||
error = trans_listen(g_api_lis_trans, port);
|
error = trans_listen(g_api_lis_trans, port);
|
||||||
|
|
||||||
|
@ -1894,11 +1894,11 @@ sound_sndsrvr_source_data_in(struct trans *trans)
|
|||||||
static int
|
static int
|
||||||
sound_start_source_listener(void)
|
sound_start_source_listener(void)
|
||||||
{
|
{
|
||||||
char port[1024];
|
char port[XRDP_SOCKETS_MAXPATH];
|
||||||
|
|
||||||
g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
|
g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
|
||||||
g_audio_l_trans_in->is_term = g_is_term;
|
g_audio_l_trans_in->is_term = g_is_term;
|
||||||
g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num);
|
g_snprintf(port, sizeof(port), CHANSRV_PORT_IN_STR, g_getuid(), g_display_num);
|
||||||
g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
|
g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
|
||||||
if (trans_listen(g_audio_l_trans_in, port) != 0)
|
if (trans_listen(g_audio_l_trans_in, port) != 0)
|
||||||
{
|
{
|
||||||
@ -1913,11 +1913,11 @@ sound_start_source_listener(void)
|
|||||||
static int
|
static int
|
||||||
sound_start_sink_listener(void)
|
sound_start_sink_listener(void)
|
||||||
{
|
{
|
||||||
char port[1024];
|
char port[XRDP_SOCKETS_MAXPATH];
|
||||||
|
|
||||||
g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
|
g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
|
||||||
g_audio_l_trans_out->is_term = g_is_term;
|
g_audio_l_trans_out->is_term = g_is_term;
|
||||||
g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num);
|
g_snprintf(port, sizeof(port), CHANSRV_PORT_OUT_STR, g_getuid(), g_display_num);
|
||||||
g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
|
g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
|
||||||
if (trans_listen(g_audio_l_trans_out, port) != 0)
|
if (trans_listen(g_audio_l_trans_out, port) != 0)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#define SESMAN_CFG_SEC_RESTRICT_INBOUND_CLIPBOARD "RestrictInboundClipboard"
|
#define SESMAN_CFG_SEC_RESTRICT_INBOUND_CLIPBOARD "RestrictInboundClipboard"
|
||||||
#define SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL "AllowAlternateShell"
|
#define SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL "AllowAlternateShell"
|
||||||
#define SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES "XorgNoNewPrivileges"
|
#define SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES "XorgNoNewPrivileges"
|
||||||
|
#define SESMAN_CFG_SEC_SESSION_SOCKDIR_GROUP "SessionSockdirGroup"
|
||||||
|
|
||||||
#define SESMAN_CFG_SESSIONS "Sessions"
|
#define SESMAN_CFG_SESSIONS "Sessions"
|
||||||
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
||||||
@ -312,6 +313,7 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
sc->xorg_no_new_privileges = 1;
|
sc->xorg_no_new_privileges = 1;
|
||||||
sc->ts_users = g_strdup("");
|
sc->ts_users = g_strdup("");
|
||||||
sc->ts_admins = g_strdup("");
|
sc->ts_admins = g_strdup("");
|
||||||
|
sc->session_sockdir_group = g_strdup("");
|
||||||
|
|
||||||
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
|
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
|
||||||
|
|
||||||
@ -324,29 +326,25 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
{
|
{
|
||||||
sc->allow_root = g_text2bool(value);
|
sc->allow_root = g_text2bool(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY))
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY))
|
|
||||||
{
|
{
|
||||||
sc->login_retry = g_atoi(value);
|
sc->login_retry = g_atoi(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP))
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP))
|
|
||||||
{
|
{
|
||||||
g_free(sc->ts_users);
|
g_free(sc->ts_users);
|
||||||
sc->ts_users = g_strdup(value);
|
sc->ts_users = g_strdup(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP))
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP))
|
|
||||||
{
|
{
|
||||||
g_free(sc->ts_admins);
|
g_free(sc->ts_admins);
|
||||||
sc->ts_admins = g_strdup(value);
|
sc->ts_admins = g_strdup(value);
|
||||||
}
|
}
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALWAYSGROUPCHECK))
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALWAYSGROUPCHECK))
|
||||||
{
|
{
|
||||||
sc->ts_always_group_check = g_text2bool(value);
|
sc->ts_always_group_check = g_text2bool(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
|
||||||
{
|
{
|
||||||
char unrecognised[256];
|
char unrecognised[256];
|
||||||
sc->restrict_outbound_clipboard =
|
sc->restrict_outbound_clipboard =
|
||||||
@ -360,7 +358,7 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
unrecognised);
|
unrecognised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_INBOUND_CLIPBOARD))
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_INBOUND_CLIPBOARD))
|
||||||
{
|
{
|
||||||
char unrecognised[256];
|
char unrecognised[256];
|
||||||
sc->restrict_inbound_clipboard =
|
sc->restrict_inbound_clipboard =
|
||||||
@ -374,17 +372,21 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
unrecognised);
|
unrecognised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL))
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL))
|
||||||
{
|
{
|
||||||
sc->allow_alternate_shell =
|
sc->allow_alternate_shell =
|
||||||
g_text2bool(value);
|
g_text2bool(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES))
|
||||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES))
|
|
||||||
{
|
{
|
||||||
sc->xorg_no_new_privileges =
|
sc->xorg_no_new_privileges =
|
||||||
g_text2bool(value);
|
g_text2bool(value);
|
||||||
}
|
}
|
||||||
|
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_SESSION_SOCKDIR_GROUP))
|
||||||
|
{
|
||||||
|
g_free(sc->session_sockdir_group);
|
||||||
|
sc->session_sockdir_group = g_strdup(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -684,6 +686,7 @@ config_dump(struct config_sesman *config)
|
|||||||
g_writeln(" RestrictInboundClipboard: %s", restrict_s);
|
g_writeln(" RestrictInboundClipboard: %s", restrict_s);
|
||||||
g_writeln(" TSUsersGroup: %s", sc->ts_users);
|
g_writeln(" TSUsersGroup: %s", sc->ts_users);
|
||||||
g_writeln(" TSAdminsGroup: %s", sc->ts_admins);
|
g_writeln(" TSAdminsGroup: %s", sc->ts_admins);
|
||||||
|
g_writeln(" SessionSockdirGroup: %s", sc->session_sockdir_group);
|
||||||
|
|
||||||
|
|
||||||
/* Xorg */
|
/* Xorg */
|
||||||
@ -741,6 +744,7 @@ config_free(struct config_sesman *cs)
|
|||||||
list_delete(cs->env_values);
|
list_delete(cs->env_values);
|
||||||
g_free(cs->sec.ts_users);
|
g_free(cs->sec.ts_users);
|
||||||
g_free(cs->sec.ts_admins);
|
g_free(cs->sec.ts_admins);
|
||||||
|
g_free(cs->sec.session_sockdir_group);
|
||||||
g_free(cs);
|
g_free(cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,12 @@ struct config_security
|
|||||||
* @brief if the Xorg X11 server should be started with no_new_privs (Linux only)
|
* @brief if the Xorg X11 server should be started with no_new_privs (Linux only)
|
||||||
*/
|
*/
|
||||||
int xorg_no_new_privileges;
|
int xorg_no_new_privileges;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @var session_sockdir_group
|
||||||
|
* @brief Group to have read access to the session sockdirs
|
||||||
|
*/
|
||||||
|
char *session_sockdir_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "session_list.h"
|
#include "session_list.h"
|
||||||
#include "sesexec_control.h"
|
#include "sesexec_control.h"
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
#include "xrdp_sockets.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ process_sys_login_request(struct pre_session_item *psi)
|
|||||||
{
|
{
|
||||||
/* We only get here if something has gone
|
/* We only get here if something has gone
|
||||||
* wrong with the handover to sesexec */
|
* wrong with the handover to sesexec */
|
||||||
rv = scp_send_login_response(psi->client_trans, errorcode, 1);
|
rv = scp_send_login_response(psi->client_trans, errorcode, 1, -1);
|
||||||
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,15 +220,15 @@ process_uds_login_request(struct pre_session_item *psi)
|
|||||||
int uid;
|
int uid;
|
||||||
int pid;
|
int pid;
|
||||||
char *username = NULL;
|
char *username = NULL;
|
||||||
int server_closed = 1;
|
int server_closed;
|
||||||
|
|
||||||
rv = g_sck_get_peer_cred(psi->client_trans->sck, &pid, &uid, NULL);
|
rv = g_sck_get_peer_cred(psi->client_trans->sck, &pid, &uid, NULL);
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
|
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
|
||||||
LOG(LOG_LEVEL_INFO,
|
LOG(LOG_LEVEL_INFO,
|
||||||
"Unable to get peer credentials for socket %d",
|
"Unable to get peer credentials for socket %d",
|
||||||
(int)psi->client_trans->sck);
|
(int)psi->client_trans->sck);
|
||||||
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -252,21 +253,26 @@ process_uds_login_request(struct pre_session_item *psi)
|
|||||||
errorcode = authenticate_and_authorize_uds_connection(
|
errorcode = authenticate_and_authorize_uds_connection(
|
||||||
psi, uid, username);
|
psi, uid, username);
|
||||||
g_free(username);
|
g_free(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (errorcode == E_SCP_LOGIN_OK)
|
if (errorcode == E_SCP_LOGIN_OK)
|
||||||
{
|
{
|
||||||
server_closed = 0;
|
server_closed = 0;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
if (server_closed)
|
|
||||||
{
|
{
|
||||||
|
server_closed = 1;
|
||||||
|
|
||||||
/* Close the connection after returning from this callback */
|
/* Close the connection after returning from this callback */
|
||||||
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
||||||
|
|
||||||
|
/* Never return the UID if the server is closing */
|
||||||
|
uid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return scp_send_login_response(psi->client_trans, errorcode, server_closed);
|
return scp_send_login_response(psi->client_trans, errorcode,
|
||||||
|
server_closed, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -302,6 +308,58 @@ process_logout_request(struct pre_session_item *psi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/**
|
||||||
|
* Create xrdp socket path for the user
|
||||||
|
*
|
||||||
|
* We do this here rather than in sesexec as we're single-threaded here
|
||||||
|
* and so don't have to worry about race conditions
|
||||||
|
*
|
||||||
|
* Directory is owned by UID of session, but can be accessed by
|
||||||
|
* the group specified in the config.
|
||||||
|
*
|
||||||
|
* Errors are logged so the caller doesn't have to
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
create_xrdp_socket_path(uid_t uid)
|
||||||
|
{
|
||||||
|
int rv = 1;
|
||||||
|
const char *sockdir_group = g_cfg->sec.session_sockdir_group;
|
||||||
|
int gid = 0; // Default if no group specified
|
||||||
|
|
||||||
|
char sockdir[XRDP_SOCKETS_MAXPATH];
|
||||||
|
g_snprintf(sockdir, sizeof(sockdir), XRDP_SOCKET_PATH, (int)uid);
|
||||||
|
|
||||||
|
// Create directory permissions 0x750, if it doesn't exist already.
|
||||||
|
int old_umask = g_umask_hex(0x750 ^ 0x777);
|
||||||
|
if (!g_directory_exist(sockdir) && !g_create_dir(sockdir))
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR,
|
||||||
|
"create_xrdp_socket_path: Can't create %s [%s]",
|
||||||
|
sockdir, g_get_strerror());
|
||||||
|
}
|
||||||
|
else if (sockdir_group != NULL && sockdir_group[0] != '\0' &&
|
||||||
|
g_getgroup_info(sockdir_group, &gid) != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR,
|
||||||
|
"create_xrdp_socket_path: Can't get GID of group %s [%s]",
|
||||||
|
sockdir_group, g_get_strerror());
|
||||||
|
}
|
||||||
|
else if (g_chown(sockdir, uid, gid) != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR,
|
||||||
|
"create_xrdp_socket_path: Can't set owner of %s to %d:%d [%s]",
|
||||||
|
sockdir, uid, gid, g_get_strerror());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
(void)g_umask_hex(old_umask);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -385,6 +443,11 @@ process_create_session_request(struct pre_session_item *psi)
|
|||||||
{
|
{
|
||||||
status = E_SCP_SCREATE_NO_MEMORY;
|
status = E_SCP_SCREATE_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
// Create a socket dir for this user
|
||||||
|
else if (create_xrdp_socket_path(psi->uid) != 0)
|
||||||
|
{
|
||||||
|
status = E_SCP_SCREATE_GENERAL_ERROR;
|
||||||
|
}
|
||||||
// Create a sesexec process if we don't have one (UDS login)
|
// Create a sesexec process if we don't have one (UDS login)
|
||||||
else if (psi->sesexec_trans == NULL && sesexec_start(psi) != 0)
|
else if (psi->sesexec_trans == NULL && sesexec_start(psi) != 0)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@ AM_CPPFLAGS = \
|
|||||||
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
||||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||||
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_srcdir)/sesman/libsesman \
|
-I$(top_srcdir)/sesman/libsesman \
|
||||||
-I$(top_srcdir)/libipm \
|
-I$(top_srcdir)/libipm \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
@ -152,9 +152,10 @@ env_set_user(int uid, char **passwd_file, int display,
|
|||||||
// Use our PID as the XRDP_SESSION value
|
// Use our PID as the XRDP_SESSION value
|
||||||
g_snprintf(text, sizeof(text), "%d", g_pid);
|
g_snprintf(text, sizeof(text), "%d", g_pid);
|
||||||
g_setenv("XRDP_SESSION", text, 1);
|
g_setenv("XRDP_SESSION", text, 1);
|
||||||
/* XRDP_SOCKET_PATH should be set even here. It's used by
|
/* XRDP_SOCKET_PATH should be set here. It's used by
|
||||||
* xorgxrdp and the pulseaudio plugin */
|
* xorgxrdp and the pulseaudio plugin */
|
||||||
g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1);
|
g_snprintf(text, sizeof(text), XRDP_SOCKET_PATH, uid);
|
||||||
|
g_setenv("XRDP_SOCKET_PATH", text, 1);
|
||||||
/* pulse sink socket */
|
/* pulse sink socket */
|
||||||
g_snprintf(text, sizeof(text), CHANSRV_PORT_OUT_BASE_STR, display);
|
g_snprintf(text, sizeof(text), CHANSRV_PORT_OUT_BASE_STR, display);
|
||||||
g_setenv("XRDP_PULSE_SINK_SOCKET", text, 1);
|
g_setenv("XRDP_PULSE_SINK_SOCKET", text, 1);
|
||||||
|
@ -280,7 +280,8 @@ login_info_sys_login_user(struct trans *scp_trans,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scp_send_login_response(scp_trans, status, server_closed) != 0)
|
if (scp_send_login_response(scp_trans, status,
|
||||||
|
server_closed, result->uid) != 0)
|
||||||
{
|
{
|
||||||
status = E_SCP_LOGIN_GENERAL_ERROR;
|
status = E_SCP_LOGIN_GENERAL_ERROR;
|
||||||
break;
|
break;
|
||||||
|
@ -370,8 +370,6 @@ prepare_xorg_xserver_params(const struct session_parameters *s,
|
|||||||
g_snprintf(text, sizeof(text), "%d", g_cfg->sess.kill_disconnected);
|
g_snprintf(text, sizeof(text), "%d", g_cfg->sess.kill_disconnected);
|
||||||
g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
|
g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
|
||||||
|
|
||||||
g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1);
|
|
||||||
|
|
||||||
/* get path of Xorg from config */
|
/* get path of Xorg from config */
|
||||||
xserver = (const char *)list_get_item(g_cfg->xorg_params, 0);
|
xserver = (const char *)list_get_item(g_cfg->xorg_params, 0);
|
||||||
|
|
||||||
@ -716,15 +714,14 @@ session_start(struct login_info *login_info,
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static int
|
static int
|
||||||
cleanup_sockets(int display)
|
cleanup_sockets(int uid, int display)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_INFO, "cleanup_sockets:");
|
LOG_DEVEL(LOG_LEVEL_INFO, "cleanup_sockets:");
|
||||||
char file[256];
|
|
||||||
int error;
|
|
||||||
|
|
||||||
error = 0;
|
char file[XRDP_SOCKETS_MAXPATH];
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
g_snprintf(file, 255, CHANSRV_PORT_OUT_STR, display);
|
g_snprintf(file, sizeof(file), CHANSRV_PORT_OUT_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -737,7 +734,7 @@ cleanup_sockets(int display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_snprintf(file, 255, CHANSRV_PORT_IN_STR, display);
|
g_snprintf(file, sizeof(file), CHANSRV_PORT_IN_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -750,7 +747,7 @@ cleanup_sockets(int display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_snprintf(file, 255, XRDP_CHANSRV_STR, display);
|
g_snprintf(file, sizeof(file), XRDP_CHANSRV_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -763,7 +760,7 @@ cleanup_sockets(int display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_snprintf(file, 255, CHANSRV_API_STR, display);
|
g_snprintf(file, sizeof(file), CHANSRV_API_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -779,7 +776,7 @@ cleanup_sockets(int display)
|
|||||||
/* the following files should be deleted by xorgxrdp
|
/* the following files should be deleted by xorgxrdp
|
||||||
* but just in case the deletion failed */
|
* but just in case the deletion failed */
|
||||||
|
|
||||||
g_snprintf(file, 255, XRDP_X11RDP_STR, display);
|
g_snprintf(file, sizeof(file), XRDP_X11RDP_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -792,7 +789,7 @@ cleanup_sockets(int display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_snprintf(file, 255, XRDP_DISCONNECT_STR, display);
|
g_snprintf(file, sizeof(file), XRDP_DISCONNECT_STR, uid, display);
|
||||||
if (g_file_exist(file))
|
if (g_file_exist(file))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
|
||||||
@ -908,7 +905,7 @@ session_process_child_exit(struct session_data *sd,
|
|||||||
|
|
||||||
if (!session_active(sd))
|
if (!session_active(sd))
|
||||||
{
|
{
|
||||||
cleanup_sockets(sd->params.display);
|
cleanup_sockets(g_login_info->uid, sd->params.display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "xrdp_configure_options.h"
|
#include "xrdp_configure_options.h"
|
||||||
|
#include "xrdp_sockets.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of pre-session items
|
* Maximum number of pre-session items
|
||||||
@ -688,9 +689,6 @@ read_pid_file(const char *pid_file, int *pid)
|
|||||||
static int
|
static int
|
||||||
create_xrdp_socket_root_path(void)
|
create_xrdp_socket_root_path(void)
|
||||||
{
|
{
|
||||||
#ifndef XRDP_SOCKET_PATH
|
|
||||||
# error "XRDP_SOCKET_PATH must be defined"
|
|
||||||
#endif
|
|
||||||
int uid = g_getuid();
|
int uid = g_getuid();
|
||||||
int gid = g_getgid();
|
int gid = g_getgid();
|
||||||
|
|
||||||
|
@ -44,6 +44,12 @@ RestrictInboundClipboard=none
|
|||||||
; however, interfere with the use of security modules such as AppArmor.
|
; however, interfere with the use of security modules such as AppArmor.
|
||||||
; Leave this unset unless you need to disable it.
|
; Leave this unset unless you need to disable it.
|
||||||
#XorgNoNewPrivileges=true
|
#XorgNoNewPrivileges=true
|
||||||
|
; Specify the group which is to have read access to the directory where
|
||||||
|
; local sockets for the session are created. This is normally the GID
|
||||||
|
; which the xrdp process runs as.
|
||||||
|
; Default is 'root'
|
||||||
|
#SessionSockdirGroup=root
|
||||||
|
|
||||||
|
|
||||||
[Sessions]
|
[Sessions]
|
||||||
;; X11DisplayOffset - x11 display number offset
|
;; X11DisplayOffset - x11 display number offset
|
||||||
|
@ -198,41 +198,6 @@ x_server_running_check_ports(int display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x_running)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
|
|
||||||
g_sprintf(text, XRDP_CHANSRV_STR, display);
|
|
||||||
x_running = g_file_exist(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x_running)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
|
|
||||||
g_sprintf(text, CHANSRV_PORT_OUT_STR, display);
|
|
||||||
x_running = g_file_exist(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x_running)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
|
|
||||||
g_sprintf(text, CHANSRV_PORT_IN_STR, display);
|
|
||||||
x_running = g_file_exist(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x_running)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
|
|
||||||
g_sprintf(text, CHANSRV_API_STR, display);
|
|
||||||
x_running = g_file_exist(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x_running)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
|
|
||||||
g_sprintf(text, XRDP_X11RDP_STR, display);
|
|
||||||
x_running = g_file_exist(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x_running)
|
if (x_running)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_INFO, "Found X server running at %s", text);
|
LOG(LOG_LEVEL_INFO, "Found X server running at %s", text);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_srcdir)/sesman/libsesman \
|
-I$(top_srcdir)/sesman/libsesman \
|
||||||
-I$(top_srcdir)/common \
|
-I$(top_srcdir)/common \
|
||||||
-I$(top_srcdir)/libipm
|
-I$(top_srcdir)/libipm
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "xrdp_sockets.h"
|
#include "xrdp_sockets.h"
|
||||||
|
#include "os_calls.h"
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -62,7 +63,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sun_family = AF_UNIX;
|
sa.sun_family = AF_UNIX;
|
||||||
sprintf(sa.sun_path, XRDP_DISCONNECT_STR, dis);
|
sprintf(sa.sun_path, XRDP_DISCONNECT_STR, g_getuid(), dis);
|
||||||
|
|
||||||
if (access(sa.sun_path, F_OK) != 0)
|
if (access(sa.sun_path, F_OK) != 0)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ int main(int argc, char **argv)
|
|||||||
if ((rv = scp_send_uds_login_request(t)) == 0 &&
|
if ((rv = scp_send_uds_login_request(t)) == 0 &&
|
||||||
(rv = wait_for_sesman_reply(t, E_SCP_LOGIN_RESPONSE)) == 0)
|
(rv = wait_for_sesman_reply(t, E_SCP_LOGIN_RESPONSE)) == 0)
|
||||||
{
|
{
|
||||||
rv = scp_get_login_response(t, &login_result, NULL);
|
rv = scp_get_login_response(t, &login_result, NULL, NULL);
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
if (login_result != E_SCP_LOGIN_OK)
|
if (login_result != E_SCP_LOGIN_OK)
|
||||||
|
@ -460,7 +460,7 @@ handle_login_response(struct trans *t, int *server_closed)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rv = scp_get_login_response(t, &login_result, server_closed);
|
rv = scp_get_login_response(t, &login_result, server_closed, NULL);
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
if (login_result != E_SCP_LOGIN_OK)
|
if (login_result != E_SCP_LOGIN_OK)
|
||||||
|
@ -9,7 +9,7 @@ AM_CPPFLAGS = \
|
|||||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||||
-DXRDP_MODULE_PATH=\"${moduledir}\" \
|
-DXRDP_MODULE_PATH=\"${moduledir}\" \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_builddir) \
|
-I$(top_builddir) \
|
||||||
-I$(top_srcdir)/common \
|
-I$(top_srcdir)/common \
|
||||||
-I$(top_srcdir)/libipm \
|
-I$(top_srcdir)/libipm \
|
||||||
|
@ -61,6 +61,8 @@ xrdp_mm_create(struct xrdp_wm *owner)
|
|||||||
self->resize_queue = list_create();
|
self->resize_queue = list_create();
|
||||||
self->resize_queue->auto_free = 1;
|
self->resize_queue->auto_free = 1;
|
||||||
|
|
||||||
|
self->uid = -1; /* Never good to default UIDs to 0 */
|
||||||
|
|
||||||
pid = g_getpid();
|
pid = g_getpid();
|
||||||
/* setup wait objects for signalling */
|
/* setup wait objects for signalling */
|
||||||
g_snprintf(buf, sizeof(buf), "xrdp_%8.8x_resize_ready", pid);
|
g_snprintf(buf, sizeof(buf), "xrdp_%8.8x_resize_ready", pid);
|
||||||
@ -469,11 +471,12 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
|
|||||||
{
|
{
|
||||||
if (self->code == XVNC_SESSION_CODE)
|
if (self->code == XVNC_SESSION_CODE)
|
||||||
{
|
{
|
||||||
g_snprintf(text, 255, "%d", 5900 + self->display);
|
g_snprintf(text, sizeof(text), "%d", 5900 + self->display);
|
||||||
}
|
}
|
||||||
else if (self->code == XORG_SESSION_CODE)
|
else if (self->code == XORG_SESSION_CODE)
|
||||||
{
|
{
|
||||||
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
|
g_snprintf(text, sizeof(text), XRDP_X11RDP_STR,
|
||||||
|
self->uid, self->display);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2178,7 +2181,8 @@ xrdp_mm_process_login_response(struct xrdp_mm *self)
|
|||||||
|
|
||||||
self->mmcs_expecting_msg = 0;
|
self->mmcs_expecting_msg = 0;
|
||||||
|
|
||||||
rv = scp_get_login_response(self->sesman_trans, &login_result, &server_closed);
|
rv = scp_get_login_response(self->sesman_trans, &login_result,
|
||||||
|
&server_closed, &self->uid);
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
if (login_result != E_SCP_LOGIN_OK)
|
if (login_result != E_SCP_LOGIN_OK)
|
||||||
@ -2346,11 +2350,16 @@ cleanup_states(struct xrdp_mm *self)
|
|||||||
* @param value assigned to chansrvport
|
* @param value assigned to chansrvport
|
||||||
* @param dest Output buffer
|
* @param dest Output buffer
|
||||||
* @param dest_size Total size of output buffer, including terminator space
|
* @param dest_size Total size of output buffer, including terminator space
|
||||||
|
* @param uid of destination
|
||||||
|
*
|
||||||
|
* Pass in dest of NULL, dest_size of 0 and uid of -1 to simply see if
|
||||||
|
* the string parses OK.
|
||||||
|
*
|
||||||
* @return 0 for success
|
* @return 0 for success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_chansrvport(const char *value, char *dest, int dest_size)
|
parse_chansrvport(const char *value, char *dest, int dest_size, int uid)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
@ -2373,7 +2382,7 @@ parse_chansrvport(const char *value, char *dest, int dest_size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_snprintf(dest, dest_size, XRDP_CHANSRV_STR, g_atoi(p));
|
g_snprintf(dest, dest_size, XRDP_CHANSRV_STR, uid, g_atoi(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2561,7 +2570,7 @@ xrdp_mm_connect(struct xrdp_mm *self)
|
|||||||
{
|
{
|
||||||
const char *csp = xrdp_mm_get_value(self, "chansrvport");
|
const char *csp = xrdp_mm_get_value(self, "chansrvport");
|
||||||
/* It's defined, but is it a valid string? */
|
/* It's defined, but is it a valid string? */
|
||||||
if (csp != NULL && parse_chansrvport(csp, NULL, 0) == 0)
|
if (csp != NULL && parse_chansrvport(csp, NULL, 0, -1) == 0)
|
||||||
{
|
{
|
||||||
self->use_chansrv = 1;
|
self->use_chansrv = 1;
|
||||||
}
|
}
|
||||||
@ -2652,6 +2661,7 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
|||||||
"access control check was successful");
|
"access control check was successful");
|
||||||
// No reply needed for this one
|
// No reply needed for this one
|
||||||
status = scp_send_logout_request(self->sesman_trans);
|
status = scp_send_logout_request(self->sesman_trans);
|
||||||
|
self->uid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 0 && self->use_sesman)
|
if (status == 0 && self->use_sesman)
|
||||||
@ -2723,20 +2733,21 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
|||||||
{
|
{
|
||||||
if (self->use_chansrv)
|
if (self->use_chansrv)
|
||||||
{
|
{
|
||||||
char portbuff[256];
|
char portbuff[XRDP_SOCKETS_MAXPATH];
|
||||||
|
|
||||||
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
|
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
|
||||||
"Connecting to chansrv");
|
"Connecting to chansrv");
|
||||||
if (self->use_sesman)
|
if (self->use_sesman)
|
||||||
{
|
{
|
||||||
g_snprintf(portbuff, sizeof(portbuff),
|
g_snprintf(portbuff, sizeof(portbuff),
|
||||||
XRDP_CHANSRV_STR, self->display);
|
XRDP_CHANSRV_STR, self->uid, self->display);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *cp = xrdp_mm_get_value(self, "chansrvport");
|
const char *cp = xrdp_mm_get_value(self, "chansrvport");
|
||||||
portbuff[0] = '\0';
|
portbuff[0] = '\0';
|
||||||
parse_chansrvport(cp, portbuff, sizeof(portbuff));
|
parse_chansrvport(cp, portbuff, sizeof(portbuff),
|
||||||
|
self->uid);
|
||||||
|
|
||||||
}
|
}
|
||||||
xrdp_mm_update_allowed_channels(self);
|
xrdp_mm_update_allowed_channels(self);
|
||||||
|
@ -401,6 +401,7 @@ struct xrdp_mm
|
|||||||
int (*mod_exit)(struct xrdp_mod *);
|
int (*mod_exit)(struct xrdp_mod *);
|
||||||
struct xrdp_mod *mod; /* module interface */
|
struct xrdp_mod *mod; /* module interface */
|
||||||
int display; /* 10 for :10.0, 11 for :11.0, etc */
|
int display; /* 10 for :10.0, 11 for :11.0, etc */
|
||||||
|
int uid; /* UID for a successful login, -1 otherwise */
|
||||||
struct guid guid; /* GUID for the session, or all zeros */
|
struct guid guid; /* GUID for the session, or all zeros */
|
||||||
int code; /* 0=Xvnc session, 20=xorg driver mode */
|
int code; /* 0=Xvnc session, 20=xorg driver mode */
|
||||||
struct xrdp_encoder *encoder;
|
struct xrdp_encoder *encoder;
|
||||||
|
@ -4,7 +4,7 @@ EXTRA_DIST = \
|
|||||||
vrplayer.mk
|
vrplayer.mk
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||||
-I$(top_srcdir)/common
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
module_LTLIBRARIES = \
|
module_LTLIBRARIES = \
|
||||||
|
@ -140,7 +140,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
|
|||||||
memset(&s, 0, sizeof(struct sockaddr_un));
|
memset(&s, 0, sizeof(struct sockaddr_un));
|
||||||
s.sun_family = AF_UNIX;
|
s.sun_family = AF_UNIX;
|
||||||
bytes = sizeof(s.sun_path);
|
bytes = sizeof(s.sun_path);
|
||||||
snprintf(s.sun_path, bytes - 1, CHANSRV_API_STR, wts->display_num);
|
snprintf(s.sun_path, bytes - 1, CHANSRV_API_STR, getuid(), wts->display_num);
|
||||||
s.sun_path[bytes - 1] = 0;
|
s.sun_path[bytes - 1] = 0;
|
||||||
bytes = sizeof(struct sockaddr_un);
|
bytes = sizeof(struct sockaddr_un);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user