diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index d2ca9832..3495c779 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -315,7 +315,8 @@ 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. +MUST be the same as runtime_group in xrdp.ini, or xrdp will not +be able to connect to any sessions. .SH "X11 SERVER" Following parameters can be used in the \fB[Xvnc]\fR and diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index e44327ce..c7a22841 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -119,6 +119,17 @@ The default port for RDP is \fB3389\fP. Multiple address:port instances must be separated by spaces or commas. Check the .ini file for examples. Specifying interfaces requires said interfaces to be UP before xrdp starts. +.TP +\fBruntime_user\fP=\fIusername\fP +.TP +\fBruntime_group\fP=\fIgroupname\fP +User name and group to run the xrdp daemon under. + +After xrdp starts, it sets its UID and GID to values derived from these +settings, so that it's running without system privilege. +The \fBruntime_group\fP MUST be set to the same value as +\fBSessionSockdirGroup\fP in \fBsesman.ini\fP if you want to run sessions. + .TP \fBenable_token_login\fP=\fI[true|false]\fP If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will scan the user name provided by the diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index 685af28b..62eae276 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -45,10 +45,10 @@ RestrictInboundClipboard=none ; 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 +; local sockets for the session are created. +; This MUST be the same as runtime_group in xrdp.ini, or xrdp will not +; be able to connect to your sessions. +#SessionSockdirGroup=xrdp [Sessions] diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index b2f94920..08377b23 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -428,8 +428,6 @@ main(int argc, char **argv) g_exit(1); } - - if (g_file_exist(pid_file)) /* xrdp.pid */ { LOG(LOG_LEVEL_ALWAYS, "It looks like xrdp is already running."); diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index 11ecada6..d2998a3c 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -27,6 +27,15 @@ port=3389 ; prefer use vsock://: above use_vsock=false +; Unprivileged User name and group to run the xrdp daemon. +; It is HIGHLY RECOMMENDED you set these values. +; A suitable user and group can be added with a command like this (Linux):- +; useradd xrdp -d / -c 'xrdp daemon' -s /usr/sbin/nologin +; Be aware that runtime_group here, and SessionSockdirGroup in sesman.ini +; MUST be the same if you want to run sessions. +#runtime_user=xrdp +#runtime_group=xrdp + ; regulate if the listening socket use socket option tcp_nodelay ; no buffering will be performed in the TCP stack tcp_nodelay=true diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 51e53446..bbf0c6d0 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -162,7 +162,8 @@ xrdp_listen_get_startup_params(struct xrdp_listen *self) int index; int port_override; int fork_override; - char *val; + const char *name; + const char *val; struct list *names; struct list *values; struct xrdp_startup_params *startup_params; @@ -181,56 +182,67 @@ xrdp_listen_get_startup_params(struct xrdp_listen *self) { for (index = 0; index < names->count; index++) { - val = (char *)list_get_item(names, index); - if (val != 0) + name = (const char *)list_get_item(names, index); + val = (const char *)list_get_item(values, index); + if (name == 0 || val == 0) { - if (g_strcasecmp(val, "port") == 0) - { - if (port_override == 0) - { - val = (char *) list_get_item(values, index); - g_strncpy(startup_params->port, val, - sizeof(startup_params->port) - 1); - } - } - if (g_strcasecmp(val, "fork") == 0) - { - if (fork_override == 0) - { - val = (char *) list_get_item(values, index); - startup_params->fork = g_text2bool(val); - } - } + continue; + } - if (g_strcasecmp(val, "tcp_nodelay") == 0) + if (g_strcasecmp(name, "port") == 0) + { + if (port_override == 0) { - val = (char *)list_get_item(values, index); - startup_params->tcp_nodelay = g_text2bool(val); + g_strncpy(startup_params->port, val, + sizeof(startup_params->port) - 1); } + } - if (g_strcasecmp(val, "tcp_keepalive") == 0) + else if (g_strcasecmp(name, "fork") == 0) + { + if (fork_override == 0) { - val = (char *)list_get_item(values, index); - startup_params->tcp_keepalive = g_text2bool(val); + startup_params->fork = g_text2bool(val); } + } - if (g_strcasecmp(val, "tcp_send_buffer_bytes") == 0) - { - val = (char *)list_get_item(values, index); - startup_params->tcp_send_buffer_bytes = g_atoi(val); - } + else if (g_strcasecmp(name, "tcp_nodelay") == 0) + { + startup_params->tcp_nodelay = g_text2bool(val); + } - if (g_strcasecmp(val, "tcp_recv_buffer_bytes") == 0) - { - val = (char *)list_get_item(values, index); - startup_params->tcp_recv_buffer_bytes = g_atoi(val); - } + else if (g_strcasecmp(name, "tcp_keepalive") == 0) + { + startup_params->tcp_keepalive = g_text2bool(val); + } - if (g_strcasecmp(val, "use_vsock") == 0) - { - val = (char *)list_get_item(values, index); - startup_params->use_vsock = g_text2bool(val); - } + else if (g_strcasecmp(name, "tcp_send_buffer_bytes") == 0) + { + startup_params->tcp_send_buffer_bytes = g_atoi(val); + } + + else if (g_strcasecmp(name, "tcp_recv_buffer_bytes") == 0) + { + startup_params->tcp_recv_buffer_bytes = g_atoi(val); + } + + else if (g_strcasecmp(name, "use_vsock") == 0) + { + startup_params->use_vsock = g_text2bool(val); + } + + else if (g_strcasecmp(name, "runtime_user") == 0) + { + g_snprintf(startup_params->runtime_user, + sizeof(startup_params->runtime_user), + "%s", val); + } + + else if (g_strcasecmp(name, "runtime_group") == 0) + { + g_snprintf(startup_params->runtime_group, + sizeof(startup_params->runtime_group), + "%s", val); } } } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index c2195a9c..8b85fbb3 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -735,6 +735,10 @@ struct xrdp_startup_params int tcp_nodelay; int tcp_keepalive; int use_vsock; + // These should be local users/groups, and so we shouldn't need + // a lot of storage for them. + char runtime_user[64]; + char runtime_group[64]; }; /*