Update logging in sesman access control

Improve the built-in access checks for sesman/sesexec:-
- Group existence is checked for at login-time rather than program
  start time
- The name of the group is now included in the message

Also, check for UID == 0 when checking for root, rather than just
checking the name (which might be an alias)
This commit is contained in:
matt335672 2023-10-04 11:43:01 +01:00
parent 5837deae04
commit cf5c2718af
3 changed files with 151 additions and 98 deletions

View File

@ -28,47 +28,142 @@
#include <config_ac.h>
#endif
#include <stdio.h>
#include "arch.h"
#include "sesman_access.h"
#include "sesman_config.h"
#include "log.h"
#include "os_calls.h"
#include "string_calls.h"
/******************************************************************************/
/**
* Root user login check
*
* @param cfg_sec Sesman security config
* @param user user name
* @return 0 if user is root and root accesses are not allowed
*/
static int
root_login_check(const struct config_security *cfg_sec,
const char *user)
{
int rv = 0;
if (cfg_sec->allow_root)
{
rv = 1;
}
else
{
// Check the UID of the user isn't 0
int uid;
if (g_getuser_info_by_name(user, &uid, NULL, NULL, NULL, NULL) != 0)
{
LOG(LOG_LEVEL_ERROR, "Can't get UID for user %s", user);
}
else if (0 == uid)
{
LOG(LOG_LEVEL_ERROR,
"ROOT login attempted, but root login is disabled");
}
else
{
rv = 1;
}
}
return rv;
}
/******************************************************************************/
/**
* Common access control for group checks
* @param group Group name
* @param param Where group comes from (e.g. "TerminalServerUsers")
* @param always_check_group 0 if a missing group allows a login
* @param user Username
* @return != 0 if the access is allowed */
static int
access_login_allowed_common(const char *group, const char *param,
int always_check_group,
const char *user)
{
int rv = 0;
int gid;
int ok;
if (group == NULL || group[0] == '\0')
{
/* Group is not defined. Default access depends on whether
* we must have the group or not */
if (always_check_group)
{
LOG(LOG_LEVEL_ERROR,
"%s group is not defined. Access denied for %s",
param, user);
}
else
{
LOG(LOG_LEVEL_INFO,
"%s group is not defined. Access granted for %s",
param, user);
rv = 1;
}
}
else if (g_getgroup_info(group, &gid) != 0)
{
/* Group is defined but doesn't exist. Default access depends
* on whether we must have the group or not */
if (always_check_group)
{
LOG(LOG_LEVEL_ERROR,
"%s group %s doesn't exist. Access denied for %s",
param, group, user);
}
else
{
LOG(LOG_LEVEL_INFO,
"%s group %s doesn't exist. Access granted for %s",
param, group, user);
rv = 1;
}
}
else if (0 != g_check_user_in_group(user, gid, &ok))
{
LOG(LOG_LEVEL_ERROR, "Error checking %s group %s. "
"Access denied for %s", param, group, user);
}
else if (!ok)
{
LOG(LOG_LEVEL_ERROR, "User %s is not in %s group %s. Access denied",
user, param, group);
}
else
{
LOG(LOG_LEVEL_INFO, "User %s is in %s group %s. Access granted",
user, param, group);
rv = 1;
}
return rv;
}
/******************************************************************************/
int
access_login_allowed(const struct config_security *cfg_sec, const char *user)
{
int ok;
int rv = 0;
if ((0 == g_strncmp(user, "root", 5)) && (0 == cfg_sec->allow_root))
if (root_login_check(cfg_sec, user))
{
LOG(LOG_LEVEL_WARNING,
"ROOT login attempted, but root login is disabled");
return 0;
rv = access_login_allowed_common(cfg_sec->ts_users,
"TerminalServerUsers",
cfg_sec->ts_always_group_check,
user);
}
if ((0 == cfg_sec->ts_users_enable) && (0 == cfg_sec->ts_always_group_check))
{
LOG(LOG_LEVEL_INFO, "Terminal Server Users group is disabled, allowing authentication");
return 1;
}
if (0 != g_check_user_in_group(user, cfg_sec->ts_users, &ok))
{
LOG(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
return 0;
}
if (ok)
{
return 1;
}
LOG(LOG_LEVEL_INFO, "login denied for user %s", user);
return 0;
return rv;
}
/******************************************************************************/
@ -76,34 +171,15 @@ int
access_login_mng_allowed(const struct config_security *cfg_sec,
const char *user)
{
int ok;
int rv = 0;
if ((0 == g_strncmp(user, "root", 5)) && (0 == cfg_sec->allow_root))
if (root_login_check(cfg_sec, user))
{
LOG(LOG_LEVEL_WARNING,
"[MNG] ROOT login attempted, but root login is disabled");
return 0;
rv = access_login_allowed_common(cfg_sec->ts_admins,
"TerminalServerAdmins",
1,
user);
}
if (0 == cfg_sec->ts_admins_enable)
{
LOG(LOG_LEVEL_INFO, "[MNG] Terminal Server Admin group is disabled, "
"allowing authentication");
return 1;
}
if (0 != g_check_user_in_group(user, cfg_sec->ts_admins, &ok))
{
LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
return 0;
}
if (ok)
{
return 1;
}
LOG(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
return 0;
return rv;
}

View File

@ -297,8 +297,8 @@ config_read_security(int file, struct config_security *sc,
struct list *param_v)
{
int i;
int gid;
char *buf;
const char *buf;
const char *value;
list_clear(param_v);
list_clear(param_n);
@ -306,49 +306,46 @@ config_read_security(int file, struct config_security *sc,
/* setting defaults */
sc->allow_root = 0;
sc->login_retry = 3;
sc->ts_users_enable = 0;
sc->ts_admins_enable = 0;
sc->restrict_outbound_clipboard = 0;
sc->restrict_inbound_clipboard = 0;
sc->allow_alternate_shell = 1;
sc->xorg_no_new_privileges = 1;
sc->ts_users = g_strdup("");
sc->ts_admins = g_strdup("");
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
for (i = 0; i < param_n->count; i++)
{
buf = (char *)list_get_item(param_n, i);
buf = (const char *)list_get_item(param_n, i);
value = (const char *)list_get_item(param_v, i);
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT))
{
sc->allow_root = g_text2bool((char *)list_get_item(param_v, i));
sc->allow_root = g_text2bool(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY))
{
sc->login_retry = g_atoi((char *)list_get_item(param_v, i));
sc->login_retry = g_atoi(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP))
{
if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0)
{
sc->ts_users_enable = 1;
sc->ts_users = gid;
}
g_free(sc->ts_users);
sc->ts_users = NULL;
sc->ts_users = g_strdup(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP))
{
if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0)
{
sc->ts_admins_enable = 1;
sc->ts_admins = gid;
}
g_free(sc->ts_admins);
sc->ts_admins = NULL;
sc->ts_admins = g_strdup(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALWAYSGROUPCHECK))
{
sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i));
sc->ts_always_group_check = g_text2bool(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
@ -382,13 +379,13 @@ config_read_security(int file, struct config_security *sc,
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL))
{
sc->allow_alternate_shell =
g_text2bool((char *)list_get_item(param_v, i));
g_text2bool(value);
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_XORG_NO_NEW_PRIVILEGES))
{
sc->xorg_no_new_privileges =
g_text2bool((char *)list_get_item(param_v, i));
g_text2bool(value);
}
}
@ -687,28 +684,8 @@ config_dump(struct config_sesman *config)
restrict_s, sizeof(restrict_s));
g_writeln(" RestrictInboundClipboard: %s", restrict_s);
g_printf( " TSUsersGroup: ");
if (sc->ts_users_enable)
{
g_printf("%d", sc->ts_users);
}
else
{
g_printf("(not defined)");
}
g_writeln("%s", "");
g_printf( " TSAdminsGroup: ");
if (sc->ts_admins_enable)
{
g_printf("%d", sc->ts_admins);
}
else
{
g_printf("(not defined)");
}
g_writeln("%s", "");
g_writeln(" TSUsersGroup: %s", sc->ts_users);
g_writeln(" TSAdminsGroup: %s", sc->ts_admins);
/* Xorg */
@ -764,6 +741,8 @@ config_free(struct config_sesman *cs)
list_delete(cs->xorg_params);
list_delete(cs->env_names);
list_delete(cs->env_values);
g_free(cs->sec.ts_users);
g_free(cs->sec.ts_admins);
g_free(cs);
}
}

View File

@ -70,14 +70,12 @@ struct config_security
* @var ts_users
* @brief Terminal Server Users group
*/
int ts_users_enable;
int ts_users;
char *ts_users;
/**
* @var ts_admins
* @brief Terminal Server Administrators group
*/
int ts_admins_enable;
int ts_admins;
char *ts_admins;
/**
* @var ts_always_group_check
* @brief if the Groups are not found deny access