Merge pull request #2207 from matt335672/move_to_uds

Move to Unix Domain Socket for SCP (sesman)
This commit is contained in:
matt335672 2022-04-18 09:25:59 +01:00 committed by GitHub
commit dd4abcb27a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 607 additions and 301 deletions

View File

@ -2322,6 +2322,55 @@ g_file_lock(int fd, int start, int len)
#endif
}
/*****************************************************************************/
/* Converts a hex mask to a mode_t value */
#if !defined(_WIN32)
static mode_t
hex_to_mode_t(int hex)
{
mode_t mode = 0;
mode |= (hex & 0x4000) ? S_ISUID : 0;
mode |= (hex & 0x2000) ? S_ISGID : 0;
mode |= (hex & 0x1000) ? S_ISVTX : 0;
mode |= (hex & 0x0400) ? S_IRUSR : 0;
mode |= (hex & 0x0200) ? S_IWUSR : 0;
mode |= (hex & 0x0100) ? S_IXUSR : 0;
mode |= (hex & 0x0040) ? S_IRGRP : 0;
mode |= (hex & 0x0020) ? S_IWGRP : 0;
mode |= (hex & 0x0010) ? S_IXGRP : 0;
mode |= (hex & 0x0004) ? S_IROTH : 0;
mode |= (hex & 0x0002) ? S_IWOTH : 0;
mode |= (hex & 0x0001) ? S_IXOTH : 0;
return mode;
}
#endif
/*****************************************************************************/
/* Converts a mode_t value to a hex mask */
#if !defined(_WIN32)
static int
mode_t_to_hex(mode_t mode)
{
int hex = 0;
hex |= (mode & S_ISUID) ? 0x4000 : 0;
hex |= (mode & S_ISGID) ? 0x2000 : 0;
hex |= (mode & S_ISVTX) ? 0x1000 : 0;
hex |= (mode & S_IRUSR) ? 0x0400 : 0;
hex |= (mode & S_IWUSR) ? 0x0200 : 0;
hex |= (mode & S_IXUSR) ? 0x0100 : 0;
hex |= (mode & S_IRGRP) ? 0x0040 : 0;
hex |= (mode & S_IWGRP) ? 0x0020 : 0;
hex |= (mode & S_IXGRP) ? 0x0010 : 0;
hex |= (mode & S_IROTH) ? 0x0004 : 0;
hex |= (mode & S_IWOTH) ? 0x0002 : 0;
hex |= (mode & S_IXOTH) ? 0x0001 : 0;
return hex;
}
#endif
/*****************************************************************************/
/* returns error */
int
@ -2330,22 +2379,22 @@ g_chmod_hex(const char *filename, int flags)
#if defined(_WIN32)
return 0;
#else
int fl;
mode_t m = hex_to_mode_t(flags);
return chmod(filename, m);
#endif
}
fl = 0;
fl |= (flags & 0x4000) ? S_ISUID : 0;
fl |= (flags & 0x2000) ? S_ISGID : 0;
fl |= (flags & 0x1000) ? S_ISVTX : 0;
fl |= (flags & 0x0400) ? S_IRUSR : 0;
fl |= (flags & 0x0200) ? S_IWUSR : 0;
fl |= (flags & 0x0100) ? S_IXUSR : 0;
fl |= (flags & 0x0040) ? S_IRGRP : 0;
fl |= (flags & 0x0020) ? S_IWGRP : 0;
fl |= (flags & 0x0010) ? S_IXGRP : 0;
fl |= (flags & 0x0004) ? S_IROTH : 0;
fl |= (flags & 0x0002) ? S_IWOTH : 0;
fl |= (flags & 0x0001) ? S_IXOTH : 0;
return chmod(filename, fl);
/*****************************************************************************/
/* returns error */
int
g_umask_hex(int flags)
{
#if defined(_WIN32)
return flags;
#else
mode_t m = hex_to_mode_t(flags);
m = umask(m);
return mode_t_to_hex(m);
#endif
}

View File

@ -128,6 +128,7 @@ int g_file_write(int fd, const char *ptr, int len);
int g_file_seek(int fd, int offset);
int g_file_lock(int fd, int start, int len);
int g_chmod_hex(const char *filename, int flags);
int g_umask_hex(int flags);
int g_chown(const char *name, int uid, int gid);
int g_mkdir(const char *dirname);
char *g_get_current_dir(char *dirname, int maxlen);

View File

@ -28,6 +28,7 @@
#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 */
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR

View File

@ -52,10 +52,16 @@ AC_CHECK_SIZEOF([void *])
AC_ARG_WITH([socketdir],
[AS_HELP_STRING([--with-socketdir=DIR],
[Use directory for UNIX sockets (default: /tmp/.xrdp)])],
[], [with_socketdir="/tmp/.xrdp"])
[Use directory for UNIX sockets for XRDP sessions (default: RUNSTATEDIR/xrdp)])],
[], [with_socketdir="$runstatedir/xrdp"])
AC_SUBST([socketdir], [$with_socketdir])
AC_ARG_WITH([sesmanruntimedir],
[AS_HELP_STRING([--with-sesmanruntimedir=DIR],
[Use directory for sesman runtime data (default: RUNSTATEDIR/xrdp-sesman))])],
[], [with_sesmanruntimedir="$runstatedir/xrdp-sesman"])
AC_SUBST([sesmanruntimedir], [$with_sesmanruntimedir])
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files, no to disable]),
[], [
@ -547,6 +553,10 @@ echo " exec_prefix $exec_prefix"
echo " libdir $libdir"
echo " bindir $bindir"
echo " sysconfdir $sysconfdir"
echo " localstatedir $localstatedir"
echo " runstatedir $runstatedir"
echo " socketdir $socketdir"
echo " sesmanruntimedir $sesmanruntimedir"
echo ""
echo " unit tests performable $perform_unit_tests"
echo ""

View File

@ -19,6 +19,7 @@ SUBST_VARS = sed \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@socketdir[@]|$(socketdir)|g' \
-e 's|@sesmanruntimedir[@]|$(sesmanruntimedir)|g' \
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \
-e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g'

View File

@ -50,13 +50,19 @@ outside their proper section will be \fIignored\fR.
Following parameters can be used in the \fB[Globals]\fR section.
.TP
\fBListenAddress\fR=\fIip address\fR
xrdp-sesman listening address. If not specified, defaults to \fI0.0.0.0\fR
(all interfaces).
.TP
\fBListenPort\fR=\fIport number\fR
xrdp-sesman listening port. If not specified, defaults to \fI3350\fR.
\fBListenPort\fR=\fIpath-to-socket\fR
UNIX domain socket for xrdp-sesman(8) to listen on.
.PP
.RS
The default value of this setting is 'sesman.socket'.
.PP
An absoute path can be specified by starting this parameter with a '/'.
In this instance, the system administrator is responsible for ensuring
the socket can only be created by a suitably privileged process.
.PP
If the parameter does not start with a '/', a name within
@sesmanruntimedir@ is used.
.RE
.TP
\fBEnableUserWindowManager\fR=\fI[true|false]\fR

View File

@ -26,15 +26,11 @@ Defaults to \fBroot\fP.
The \fIpassword\fP to authenticate with.
The default is to ask for the password interactively.
.TP
.BI \-s= server
The host address of the \fIserver\fP to connect to.
Defaults to \fBlocalhost\fP.
.TP
.BI \-i= port
The TCP \fIport\fP number to connect to.
Defaults to \fB3350\fP.
The sesman \fIUNIX domain socket\fP to connect to.
Defaults to \fBsesman.socket\fP.
If no path is specified for the socket, a default of @sesmanruntimedir@ is used.
.TP
.BI \-c= command

View File

@ -58,6 +58,8 @@ to read it.
@localstatedir@/log/xrdp\-sesman.log
.br
@localstatedir@/run/xrdp\-sesman.pid
.br
@sesmanruntimedir@/sesman.socket
.SH "AUTHORS"
Jay Sorg <jsorg71@users.sourceforge.net>

View File

@ -29,11 +29,6 @@ option may not do what you expect.
Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
will ignore this setting.
.TP
.B -s <server>
Server on which sesman is running (probably 'localhost').
.br
Use of this option is discouraged as it will be removed in the future.
.TP
.B -t <session-type>
Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
only, use the numeric session code.

View File

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

View File

@ -33,6 +33,7 @@
#include "trans.h"
#include "os_calls.h"
#include "string_calls.h"
#include "xrdp_sockets.h"
/*****************************************************************************/
static const char *
@ -66,28 +67,97 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size)
return buff;
}
/*****************************************************************************/
int
scp_port_to_unix_domain_path(const char *port, char *buff,
unsigned int bufflen)
{
/* GOTCHA: Changes to this logic should be mirrored in
* scp_port_to_display_string() */
int result;
/* Make sure we can safely de-reference 'port' */
if (port == NULL)
{
port = "";
}
if (port[0] == '/')
{
result = g_snprintf(buff, bufflen, "%s", port);
}
else
{
const char *sep;
if ((sep = g_strrchr(port, '/')) != NULL && sep != port)
{
/* We allow the user to specify an absolute path, but not
* a relative one with embedded '/' characters */
LOG(LOG_LEVEL_WARNING, "Ignoring path elements of '%s'", port);
port = sep + 1;
}
if (port[0] == '\0')
{
port = SCP_LISTEN_PORT_BASE_STR;
}
else if (g_strcmp(port, "3350") == 0)
{
/* Version v0.9.x and earlier of xrdp used a TCP port
* number. If we come across this, we'll ignore it for
* compatibility with old config files */
LOG(LOG_LEVEL_WARNING,
"Ignoring obsolete SCP port value '%s'", port);
port = SCP_LISTEN_PORT_BASE_STR;
}
result = g_snprintf(buff, bufflen, SESMAN_RUNTIME_PATH "/%s", port);
}
return result;
}
/*****************************************************************************/
int
scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen)
{
/* Make sure we can safely de-reference 'port' */
if (port == NULL)
{
port = "";
}
/* Ignore any directories for the display */
const char *sep;
if ((sep = g_strrchr(port, '/')) != NULL)
{
port = sep + 1;
}
/* Check for a default */
if (port[0] == '\0' || g_strcmp(port, "3350") == 0)
{
port = SCP_LISTEN_PORT_BASE_STR;
}
return g_snprintf(buff, bufflen, "%s", port);
}
/*****************************************************************************/
struct trans *
scp_connect(const char *host, const char *port,
scp_connect(const char *port,
int (*term_func)(void))
{
char sock_path[256];
struct trans *t;
if ((t = trans_create(TRANS_MODE_TCP, 128, 128)) != NULL)
(void)scp_port_to_unix_domain_path(port, sock_path, sizeof(sock_path));
if ((t = trans_create(TRANS_MODE_UNIX, 128, 128)) != NULL)
{
if (host == NULL)
{
host = "localhost";
}
if (port == NULL)
{
port = "3350";
}
t->is_term = term_func;
trans_connect(t, host, port, 3000);
if (t->status != TRANS_STATUS_UP)
if (trans_connect(t, NULL, sock_path, 3000) != 0)
{
trans_delete(t);
t = NULL;

View File

@ -65,11 +65,38 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size);
/* Connection management facilities */
/**
* Maps a port definition to a UNIX domain socket path
* @param port Port definition (e.g. from sesman.ini). Can be "" or NULL
* @param buff Buffer for result
* @param bufflen Length of buff
*
* @return Number of chars needed for result, excluding the '\0'
*/
int
scp_port_to_unix_domain_path(const char *port, char *buff,
unsigned int bufflen);
/**
* Maps a port definition to a displayable string
* @param port Port definition (e.g. from sesman.ini). Can be "" or NULL
* @param buff Buffer for result
* @param bufflen Length of buff
*
* @return Number of chars needed for result, excluding the '\0'
*
* This differs from scp_port_to_unix_domain_path() in that the result is
* for displaying to the user (i.e. in a status message), rather than for
* connecting to. For log messages, use the result of
* scp_port_to_unix_domain_path()
*/
int
scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen);
/**
* Connect to an SCP server
*
* @param host Host providing SCP service
* @param port TCP port for SCP service
* @param port Port definition (e.g. from sesman.ini)
* @param term_func Function to poll during connection for program
* termination, or NULL for none.
* @return Initialised SCP transport
@ -77,7 +104,7 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size);
* The returned tranport has the is_term member set to term_func.
*/
struct trans *
scp_connect(const char *host, const char *port,
scp_connect(const char *port,
int (*term_func)(void));
/**

View File

@ -8,6 +8,7 @@ AM_CPPFLAGS = \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
-I$(top_srcdir)/common \
-I$(top_srcdir)/libipm
@ -45,6 +46,8 @@ xrdp_sesman_SOURCES = \
config.h \
env.c \
env.h \
lock_uds.c \
lock_uds.h \
scp_process.c \
scp_process.h \
sesman.c \

View File

@ -35,6 +35,7 @@
#include "log.h"
#include "string_calls.h"
#include "chansrv/chansrv_common.h"
#include "scp.h"
/***************************************************************************//**
*
@ -51,14 +52,11 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
struct list *param_v)
{
int i;
int length;
char *buf;
list_clear(param_v);
list_clear(param_n);
/* resetting the struct */
cf->listen_address[0] = '\0';
cf->listen_port[0] = '\0';
cf->enable_user_wm = 0;
cf->user_wm[0] = '\0';
@ -70,47 +68,50 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
for (i = 0; i < param_n->count; i++)
{
buf = (char *)list_get_item(param_n, i);
const char *param = (const char *)list_get_item(param_n, i);
const char *val = (const char *)list_get_item(param_v, i);
if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM))
if (0 == g_strcasecmp(param, SESMAN_CFG_DEFWM))
{
cf->default_wm = g_strdup((char *)list_get_item(param_v, i));
cf->default_wm = g_strdup(val);
}
else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM))
else if (0 == g_strcasecmp(param, SESMAN_CFG_USERWM))
{
g_strncpy(cf->user_wm, (char *)list_get_item(param_v, i), 31);
g_strncpy(cf->user_wm, val, sizeof(cf->user_wm) - 1);
}
else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM))
else if (0 == g_strcasecmp(param, SESMAN_CFG_ENABLE_USERWM))
{
cf->enable_user_wm = g_text2bool((char *)list_get_item(param_v, i));
cf->enable_user_wm = g_text2bool(val);
}
else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT))
else if (0 == g_strcasecmp(param, SESMAN_CFG_PORT))
{
g_strncpy(cf->listen_port, (char *)list_get_item(param_v, i), 15);
scp_port_to_unix_domain_path(val, cf->listen_port,
sizeof(cf->listen_port));
}
else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS))
else if (0 == g_strcasecmp(param, SESMAN_CFG_AUTH_FILE_PATH))
{
g_strncpy(cf->listen_address, (char *)list_get_item(param_v, i), 31);
cf->auth_file_path = g_strdup(val);
}
else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH))
else if (g_strcasecmp(param, SESMAN_CFG_RECONNECT_SH) == 0)
{
cf->auth_file_path = g_strdup((char *)list_get_item(param_v, i));
cf->reconnect_sh = g_strdup(val);
}
else if (g_strcasecmp(buf, SESMAN_CFG_RECONNECT_SH) == 0)
else if (0 == g_strcasecmp(param, SESMAN_CFG_ADDRESS))
{
cf->reconnect_sh = g_strdup((char *)list_get_item(param_v, i));
/* Config must be updated for Unix Domain Sockets */
LOG(LOG_LEVEL_WARNING, "Obsolete setting' " SESMAN_CFG_ADDRESS
"' in [" SESMAN_CFG_GLOBALS "] should be removed.");
LOG(LOG_LEVEL_WARNING, "Review setting' " SESMAN_CFG_PORT "' in ["
SESMAN_CFG_GLOBALS "]");
}
}
/* checking for missing required parameters */
if ('\0' == cf->listen_address[0])
{
g_strncpy(cf->listen_address, "0.0.0.0", 8);
}
if ('\0' == cf->listen_port[0])
{
g_strncpy(cf->listen_port, "3350", 5);
/* Load the default value */
scp_port_to_unix_domain_path(NULL, cf->listen_port,
sizeof(cf->listen_port));
}
if ('\0' == cf->user_wm[0])
@ -118,46 +119,40 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
cf->enable_user_wm = 0;
}
if (cf->default_wm == 0)
{
cf->default_wm = g_strdup("startwm.sh");
}
else if (g_strlen(cf->default_wm) == 0)
if (cf->default_wm == 0 || cf->default_wm[0] == '\0')
{
g_free(cf->default_wm);
cf->default_wm = g_strdup("startwm.sh");
}
/* if default_wm doesn't begin with '/', it's a relative path to XRDP_CFG_PATH */
/* if default_wm doesn't begin with '/', it's a relative path to
* XRDP_CFG_PATH */
if (cf->default_wm[0] != '/')
{
/* sizeof operator returns string length including null terminator */
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->default_wm) + 1; /* '/' */
buf = (char *)g_malloc(length, 0);
int length = (sizeof(XRDP_CFG_PATH) +
g_strlen(cf->default_wm) + 1); /* '/' */
char *buf = (char *)g_malloc(length, 0);
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->default_wm);
g_free(cf->default_wm);
cf->default_wm = g_strdup(buf);
g_free(buf);
cf->default_wm = buf;
}
if (cf->reconnect_sh == 0)
{
cf->reconnect_sh = g_strdup("reconnectwm.sh");
}
else if (g_strlen(cf->reconnect_sh) == 0)
if (cf->reconnect_sh == 0 || cf->reconnect_sh[0] == '\0')
{
g_free(cf->reconnect_sh);
cf->reconnect_sh = g_strdup("reconnectwm.sh");
}
/* if reconnect_sh doesn't begin with '/', it's a relative path to XRDP_CFG_PATH */
/* if reconnect_sh doesn't begin with '/', it's a relative path to
* XRDP_CFG_PATH */
if (cf->reconnect_sh[0] != '/')
{
/* sizeof operator returns string length including null terminator */
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->reconnect_sh) + 1; /* '/' */
buf = (char *)g_malloc(length, 0);
int length = (sizeof(XRDP_CFG_PATH) +
g_strlen(cf->reconnect_sh) + 1); /* '/' */
char *buf = (char *)g_malloc(length, 0);
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->reconnect_sh);
g_free(cf->reconnect_sh);
cf->reconnect_sh = g_strdup(buf);
g_free(buf);
cf->reconnect_sh = buf;
}
return 0;
@ -530,6 +525,7 @@ config_read(const char *sesman_ini)
param_n->auto_free = 1;
param_v = list_create();
param_v->auto_free = 1;
all_ok = 1;
/* read global config */
config_read_globals(fd, cfg, param_n, param_v);
@ -552,7 +548,6 @@ config_read(const char *sesman_ini)
list_delete(param_v);
list_delete(param_n);
g_file_close(fd);
all_ok = 1;
}
}
}
@ -579,14 +574,13 @@ config_dump(struct config_sesman *config)
/* Global sesman configuration */
g_writeln("Filename: %s", config->sesman_ini);
g_writeln("Global configuration:");
g_writeln(" ListenAddress: %s", config->listen_address);
g_writeln(" ListenPort: %s", config->listen_port);
g_writeln(" EnableUserWindowManager: %d", config->enable_user_wm);
g_writeln(" UserWindowManager: %s", config->user_wm);
g_writeln(" DefaultWindowManager: %s", config->default_wm);
g_writeln(" ReconnectScript: %s", config->reconnect_sh);
g_writeln(" AuthFilePath: %s",
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
(config->auth_file_path ? config->auth_file_path : "disabled"));
/* Session configuration */
g_writeln("Session configuration:");

View File

@ -201,16 +201,11 @@ struct config_sesman
*/
char *sesman_ini;
/**
* @var listen_address
* @brief Listening address
*/
char listen_address[32];
/**
* @var listen_port
* @brief Listening port
*/
char listen_port[16];
char listen_port[256];
/**
* @var enable_user_wm
* @brief Flag that enables user specific wm

146
sesman/lock_uds.c Normal file
View File

@ -0,0 +1,146 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) 2022 Matt Burt, all xrdp contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
* @file lock_uds.c
* @brief Providing a locking facility for Unix Domain Sockets
* @author Matt Burt
*
* It is difficult for a server to determine whether a socket it wishes
* to listen on is already active or not. The purpose of this module is to
* provide a locking facility which can be used as a proxy for this.
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "arch.h"
#include "os_calls.h"
#include "string_calls.h"
#include "log.h"
#include "lock_uds.h"
struct lock_uds
{
char *filename; ///<< Name of the lock file
int fd; ///<< File decriptor for open file
int pid; ///<< PID of process originally taking out lock
};
/******************************************************************************/
struct lock_uds *
lock_uds(const char *sockname)
{
struct lock_uds *lock = NULL;
char *filename = NULL;
int fd = -1;
if (sockname == NULL || sockname[0] != '/')
{
LOG_DEVEL(LOG_LEVEL_ERROR, "Invalid sockname '%s'",
(sockname == NULL) ? "<null>" : sockname);
}
else
{
/* Allocate space for lock filename and result */
filename = (char *)g_malloc(g_strlen(sockname) + 1 + 5 + 1, 0);
lock = g_new0(struct lock_uds, 1);
if (lock == NULL || filename == NULL)
{
LOG(LOG_LEVEL_ERROR, "%s : Out of memory", __func__);
}
else
{
int saved_umask;
/* Construct the filename */
/* This call is guaranteed to succeed as we know that sockname
* contains at least one '/' */
char *p = filename;
const char *basename = g_strrchr(sockname, '/') + 1;
g_memcpy(p, sockname, basename - sockname);
p += basename - sockname;
*p++ = '.';
g_strcpy(p, basename);
p += g_strlen(p);
*p++ = '.';
*p++ = 'l';
*p++ = 'o';
*p++ = 'c';
*p++ = 'k';
*p++ = '\0';
saved_umask = g_umask_hex(0x77);
fd = g_file_open(filename);
g_umask_hex(saved_umask);
if (fd < 0)
{
LOG(LOG_LEVEL_ERROR, "Unable to create '%s' [%s]",
filename, g_get_strerror());
}
else if (g_file_lock(fd, 0, 0) == 0)
{
LOG(LOG_LEVEL_ERROR, "Unable to get lock for '%s' - "
"program already running?", sockname);
g_file_close(fd);
fd = -1;
}
}
}
if (fd >= 0)
{
/* Success - finish off */
lock->filename = filename;
lock->fd = fd;
lock->pid = g_getpid();
}
else
{
g_free(filename);
g_free(lock);
lock = NULL;
}
return lock;
}
/******************************************************************************/
void
unlock_uds(struct lock_uds *lock)
{
if (lock != NULL)
{
if (lock->fd >= 0)
{
g_file_close(lock->fd);
lock->fd = -1; // In case of use-after-free
}
/* Only delete the lock file if we are the process which
* created it */
if (g_getpid() == lock->pid)
{
g_file_delete(lock->filename);
}
g_free(lock->filename);
lock->filename = NULL;
g_free(lock);
}
}

59
sesman/lock_uds.h Normal file
View File

@ -0,0 +1,59 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) 2022 Matt Burt, all xrdp contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
* @file lock_uds.h
* @brief Providing a locking facility for Unix Domain Sockets
* @author Matt Burt
*
* It is difficult for a server to determine whether a socket it wishes
* to listen on is already active or not. The purpose of this module is to
* provide a locking facility which can be used as a proxy for this.
*/
#ifndef LOCK_UDS_H
#define LOCK_UDS_H
struct lock_uds;
/**
* Take out a lock for the specified Unix Domain socket
* @param sockname Name of socket. Must start with a '/'
* @return A struct lock_uds instance if the lock was successfully acquired.
*
* A NULL return may indicate a lack of memory, or that another
* process has the lock.
*
* A file is created in the same directory as the socket. The name
* of the file is ".${basename}.lock", where basename is the base name
* of the socket. THE file is removed when the lock is relinquished. */
struct lock_uds *
lock_uds(const char *sockname);
/**
* Relinquish a lock on the specified Unix Domain Socket.
* @param lock to relinquish
*
* If the process which has originally taken out the lock forks, this
* routine should be called from the child process to prevent the lock
* inadvertently being passed to the child. */
void
unlock_uds(struct lock_uds *lock);
#endif // LOCK_UDS_H

View File

@ -36,6 +36,7 @@
#include "trans.h"
#include "scp_process.h"
#include "lock_uds.h"
/**
* Maximum number of short-lived connections to sesman
@ -70,6 +71,10 @@ struct sesman_con
};
static struct trans *g_list_trans;
/* Variables used to lock g_list_trans */
static struct lock_uds *g_list_trans_lock;
static struct list *g_con_list = NULL;
static int g_pid;
@ -206,45 +211,52 @@ sesman_process_params(int argc, char **argv,
}
/******************************************************************************/
static int sesman_listen_test(struct config_sesman *cfg)
static int
create_sesman_runtime_dir(void)
{
int error;
int sck;
int rv = 0;
int rv = -1;
/* Make sure if we create the directory, there's no gap where it
* may have the wrong permissions */
int entry_umask = g_umask_hex(0x755);
sck = g_tcp_socket();
if (sck < 0)
if (!g_directory_exist(SESMAN_RUNTIME_PATH) &&
!g_create_dir(SESMAN_RUNTIME_PATH))
{
return 1;
LOG(LOG_LEVEL_ERROR,
"Can't create runtime directory '"
SESMAN_RUNTIME_PATH "' [%s]", g_get_strerror());
}
LOG(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.",
cfg->listen_address, cfg->listen_port);
g_tcp_set_non_blocking(sck);
error = g_tcp_bind_address(sck, cfg->listen_port, cfg->listen_address);
if (error == 0)
else if (g_chown(SESMAN_RUNTIME_PATH, g_getuid(), g_getuid()) != 0)
{
/* try to listen */
error = g_tcp_listen(sck);
if (error == 0)
{
/* if listen succeeded, stop listen immediately */
g_sck_close(sck);
}
else
{
rv = 1;
}
LOG(LOG_LEVEL_ERROR,
"Can't set ownership of sesman runtime directory [%s]",
g_get_strerror());
}
else if (g_chmod_hex(SESMAN_RUNTIME_PATH, 0x755) != 0)
{
/* This might seem redundant, but there's a chance the
* directory already exists */
LOG(LOG_LEVEL_ERROR,
"Can't set permissions of sesman runtime directory [%s]",
g_get_strerror());
}
else
{
rv = 1;
rv = 0;
}
g_umask_hex(entry_umask);
return rv;
}
/******************************************************************************/
static int sesman_listen_test(struct config_sesman *cfg)
{
int status = sesman_create_listening_transport(cfg);
sesman_delete_listening_transport();
return status;
}
/******************************************************************************/
int
sesman_close_all(void)
@ -357,8 +369,18 @@ set_reload_event(int sig)
void
sesman_delete_listening_transport(void)
{
trans_delete(g_list_trans);
if (g_getpid() == g_pid)
{
trans_delete(g_list_trans);
}
else
{
trans_delete_from_child(g_list_trans);
}
g_list_trans = NULL;
unlock_uds(g_list_trans_lock);
g_list_trans_lock = NULL;
}
/******************************************************************************/
@ -366,26 +388,43 @@ int
sesman_create_listening_transport(const struct config_sesman *cfg)
{
int rv = 1;
g_list_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
g_list_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
if (g_list_trans == NULL)
{
LOG(LOG_LEVEL_ERROR, "%s: trans_create failed", __func__);
}
else
else if ((g_list_trans_lock = lock_uds(cfg->listen_port)) != NULL)
{
LOG(LOG_LEVEL_DEBUG, "%s: address %s port %s",
__func__, cfg->listen_address, cfg->listen_port);
rv = trans_listen_address(g_list_trans, cfg->listen_port,
cfg->listen_address);
/* Make sure the file is always created with the correct
* permissions, if it's not there */
int entry_umask = g_umask_hex(0x666);
LOG_DEVEL(LOG_LEVEL_DEBUG, "%s: port %s", __func__, cfg->listen_port);
rv = trans_listen_address(g_list_trans, cfg->listen_port, NULL);
if (rv != 0)
{
LOG(LOG_LEVEL_ERROR, "%s: trans_listen_address failed", __func__);
sesman_delete_listening_transport();
}
else if (g_chown(cfg->listen_port, g_getuid(), g_getuid()) != 0)
{
LOG(LOG_LEVEL_ERROR,
"Can't set ownership of '%s' [%s]",
cfg->listen_port, g_get_strerror());
}
else if ((rv = g_chmod_hex(cfg->listen_port, 0x666)) != 0)
{
LOG(LOG_LEVEL_ERROR, "%s: Can't set permissions on '%s' [%s]",
__func__, cfg->listen_port, g_get_strerror());
}
else
{
g_list_trans->trans_conn_in = sesman_listen_conn_in;
}
g_umask_hex(entry_umask);
}
if (rv != 0)
{
sesman_delete_listening_transport();
}
return rv;
@ -422,6 +461,7 @@ sesman_main_loop(void)
list_delete(g_con_list);
return 1;
}
LOG(LOG_LEVEL_INFO, "Sesman now listening on %s", g_cfg->listen_port);
error = 0;
while (!error)
@ -722,7 +762,6 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__);
LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini);
LOG(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address);
LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port);
LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm);
LOG(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm);
@ -751,6 +790,16 @@ main(int argc, char **argv)
}
}
/* Create the runtime directory before we try to listen (or
* test-listen), so there's somewhere for the default socket to live */
if (create_sesman_runtime_dir() != 0)
{
config_free(g_cfg);
log_end();
g_deinit();
g_exit(1);
}
if (daemon)
{
/* start of daemonizing code */
@ -759,6 +808,7 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, "
"possibly address already in use.");
config_free(g_cfg);
log_end();
g_deinit();
g_exit(1);
}
@ -766,14 +816,17 @@ main(int argc, char **argv)
if (0 != g_fork())
{
config_free(g_cfg);
log_end();
g_deinit();
g_exit(0);
}
}
/* signal handling */
/* Now we've forked (if necessary), we can get the prgram PID */
g_pid = g_getpid();
/* signal handling */
g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid);
g_term_event = g_create_wait_obj(text);
g_snprintf(text, 255, "xrdp_sesman_%8.8x_sigchld", g_pid);

View File

@ -1,8 +1,8 @@
;; See `man 5 sesman.ini` for details
[Globals]
ListenAddress=127.0.0.1
ListenPort=3350
; listening port
#ListenPort=sesman.socket
EnableUserWindowManager=true
; Give in relative path to user's home directory
UserWindowManager=startwm.sh

View File

@ -47,16 +47,19 @@ sig_sesman_reload_cfg(void)
}
/* Deal with significant config changes */
if (g_strcmp(g_cfg->listen_address, cfg->listen_address) != 0 ||
g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
if (g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
{
LOG(LOG_LEVEL_INFO, "sesman listen address changed to %s:%s",
cfg->listen_address, cfg->listen_port);
LOG(LOG_LEVEL_INFO, "sesman listen port changed to %s",
cfg->listen_port);
/* We have to delete the old port before listening to the new one
* in case they overlap in scope */
sesman_delete_listening_transport();
sesman_create_listening_transport(cfg);
if (sesman_create_listening_transport(cfg) == 0)
{
LOG(LOG_LEVEL_INFO, "Sesman now listening on %s",
g_cfg->listen_port);
}
}
/* free old config data */

View File

@ -34,7 +34,6 @@
char user[257];
char pass[257];
char cmnd[257];
char serv[257];
char port[257];
static int cmndList(struct trans *t);
@ -55,7 +54,6 @@ int main(int argc, char **argv)
user[0] = '\0';
pass[0] = '\0';
cmnd[0] = '\0';
serv[0] = '\0';
port[0] = '\0';
logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL);
@ -72,10 +70,6 @@ int main(int argc, char **argv)
{
g_strncpy(pass, (argv[idx]) + 3, 256);
}
else if (0 == g_strncmp(argv[idx], "-s=", 3))
{
g_strncpy(serv, (argv[idx]) + 3, 256);
}
else if (0 == g_strncmp(argv[idx], "-i=", 3))
{
g_strncpy(port, (argv[idx]) + 3, 256);
@ -86,11 +80,6 @@ int main(int argc, char **argv)
}
}
if (0 == g_strncmp(serv, "", 1))
{
g_strncpy(serv, "localhost", 256);
}
if (0 == g_strncmp(port, "", 1))
{
g_strncpy(port, "3350", 256);
@ -115,7 +104,7 @@ int main(int argc, char **argv)
}
t = scp_connect(serv, port, NULL);
t = scp_connect(port, NULL);
if (t == NULL)

View File

@ -63,10 +63,6 @@
# define DEFAULT_BPP 32
#endif
#ifndef DEFAULT_SERVER
# define DEFAULT_SERVER "localhost"
#endif
#ifndef DEFAULT_TYPE
# define DEFAULT_TYPE "Xorg"
#endif
@ -95,7 +91,6 @@ struct session_params
int height;
int bpp;
enum scp_session_type session_type;
const char *server;
const char *directory;
const char *shell;
@ -175,9 +170,6 @@ usage(void)
g_printf(" -g <geometry> Default:%dx%d\n",
DEFAULT_WIDTH, DEFAULT_HEIGHT);
g_printf(" -b <bits-per-pixel> Default:%d\n", DEFAULT_BPP);
/* Don't encourage use of this one - we need to move to local sockets */
g_printf(" -s <server> Default:%s (Deprecated)\n",
DEFAULT_SERVER);
g_printf(" -t <type> Default:%s\n", DEFAULT_TYPE);
g_printf(" -D <directory> Default: $HOME\n"
" -S <shell> Default: Defined window manager\n"
@ -291,7 +283,6 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
sp->height = DEFAULT_HEIGHT;
sp->bpp = DEFAULT_BPP;
(void)string_to_session_type(DEFAULT_TYPE, &sp->session_type);
sp->server = DEFAULT_SERVER;
sp->directory = "";
sp->shell = "";
@ -315,11 +306,6 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
sp->bpp = atoi(optarg);
break;
case 's':
LOG(LOG_LEVEL_WARNING, "Using deprecated option '-s'");
sp->server = optarg;
break;
case 't':
if (string_to_session_type(optarg, &sp->session_type) != 0)
{
@ -419,10 +405,10 @@ send_create_session_request(struct trans *t, const struct session_params *sp)
{
LOG(LOG_LEVEL_DEBUG,
"width:%d height:%d bpp:%d code:%d\n"
"server:\"%s\" directory:\"%s\"\n"
"directory:\"%s\"\n"
"shell:\"%s\" connection_description:\"%s\"",
sp->width, sp->height, sp->bpp, sp->session_type,
sp->server, sp->directory,
sp->directory,
sp->shell, sp->connection_description);
/* Only log the password in development builds */
LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
@ -498,7 +484,7 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s",
sesman_ini, g_get_strerror());
}
else if (!(t = scp_connect(sp.server, cfg->listen_port, NULL)))
else if (!(t = scp_connect(cfg->listen_port, NULL)))
{
LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror());
}

View File

@ -223,7 +223,6 @@ name=Xorg
lib=libxup.@lib_extension@
username=ask
password=ask
ip=127.0.0.1
port=-1
code=20
@ -232,7 +231,6 @@ name=Xvnc
lib=libvnc.@lib_extension@
username=ask
password=ask
ip=127.0.0.1
port=-1
#xserverbpp=24
#delay_ms=2000
@ -256,7 +254,6 @@ username=na
password=ask
#pamusername=asksame
#pampassword=asksame
#pamsessionmng=127.0.0.1
#delay_ms=2000
; Generic RDP proxy using NeutrinoRDP
@ -275,7 +272,6 @@ password=ask
; connections.
#pamusername=ask
#pampassword=ask
#pamsessionmng=127.0.0.1
; Currently NeutrinoRDP doesn't support dynamic resizing. Uncomment
; this line if you're using a client which does.
#enable_dynamic_resizing=false

View File

@ -51,7 +51,7 @@ getPAMError(const int pamError, char *text, int text_bytes);
static const char *
getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self);
static int
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port);
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port);
static void
xrdp_mm_connect_sm(struct xrdp_mm *self);
@ -159,8 +159,6 @@ xrdp_mm_delete(struct xrdp_mm *self)
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = 0;
list_delete(self->login_names);
list_delete(self->login_values);
g_free(self);
@ -229,7 +227,7 @@ xrdp_mm_send_gateway_login(struct xrdp_mm *self, const char *username,
"sending login info to session manager, please wait...");
return scp_send_gateway_request(
self->pam_auth_trans, username, password,
self->sesman_trans, username, password,
self->wm->client_info->connection_description);
}
@ -475,7 +473,6 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
int rv;
int key_flags;
int device_flags;
int use_uds;
rv = 1; /* failure */
g_memset(text, 0, sizeof(text));
@ -500,22 +497,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
}
else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
{
use_uds = 1;
if ((value = xrdp_mm_get_value(self, "ip")) != NULL &&
g_strcmp(value, "127.0.0.1") != 0)
{
use_uds = 0;
}
if (use_uds)
{
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
}
else
{
g_snprintf(text, 255, "%d", 6200 + self->display);
}
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
}
else
{
@ -1691,10 +1673,9 @@ xrdp_mm_chan_data_in(struct trans *trans)
static void cleanup_sesman_connection(struct xrdp_mm *self)
{
/* Don't delete these transports here - we may be in
/* Don't delete any transports here - we may be in
* an auth callback from one of them */
self->delete_sesman_trans = 1;
self->delete_pam_auth_trans = 1;
if (self->wm->login_state != WMLS_CLEANUP)
{
@ -1861,16 +1842,12 @@ xrdp_mm_process_gateway_response(struct xrdp_mm *self)
int auth_result;
int rv;
rv = scp_get_gateway_response(self->pam_auth_trans, &auth_result);
rv = scp_get_gateway_response(self->sesman_trans, &auth_result);
if (rv == 0)
{
const char *additionalError;
char pam_error[128];
/* We no longer need the pam_auth transport - it's only used
* for the one message */
self->delete_pam_auth_trans = 1;
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
"Reply from access control: %s",
getPAMError(auth_result,
@ -1987,11 +1964,8 @@ xrdp_mm_scp_data_in(struct trans *trans)
{
char buff[64];
scp_msgno_to_str(msgno, buff, sizeof(buff));
const char *src = (trans == self->pam_auth_trans)
? "PAM authenticator"
: "sesman";
LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from %s",
buff, src);
LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from sesman",
buff);
}
}
@ -2015,10 +1989,8 @@ cleanup_states(struct xrdp_mm *self)
self->use_chansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
self->use_pam_auth = 0; /* true if we're to use the PAM authentication facility */
self->sesman_trans = NULL; /* connection to sesman */
self->pam_auth_trans = NULL; /* connection to PAM authenticator */
self->chan_trans = NULL; /* connection to chansrv */
self->delete_sesman_trans = 0;
self->delete_pam_auth_trans = 0;
self->display = 0; /* 10 for :10.0, 11 for :11.0, etc */
guid_clear(&self->guid);
self->code = 0; /* 0 Xvnc session, 10 X11rdp session, 20 Xorg session */
@ -2304,28 +2276,31 @@ parse_chansrvport(const char *value, char *dest, int dest_size)
/*****************************************************************************/
static struct trans *
xrdp_mm_scp_connect(struct xrdp_mm *self, const char *target, const char *ip)
xrdp_mm_scp_connect(struct xrdp_mm *self)
{
char port[128];
char port_description[128];
struct trans *t;
xrdp_mm_get_sesman_port(port, sizeof(port));
scp_port_to_display_string(port,
port_description, sizeof(port_description));
xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
"connecting to %s on %s:%s", target, ip, port);
t = scp_connect(ip, port, g_is_term);
"connecting to sesman on %s", port_description);
t = scp_connect(port, g_is_term);
if (t != NULL)
{
/* fully connected */
t->trans_data_in = xrdp_mm_scp_data_in;
t->callback_data = self;
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s connect ok", target);
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "sesman connect ok");
}
else
{
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
"Error connecting to %s on %s:%s",
target, ip, port);
"Error connecting to sesman on %s", port_description);
trans_delete(t);
t = NULL;
}
@ -2334,27 +2309,17 @@ xrdp_mm_scp_connect(struct xrdp_mm *self, const char *target, const char *ip)
/*****************************************************************************/
static int
xrdp_mm_pam_auth_connect(struct xrdp_mm *self, const char *ip)
{
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = xrdp_mm_scp_connect(self, "PAM authenticator", ip);
return (self->pam_auth_trans == NULL); /* 0 for success */
}
/*****************************************************************************/
static int
xrdp_mm_sesman_connect(struct xrdp_mm *self, const char *ip)
xrdp_mm_sesman_connect(struct xrdp_mm *self)
{
trans_delete(self->sesman_trans);
self->sesman_trans = xrdp_mm_scp_connect(self, "sesman", ip);
self->sesman_trans = xrdp_mm_scp_connect(self);
return (self->sesman_trans == NULL); /* 0 for success */
}
/*****************************************************************************/
static int
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port)
{
if (self->wm->client_info->channels_allowed == 0)
{
@ -2365,16 +2330,7 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
}
/* connect channel redir */
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
}
else
{
/* tcp */
self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
}
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
self->chan_trans->is_term = g_is_term;
self->chan_trans->si = &(self->wm->session->si);
@ -2386,7 +2342,7 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
self->chan_trans->extra_flags = 0;
/* try to connect for up to 10 seconds */
trans_connect(self->chan_trans, ip, port, 10 * 1000);
trans_connect(self->chan_trans, NULL, port, 10 * 1000);
if (self->chan_trans->status != TRANS_STATUS_UP)
{
LOG(LOG_LEVEL_ERROR, "xrdp_mm_chansrv_connect: error in "
@ -2454,10 +2410,26 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (port != NULL && g_strcmp(port, "-1") == 0)
{
self->use_sesman = 1;
/* Connecting to a remote sesman is no longer supported */
if (xrdp_mm_get_value(self, "ip") != NULL)
{
xrdp_wm_log_msg(self->wm,
LOG_LEVEL_WARNING,
"Parameter 'ip' is obsolete for sesman connections."
" Please remove from config");
}
}
if (gateway_username != NULL)
{
/* Connecting to a remote sesman is no longer supported */
if (xrdp_mm_get_value(self, "pamsessionmng") != NULL)
{
xrdp_wm_log_msg(self->wm,
LOG_LEVEL_WARNING,
"Parameter 'pamsessionmng' is obsolete."
" Please remove from config");
}
#ifdef USE_PAM
self->use_pam_auth = 1;
#else
@ -2499,22 +2471,10 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
{
case MMCS_CONNECT_TO_SESMAN:
{
if (self->use_sesman)
if (self->use_sesman || self->use_pam_auth)
{
/* Synchronous call */
const char *ip = xrdp_mm_get_value(self, "ip");
status = xrdp_mm_sesman_connect(self, ip);
}
if (status == 0 && self->use_pam_auth)
{
/* Synchronous call */
const char *ip = xrdp_mm_get_value(self, "pamsessionmng");
if (ip == NULL)
{
ip = xrdp_mm_get_value(self, "ip");
}
status = xrdp_mm_pam_auth_connect(self, ip);
status = xrdp_mm_sesman_connect(self);
}
}
break;
@ -2589,25 +2549,12 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
{
if (self->use_chansrv)
{
const char *ip = "";
char portbuff[256];
if (self->use_sesman)
{
ip = xrdp_mm_get_value(self, "ip");
/* connect channel redir */
if (ip == NULL || (ip[0] == '\0') ||
(g_strcmp(ip, "127.0.0.1") == 0))
{
g_snprintf(portbuff, sizeof(portbuff),
XRDP_CHANSRV_STR, self->display);
}
else
{
g_snprintf(portbuff, sizeof(portbuff),
"%d", 7200 + self->display);
}
g_snprintf(portbuff, sizeof(portbuff),
XRDP_CHANSRV_STR, self->display);
}
else
{
@ -2617,7 +2564,7 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
}
xrdp_mm_update_allowed_channels(self);
xrdp_mm_chansrv_connect(self, ip, portbuff);
xrdp_mm_chansrv_connect(self, portbuff);
}
}
break;
@ -2668,12 +2615,6 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
trans_get_wait_objs(self->sesman_trans, read_objs, rcount);
}
if (self->pam_auth_trans != 0 &&
self->pam_auth_trans->status == TRANS_STATUS_UP)
{
trans_get_wait_objs(self->pam_auth_trans, read_objs, rcount);
}
if ((self->chan_trans != 0) && self->chan_trans->status == TRANS_STATUS_UP)
{
trans_get_wait_objs_rw(self->chan_trans, read_objs, rcount,
@ -2898,22 +2839,6 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->sesman_trans = NULL;
}
if (self->pam_auth_trans != NULL &&
!self->delete_pam_auth_trans &&
self->pam_auth_trans->status == TRANS_STATUS_UP)
{
if (trans_check_wait_objs(self->pam_auth_trans) != 0)
{
self->delete_pam_auth_trans = 1;
}
}
if (self->delete_pam_auth_trans)
{
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = NULL;
}
if (self->chan_trans != NULL &&
self->chan_trans->status == TRANS_STATUS_UP)
{

View File

@ -322,7 +322,6 @@ struct xrdp_mm
int use_pam_auth; /* True if we're to authenticate using PAM */
int use_chansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
struct trans *sesman_trans; /* connection to sesman */
struct trans *pam_auth_trans; /* connection to pam authenticator */
struct trans *chan_trans; /* connection to chansrv */
/* We can't delete transports while we're in a callback for that
@ -330,7 +329,6 @@ struct xrdp_mm
* These flags mark transports as needing to be deleted when
* we are definitely not in a transport callback */
int delete_sesman_trans;
int delete_pam_auth_trans;
struct list *login_names;
struct list *login_values;