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:
matt335672 2023-06-14 13:59:55 +01:00
parent 63235eaafd
commit 675dd77807
28 changed files with 219 additions and 116 deletions

View File

@ -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

View File

@ -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.

View File

@ -1,6 +1,7 @@
AM_CPPFLAGS = \
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
-DXRDP_SOCKET_ROOT_PATH=\"${socketdir}\" \
-I$(top_srcdir)/common
module_LTLIBRARIES = \

View File

@ -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;
}

View File

@ -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)

View File

@ -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 \

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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;
};
/**

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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)

View File

@ -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)

View File

@ -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 \

View File

@ -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);

View File

@ -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;

View File

@ -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 = \

View File

@ -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);