Skip to content

Commit 67e0337

Browse files
committed
Updated session allocation policy for sesman
Made session allocation policies more readable and maintainable. The 'C' policy which was confusing before has been replaced with the 'Separate' keyword. This is a public interface change, but is unlikely to affect many users. The logging in session_get_bydata() is substantially improved, making it far easier to spot why sessions are getting matched or not matched.
1 parent b1a61bd commit 67e0337

File tree

5 files changed

+198
-102
lines changed

5 files changed

+198
-102
lines changed

docs/man/sesman.ini.5.in

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,30 +176,34 @@ If set to \fI0\fR, idle sessions will never be disconnected by timeout.
176176
This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
177177

178178
.TP
179-
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
179+
\fBPolicy\fR=\fI[Default|Separate|{UBDI}]\fR
180180
Session allocation policy. Used to decide when to allocate a
181181
new session. Set to one of the following values:
182182
.br
183183

184-
.br
185-
\fBDefault\fR - session per <User,BitPerPixel>
186-
.br
187-
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
188-
.br
189-
\fBUBI\fR - session per <User,BitPerPixel,IPAddr>
190-
.br
191-
\fBUBC\fR - session per <User,BitPerPixel,Connection>
192-
.br
193-
\fBUBDI\fR - session per <User,BitPerPixel,DisplaySize,IPAddr>
194-
.br
195-
\fBUBDC\fR - session per <User,BitPerPixel,DisplaySize,Connection>
196-
.br
184+
.RS
185+
.HP 12
186+
\fBDefault\fR - Currently the same as "UB" for all session types
187+
.HP 12
188+
\fBSeparate\fR - All sessions are separate. Sessions can never be rejoined,
189+
and will need to be cleaned up manually, or automatically by setting other
190+
sesman options.
191+
.P
192+
Alternatively combine one-or-more of the following options
193+
.HP 4
194+
\fBU\fR - Sessions are separated per user
195+
.HP 4
196+
\fBB\fR - Sessions are separated by bits-per-pixel
197+
.HP 4
198+
\fBD\fR - Sessions are separated by initial display size
199+
.HP 4
200+
\fBI\fR - Sessions are separated by IP address
201+
.RE
197202

198-
.br
199-
Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
203+
.IP
204+
Note that the \fBU\fR and \fBB\fR criteria cannot be turned
200205
off. \fBDisplaySize\fR refers to the initial geometry of a connection,
201206
as actual display sizes can change dynamically.
202-
.br
203207

204208
.SH "SECURITY"
205209
Following parameters can be used in the \fB[Security]\fR section.

sesman/config.c

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,81 @@
3737
#include "chansrv/chansrv_common.h"
3838
#include "scp.h"
3939

40+
static const struct bitmask_char policy_bits[] =
41+
{
42+
{ SESMAN_CFG_SESS_POLICY_U, 'U' },
43+
{ SESMAN_CFG_SESS_POLICY_B, 'B' },
44+
{ SESMAN_CFG_SESS_POLICY_D, 'D' },
45+
{ SESMAN_CFG_SESS_POLICY_I, 'I' },
46+
BITMASK_CHAR_END_OF_LIST
47+
};
48+
49+
/***************************************************************************//**
50+
* Parse a session allocation policy string
51+
*/
52+
static unsigned int
53+
parse_policy_string(const char *value)
54+
{
55+
unsigned int rv;
56+
char unrecognised[16];
57+
58+
if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_DFLT_S))
59+
{
60+
rv = SESMAN_CFG_SESS_POLICY_DEFAULT;
61+
}
62+
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_SEP_S))
63+
{
64+
rv = SESMAN_CFG_SESS_POLICY_SEPARATE;
65+
}
66+
else
67+
{
68+
unrecognised[0] = '\0';
69+
rv = g_charstr_to_bitmask(value, policy_bits, unrecognised,
70+
sizeof(unrecognised));
71+
if (unrecognised[0] != '\0')
72+
{
73+
LOG(LOG_LEVEL_WARNING, "Character(s) '%s' in the session"
74+
" allocation policy are not recognised", unrecognised);
75+
76+
if (g_strchr(unrecognised, 'C') != NULL ||
77+
g_strchr(unrecognised, 'c') != NULL)
78+
{
79+
/* Change from xrdp v0.9.x */
80+
LOG(LOG_LEVEL_WARNING, "Character 'C' is no longer used"
81+
" in session allocation policies - use '%s'",
82+
SESMAN_CFG_SESS_POLICY_SEP_S);
83+
}
84+
}
85+
}
86+
87+
return rv;
88+
}
89+
90+
/******************************************************************************/
91+
int
92+
config_output_policy_string(unsigned int value,
93+
char *buff, unsigned int bufflen)
94+
{
95+
int rv = 0;
96+
if (bufflen > 0)
97+
{
98+
if (value & SESMAN_CFG_SESS_POLICY_DEFAULT)
99+
{
100+
rv = g_snprintf(buff, bufflen, "Default");
101+
}
102+
else if (value & SESMAN_CFG_SESS_POLICY_SEPARATE)
103+
{
104+
rv = g_snprintf(buff, bufflen, "Separate");
105+
}
106+
else
107+
{
108+
rv = g_bitmask_to_charstr(value, policy_bits, buff, bufflen, NULL);
109+
}
110+
}
111+
112+
return rv;
113+
}
114+
40115
/***************************************************************************//**
41116
*
42117
* @brief Reads sesman [global] configuration section
@@ -295,7 +370,8 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
295370
struct list *param_v)
296371
{
297372
int i;
298-
char *buf;
373+
const char *buf;
374+
const char *value;
299375

300376
list_clear(param_v);
301377
list_clear(param_n);
@@ -306,70 +382,43 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
306382
se->max_idle_time = 0;
307383
se->max_disc_time = 0;
308384
se->kill_disconnected = 0;
309-
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
385+
se->policy = SESMAN_CFG_SESS_POLICY_DEFAULT;
310386

311387
file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v);
312388

313389
for (i = 0; i < param_n->count; i++)
314390
{
315-
buf = (char *)list_get_item(param_n, i);
391+
buf = (const char *)list_get_item(param_n, i);
392+
value = (const char *)list_get_item(param_v, i);
316393

317394
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_X11DISPLAYOFFSET))
318395
{
319-
se->x11_display_offset = g_atoi((char *)list_get_item(param_v, i));
396+
se->x11_display_offset = g_atoi(value);
320397
}
321398

322-
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX))
399+
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX))
323400
{
324-
se->max_sessions = g_atoi((char *)list_get_item(param_v, i));
401+
se->max_sessions = g_atoi(value);
325402
}
326403

327-
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC))
404+
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC))
328405
{
329-
se->kill_disconnected = g_text2bool((char *)list_get_item(param_v, i));
406+
se->kill_disconnected = g_text2bool(value);
330407
}
331408

332-
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT))
409+
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT))
333410
{
334-
se->max_idle_time = g_atoi((char *)list_get_item(param_v, i));
411+
se->max_idle_time = g_atoi(value);
335412
}
336413

337-
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT))
414+
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT))
338415
{
339-
se->max_disc_time = g_atoi((char *)list_get_item(param_v, i));
416+
se->max_disc_time = g_atoi(value);
340417
}
341418

342-
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_POLICY_S))
419+
else if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_POLICY_S))
343420
{
344-
char *value = (char *)list_get_item(param_v, i);
345-
if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_DFLT_S))
346-
{
347-
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
348-
}
349-
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBD_S))
350-
{
351-
se->policy = SESMAN_CFG_SESS_POLICY_UBD;
352-
}
353-
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBI_S))
354-
{
355-
se->policy = SESMAN_CFG_SESS_POLICY_UBI;
356-
}
357-
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBC_S))
358-
{
359-
se->policy = SESMAN_CFG_SESS_POLICY_UBC;
360-
}
361-
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDI_S))
362-
{
363-
se->policy = SESMAN_CFG_SESS_POLICY_UBDI;
364-
}
365-
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDC_S))
366-
{
367-
se->policy = SESMAN_CFG_SESS_POLICY_UBDC;
368-
}
369-
else /* silently ignore typos */
370-
{
371-
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
372-
}
421+
se->policy = parse_policy_string(value);
373422
}
374423
}
375424

@@ -570,6 +619,7 @@ config_dump(struct config_sesman *config)
570619
struct config_security *sc;
571620
se = &(config->sess);
572621
sc = &(config->sec);
622+
char policy_s[64];
573623

574624
/* Global sesman configuration */
575625
g_writeln("Filename: %s", config->sesman_ini);
@@ -583,13 +633,15 @@ config_dump(struct config_sesman *config)
583633
(config->auth_file_path ? config->auth_file_path : "disabled"));
584634

585635
/* Session configuration */
636+
config_output_policy_string(se->policy, policy_s, sizeof(policy_s));
637+
586638
g_writeln("Session configuration:");
587639
g_writeln(" MaxSessions: %d", se->max_sessions);
588640
g_writeln(" X11DisplayOffset: %d", se->x11_display_offset);
589641
g_writeln(" KillDisconnected: %d", se->kill_disconnected);
590642
g_writeln(" IdleTimeLimit: %d", se->max_idle_time);
591643
g_writeln(" DisconnectedTimeLimit: %d", se->max_disc_time);
592-
g_writeln(" Policy: %d", se->policy);
644+
g_writeln(" Policy: %s", policy_s);
593645

594646
/* Security configuration */
595647
g_writeln("Security configuration:");

sesman/config.h

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,27 +72,18 @@
7272

7373
#define SESMAN_CFG_SESS_POLICY_S "Policy"
7474
#define SESMAN_CFG_SESS_POLICY_DFLT_S "Default"
75-
#define SESMAN_CFG_SESS_POLICY_UBD_S "UBD"
76-
#define SESMAN_CFG_SESS_POLICY_UBI_S "UBI"
77-
#define SESMAN_CFG_SESS_POLICY_UBC_S "UBC"
78-
#define SESMAN_CFG_SESS_POLICY_UBDI_S "UBDI"
79-
#define SESMAN_CFG_SESS_POLICY_UBDC_S "UBDC"
75+
#define SESMAN_CFG_SESS_POLICY_SEP_S "Separate"
8076

8177
enum SESMAN_CFG_SESS_POLICY_BITS
8278
{
83-
SESMAN_CFG_SESS_POLICY_D = 0x01,
84-
SESMAN_CFG_SESS_POLICY_I = 0x02,
85-
SESMAN_CFG_SESS_POLICY_C = 0x04
86-
};
87-
88-
enum SESMAN_CFG_SESS_POLICY
89-
{
90-
SESMAN_CFG_SESS_POLICY_DFLT = 0,
91-
SESMAN_CFG_SESS_POLICY_UBD = SESMAN_CFG_SESS_POLICY_D,
92-
SESMAN_CFG_SESS_POLICY_UBI = SESMAN_CFG_SESS_POLICY_I,
93-
SESMAN_CFG_SESS_POLICY_UBC = SESMAN_CFG_SESS_POLICY_C,
94-
SESMAN_CFG_SESS_POLICY_UBDI = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_I,
95-
SESMAN_CFG_SESS_POLICY_UBDC = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_C
79+
/* If these two are set, they override everything else */
80+
SESMAN_CFG_SESS_POLICY_DEFAULT = (1 << 0),
81+
SESMAN_CFG_SESS_POLICY_SEPARATE = (1 << 1),
82+
/* Configuration bits */
83+
SESMAN_CFG_SESS_POLICY_U = (1 << 2),
84+
SESMAN_CFG_SESS_POLICY_B = (1 << 3),
85+
SESMAN_CFG_SESS_POLICY_D = (1 << 4),
86+
SESMAN_CFG_SESS_POLICY_I = (1 << 5)
9687
};
9788

9889
/**
@@ -180,7 +171,7 @@ struct config_sessions
180171
* @var policy
181172
* @brief session allocation policy
182173
*/
183-
enum SESMAN_CFG_SESS_POLICY policy;
174+
unsigned int policy;
184175
};
185176

186177
/**
@@ -304,4 +295,16 @@ config_dump(struct config_sesman *config);
304295
void
305296
config_free(struct config_sesman *cs);
306297

298+
/**
299+
* Converts a session allocation Policy value to a strin
300+
* @param value - Session allocation policy value
301+
* @param buff - Buffer for result
302+
* @param bufflen - Length of buffer
303+
* @return Length of string that would be required without a terminator
304+
* to write the whole output (like snprintf())
305+
*/
306+
int
307+
config_output_policy_string(unsigned int value,
308+
char *buff, unsigned int bufflen);
309+
307310
#endif

sesman/sesman.ini.in

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,20 @@ DisconnectedTimeLimit=0
6969
IdleTimeLimit=0
7070

7171
;; Policy - session allocation policy
72-
; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
73-
; "Default" session per <User,BitPerPixel>
74-
; "UBD" session per <User,BitPerPixel,DisplaySize>
75-
; "UBI" session per <User,BitPerPixel,IPAddr>
76-
; "UBC" session per <User,BitPerPixel,Connection>
77-
; "UBDI" session per <User,BitPerPixel,DisplaySize,IPAddr>
78-
; "UBDC" session per <User,BitPerPixel,DisplaySize,Connection>
72+
;
73+
; Type: enum [ "Default" | "Separate" | Combination from {UBDI} ]
74+
; "Default" Currently same as "UB"
75+
; "Separate" All sessions are separate. Sessions can never be rejoined,
76+
; and will need to be cleaned up manually, or automatically
77+
; by setting other sesman options.
78+
;
79+
; Combination options:-
80+
; U Sessions are separated per user
81+
; B Sessions are separated by bits-per-pixel
82+
; D Sessions are separated by initial display size
83+
; I Sessions are separated by IP address
84+
;
85+
; The options U and B are always active, and cannot be de-selected.
7986
Policy=Default
8087

8188
[Logging]

0 commit comments

Comments
 (0)