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)
|
||||
#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 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_API_BASE_STR "xrdpapi_%d"
|
||||
#define XRDP_X11RDP_BASE_STR "xrdp_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 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
|
||||
|
@ -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
|
||||
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"
|
||||
Following parameters can be used in the \fB[Xvnc]\fR and
|
||||
\fB[Xorg]\fR sections.
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_srcdir)/common
|
||||
|
||||
module_LTLIBRARIES = \
|
||||
|
25
libipm/scp.c
25
libipm/scp.c
@ -332,14 +332,16 @@ scp_get_sys_login_request(struct trans *trans,
|
||||
int
|
||||
scp_send_login_response(struct trans *trans,
|
||||
enum scp_login_status login_result,
|
||||
int server_closed)
|
||||
int server_closed,
|
||||
int uid)
|
||||
{
|
||||
return libipm_msg_out_simple_send(
|
||||
trans,
|
||||
(int)E_SCP_LOGIN_RESPONSE,
|
||||
"ib",
|
||||
"ibi",
|
||||
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
|
||||
scp_get_login_response(struct trans *trans,
|
||||
enum scp_login_status *login_result,
|
||||
int *server_closed)
|
||||
int *server_closed,
|
||||
int *uid)
|
||||
{
|
||||
int32_t i_login_result = 0;
|
||||
int32_t i_uid = 0;
|
||||
int dummy;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
*login_result = (enum scp_login_status)i_login_result;
|
||||
*uid = i_uid;
|
||||
}
|
||||
|
||||
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 server_closed If login fails, whether server has closed connection.
|
||||
* If not, a retry can be made.
|
||||
* @param uid UID for a successful login
|
||||
* @return != 0 for error
|
||||
*/
|
||||
int
|
||||
scp_send_login_response(struct trans *trans,
|
||||
enum scp_login_status login_result,
|
||||
int server_closed);
|
||||
int server_closed,
|
||||
int uid);
|
||||
|
||||
/**
|
||||
* 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] server_closed If login fails, whether server has closed
|
||||
* 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
|
||||
*/
|
||||
int
|
||||
scp_get_login_response(struct trans *trans,
|
||||
enum scp_login_status *login_result,
|
||||
int *server_closed);
|
||||
int *server_closed,
|
||||
int *uid);
|
||||
|
||||
/**
|
||||
* Send an E_SCP_LOGOUT_REQUEST (SCP client)
|
||||
|
@ -6,7 +6,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||
-I$(top_srcdir)/sesman/libsesman \
|
||||
-I$(top_srcdir)/common \
|
||||
|
@ -8,7 +8,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_srcdir)/sesman/libsesman \
|
||||
-I$(top_srcdir)/common
|
||||
|
||||
|
@ -1238,7 +1238,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
|
||||
static int
|
||||
setup_listen(void)
|
||||
{
|
||||
char port[256];
|
||||
char port[XRDP_SOCKETS_MAXPATH];
|
||||
int error = 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->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;
|
||||
error = trans_listen(g_lis_trans, port);
|
||||
@ -1267,12 +1267,12 @@ setup_listen(void)
|
||||
static int
|
||||
setup_api_listen(void)
|
||||
{
|
||||
char port[256];
|
||||
char port[XRDP_SOCKETS_MAXPATH];
|
||||
int error = 0;
|
||||
|
||||
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
|
||||
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;
|
||||
error = trans_listen(g_api_lis_trans, port);
|
||||
|
||||
|
@ -1894,11 +1894,11 @@ sound_sndsrvr_source_data_in(struct trans *trans)
|
||||
static int
|
||||
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->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;
|
||||
if (trans_listen(g_audio_l_trans_in, port) != 0)
|
||||
{
|
||||
@ -1913,11 +1913,11 @@ sound_start_source_listener(void)
|
||||
static int
|
||||
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->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;
|
||||
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_ALLOW_ALTERNATE_SHELL "AllowAlternateShell"
|
||||
#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_SESS_MAX "MaxSessions"
|
||||
@ -312,6 +313,7 @@ config_read_security(int file, struct config_security *sc,
|
||||
sc->xorg_no_new_privileges = 1;
|
||||
sc->ts_users = g_strdup("");
|
||||
sc->ts_admins = g_strdup("");
|
||||
sc->session_sockdir_group = g_strdup("");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY))
|
||||
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY))
|
||||
{
|
||||
sc->login_retry = g_atoi(value);
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP))
|
||||
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP))
|
||||
{
|
||||
g_free(sc->ts_users);
|
||||
sc->ts_users = g_strdup(value);
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP))
|
||||
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP))
|
||||
{
|
||||
g_free(sc->ts_admins);
|
||||
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);
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
||||
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
||||
{
|
||||
char unrecognised[256];
|
||||
sc->restrict_outbound_clipboard =
|
||||
@ -360,7 +358,7 @@ config_read_security(int file, struct config_security *sc,
|
||||
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];
|
||||
sc->restrict_inbound_clipboard =
|
||||
@ -374,17 +372,21 @@ config_read_security(int file, struct config_security *sc,
|
||||
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 =
|
||||
g_text2bool(value);
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES))
|
||||
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES))
|
||||
{
|
||||
sc->xorg_no_new_privileges =
|
||||
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;
|
||||
@ -684,6 +686,7 @@ config_dump(struct config_sesman *config)
|
||||
g_writeln(" RestrictInboundClipboard: %s", restrict_s);
|
||||
g_writeln(" TSUsersGroup: %s", sc->ts_users);
|
||||
g_writeln(" TSAdminsGroup: %s", sc->ts_admins);
|
||||
g_writeln(" SessionSockdirGroup: %s", sc->session_sockdir_group);
|
||||
|
||||
|
||||
/* Xorg */
|
||||
@ -741,6 +744,7 @@ config_free(struct config_sesman *cs)
|
||||
list_delete(cs->env_values);
|
||||
g_free(cs->sec.ts_users);
|
||||
g_free(cs->sec.ts_admins);
|
||||
g_free(cs->sec.session_sockdir_group);
|
||||
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)
|
||||
*/
|
||||
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 "sesexec_control.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
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -219,15 +220,15 @@ process_uds_login_request(struct pre_session_item *psi)
|
||||
int uid;
|
||||
int pid;
|
||||
char *username = NULL;
|
||||
int server_closed = 1;
|
||||
int server_closed;
|
||||
|
||||
rv = g_sck_get_peer_cred(psi->client_trans->sck, &pid, &uid, NULL);
|
||||
if (rv != 0)
|
||||
{
|
||||
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"Unable to get peer credentials for socket %d",
|
||||
(int)psi->client_trans->sck);
|
||||
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,21 +253,26 @@ process_uds_login_request(struct pre_session_item *psi)
|
||||
errorcode = authenticate_and_authorize_uds_connection(
|
||||
psi, uid, username);
|
||||
g_free(username);
|
||||
|
||||
if (errorcode == E_SCP_LOGIN_OK)
|
||||
{
|
||||
server_closed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (server_closed)
|
||||
if (errorcode == E_SCP_LOGIN_OK)
|
||||
{
|
||||
server_closed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
server_closed = 1;
|
||||
|
||||
/* Close the connection after returning from this callback */
|
||||
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;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* 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
|
||||
@ -385,6 +443,11 @@ process_create_session_request(struct pre_session_item *psi)
|
||||
{
|
||||
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)
|
||||
else if (psi->sesexec_trans == NULL && sesexec_start(psi) != 0)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||
-DXRDP_LIBEXEC_PATH=\"${libexecdir}/xrdp\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_srcdir)/sesman/libsesman \
|
||||
-I$(top_srcdir)/libipm \
|
||||
-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
|
||||
g_snprintf(text, sizeof(text), "%d", g_pid);
|
||||
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 */
|
||||
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 */
|
||||
g_snprintf(text, sizeof(text), CHANSRV_PORT_OUT_BASE_STR, display);
|
||||
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;
|
||||
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_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
|
||||
|
||||
g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1);
|
||||
|
||||
/* get path of Xorg from config */
|
||||
xserver = (const char *)list_get_item(g_cfg->xorg_params, 0);
|
||||
|
||||
@ -716,15 +714,14 @@ session_start(struct login_info *login_info,
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
cleanup_sockets(int display)
|
||||
cleanup_sockets(int uid, int display)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "cleanup_sockets:");
|
||||
char file[256];
|
||||
int error;
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "cleanup_sockets:");
|
||||
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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
|
||||
* 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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
cleanup_sockets(sd->params.display);
|
||||
cleanup_sockets(g_login_info->uid, sd->params.display);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "string_calls.h"
|
||||
#include "trans.h"
|
||||
#include "xrdp_configure_options.h"
|
||||
#include "xrdp_sockets.h"
|
||||
|
||||
/**
|
||||
* Maximum number of pre-session items
|
||||
@ -688,9 +689,6 @@ read_pid_file(const char *pid_file, int *pid)
|
||||
static int
|
||||
create_xrdp_socket_root_path(void)
|
||||
{
|
||||
#ifndef XRDP_SOCKET_PATH
|
||||
# error "XRDP_SOCKET_PATH must be defined"
|
||||
#endif
|
||||
int uid = g_getuid();
|
||||
int gid = g_getgid();
|
||||
|
||||
|
@ -44,6 +44,12 @@ RestrictInboundClipboard=none
|
||||
; however, interfere with the use of security modules such as AppArmor.
|
||||
; Leave this unset unless you need to disable it.
|
||||
#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]
|
||||
;; 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)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "Found X server running at %s", text);
|
||||
|
@ -1,6 +1,6 @@
|
||||
AM_CPPFLAGS = \
|
||||
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_srcdir)/sesman/libsesman \
|
||||
-I$(top_srcdir)/common \
|
||||
-I$(top_srcdir)/libipm
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "xrdp_sockets.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -62,7 +63,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
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)
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ int main(int argc, char **argv)
|
||||
if ((rv = scp_send_uds_login_request(t)) == 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 (login_result != E_SCP_LOGIN_OK)
|
||||
|
@ -460,7 +460,7 @@ handle_login_response(struct trans *t, int *server_closed)
|
||||
}
|
||||
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 (login_result != E_SCP_LOGIN_OK)
|
||||
|
@ -9,7 +9,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||
-DXRDP_MODULE_PATH=\"${moduledir}\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/common \
|
||||
-I$(top_srcdir)/libipm \
|
||||
|
@ -61,6 +61,8 @@ xrdp_mm_create(struct xrdp_wm *owner)
|
||||
self->resize_queue = list_create();
|
||||
self->resize_queue->auto_free = 1;
|
||||
|
||||
self->uid = -1; /* Never good to default UIDs to 0 */
|
||||
|
||||
pid = g_getpid();
|
||||
/* setup wait objects for signalling */
|
||||
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)
|
||||
{
|
||||
g_snprintf(text, 255, "%d", 5900 + self->display);
|
||||
g_snprintf(text, sizeof(text), "%d", 5900 + self->display);
|
||||
}
|
||||
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
|
||||
{
|
||||
@ -2178,7 +2181,8 @@ xrdp_mm_process_login_response(struct xrdp_mm *self)
|
||||
|
||||
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 (login_result != E_SCP_LOGIN_OK)
|
||||
@ -2346,11 +2350,16 @@ cleanup_states(struct xrdp_mm *self)
|
||||
* @param value assigned to chansrvport
|
||||
* @param dest Output buffer
|
||||
* @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
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
@ -2373,7 +2382,7 @@ parse_chansrvport(const char *value, char *dest, int dest_size)
|
||||
}
|
||||
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
|
||||
@ -2561,7 +2570,7 @@ xrdp_mm_connect(struct xrdp_mm *self)
|
||||
{
|
||||
const char *csp = xrdp_mm_get_value(self, "chansrvport");
|
||||
/* 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;
|
||||
}
|
||||
@ -2652,6 +2661,7 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
||||
"access control check was successful");
|
||||
// No reply needed for this one
|
||||
status = scp_send_logout_request(self->sesman_trans);
|
||||
self->uid = -1;
|
||||
}
|
||||
|
||||
if (status == 0 && self->use_sesman)
|
||||
@ -2723,20 +2733,21 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
||||
{
|
||||
if (self->use_chansrv)
|
||||
{
|
||||
char portbuff[256];
|
||||
char portbuff[XRDP_SOCKETS_MAXPATH];
|
||||
|
||||
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
|
||||
"Connecting to chansrv");
|
||||
if (self->use_sesman)
|
||||
{
|
||||
g_snprintf(portbuff, sizeof(portbuff),
|
||||
XRDP_CHANSRV_STR, self->display);
|
||||
XRDP_CHANSRV_STR, self->uid, self->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *cp = xrdp_mm_get_value(self, "chansrvport");
|
||||
portbuff[0] = '\0';
|
||||
parse_chansrvport(cp, portbuff, sizeof(portbuff));
|
||||
parse_chansrvport(cp, portbuff, sizeof(portbuff),
|
||||
self->uid);
|
||||
|
||||
}
|
||||
xrdp_mm_update_allowed_channels(self);
|
||||
|
@ -401,6 +401,7 @@ struct xrdp_mm
|
||||
int (*mod_exit)(struct xrdp_mod *);
|
||||
struct xrdp_mod *mod; /* module interface */
|
||||
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 */
|
||||
int code; /* 0=Xvnc session, 20=xorg driver mode */
|
||||
struct xrdp_encoder *encoder;
|
||||
|
@ -4,7 +4,7 @@ EXTRA_DIST = \
|
||||
vrplayer.mk
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
|
||||
-I$(top_srcdir)/common
|
||||
|
||||
module_LTLIBRARIES = \
|
||||
|
@ -140,7 +140,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
|
||||
memset(&s, 0, sizeof(struct sockaddr_un));
|
||||
s.sun_family = AF_UNIX;
|
||||
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;
|
||||
bytes = sizeof(struct sockaddr_un);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user