regression: Display number related issues

The move away from the X11 display number has introduced a couple of regressions
1) XDG_SESSION_TYPE is not detected properly.

   pam_systemd.so contains code to map a PAM_TTY of ':n' to an 'x11'
   session type. This mapping is no longer done. We could re-introduce
   this code for X11, but there is no such code to detect a wayland
   display type. We try to fix this in a forward-looking way by setting
   XDG_SESSION_TYPE explicity before starting the PAM session.

2) utmp is not being updated correctly.

   The code for setting ut_id in the utmp[x] structure was setting the
   same value for all X11 displays, thus preventing utmp from being able
   to see more than one xrdp user

Also, an include is needed for sesman/eicp_process.c on some systems to
get access to strlcpy()
This commit is contained in:
matt335672
2026-03-11 11:48:48 +00:00
parent 90275daf6d
commit defb1bcba4
4 changed files with 67 additions and 31 deletions
+1
View File
@@ -40,6 +40,7 @@
#include "sesman.h"
#include "sesman_access.h"
#include "sesman_config.h"
#include "string_calls.h"
#include "guid.h"
/******************************************************************************/
+13 -2
View File
@@ -400,9 +400,20 @@ auth_uds(const char *user, enum scp_login_status *errorcode)
static int
auth_start_session_private(struct auth_info *auth_info, const char *display)
{
int error;
// For Linux and maybe other systems, pam_systemd needs to know the
// session type in order to set the session up correctly
const char *session_type;
if (g_get_x11_display_from_display_string(display) >= 0)
{
session_type = "x11";
}
else
{
session_type = "wayland";
}
g_setenv_log("XDG_SESSION_TYPE", session_type, 1);
error = pam_set_item(auth_info->ph, PAM_TTY, display);
int error = pam_set_item(auth_info->ph, PAM_TTY, display);
if (error != PAM_SUCCESS)
{
+13 -2
View File
@@ -209,9 +209,20 @@ auth_uds(const char *user, enum scp_login_status *errorcode)
static int
auth_start_session_private(struct auth_info *auth_info, const char *display)
{
int error;
// For Linux and maybe other systems, pam_systemd needs to know the
// session type in order to set the session up correctly
const char *session_type;
if (g_get_x11_display_from_display_string(display) >= 0)
{
session_type = "x11";
}
else
{
session_type = "wayland";
}
g_setenv_log("XDG_SESSION_TYPE", session_type, 1);
error = pam_set_item(auth_info->ph, PAM_TTY, display);
int error = pam_set_item(auth_info->ph, PAM_TTY, display);
if (error != PAM_SUCCESS)
{
+31 -18
View File
@@ -71,9 +71,9 @@ typedef struct utmp _utmp;
#include "string_calls.h"
#define XRDP_LINE_FORMAT "xrdp:%s"
// ut_id is a very small field on some platforms, so use the display
// number in hex
#define XRDP_ID_FORMAT ":%x"
// ut_id is a very small field on some platforms, so use a discriminator
// (e.g. ':' for x11) and a number in hex
#define XRDP_ID_FORMAT "%c%x"
/******************************************************************************/
/**
@@ -106,30 +106,46 @@ str2memcpy(void *dest, const char *src, size_t n)
/******************************************************************************/
/**
* Get a display number from the display string
* Set the idbuff string
*
* Converts the display string to some sort of number to write to the
* extremely short ut_id field
* @param display string
* @return display number
* The ut_id field is extremely short (e.g. 4 usable characters on
* Linux/FreeBSD).
*
* @param buff Output buffer, including terminator
* @param bufflen Length of above
* @param display Display string for the session
*/
static unsigned int
get_display_num(const char *display)
static void
set_idbuff_str(char buff[], unsigned int bufflen, const char *display)
{
unsigned int result = 0;
unsigned int display_num = 0;
char discriminator;
// X11 display?
int x11_display = g_get_x11_display_from_display_string(display);
if (x11_display >= 0)
{
discriminator = ':';
display_num = (unsigned int)x11_display;
}
else
{
discriminator = 'W';
/* Look for the first digit in the string */
while (*display != '\0' && !isdigit(*display))
{
++display;
}
/* convert consecutive digits to a number */
display_num = 0;
while (*display != '\0' && isdigit(*display))
{
result = (result * 10) + (*display - '0');
display_num = (display_num * 10) + (*display - '0');
++display;
}
return result;
}
display_num = MIN(display_num, 0xfff);
g_snprintf(buff, bufflen, XRDP_ID_FORMAT, discriminator, display_num);
}
/******************************************************************************/
@@ -158,11 +174,8 @@ add_xtmp_entry(int pid, const char *display,
struct timeval tv;
/* Convert the display string to a number */
unsigned int display_num = get_display_num(display);
g_memset(&ut, 0, sizeof(ut));
g_snprintf(idbuff, sizeof(idbuff), XRDP_ID_FORMAT, display_num);
set_idbuff_str(idbuff, sizeof(idbuff), display);
g_snprintf(linebuff, sizeof(linebuff), XRDP_LINE_FORMAT, display);
gettimeofday(&tv, NULL);