From a2bbbd8cc336bedbda61a6af47d90bcccbe6aead Mon Sep 17 00:00:00 2001 From: ArvidNorr Date: Wed, 16 Jan 2013 01:28:35 -0800 Subject: [PATCH 1/3] Display PAM error in gateway setup, use domain name as IP/DNS, changed how the socket is closed --- common/trans.h | 2 +- libxrdp/xrdp_mcs.c | 28 +++++++++- sesman/auth.h | 2 +- sesman/scp_v0.c | 9 +-- sesman/scp_v1.c | 4 +- sesman/scp_v1_mng.c | 2 +- sesman/verify_user_pam.c | 22 +++++++- xrdp/xrdp.c | 2 +- xrdp/xrdp_login_wnd.c | 13 ++++- xrdp/xrdp_mm.c | 118 ++++++++++++++++++++++++++++++++------- xrdp/xrdp_process.c | 4 +- xrdp/xrdp_wm.c | 7 ++- xrdp/xrdpwin.c | 2 +- 13 files changed, 174 insertions(+), 41 deletions(-) diff --git a/common/trans.h b/common/trans.h index 36d08a7c..1133477a 100644 --- a/common/trans.h +++ b/common/trans.h @@ -41,7 +41,7 @@ typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self); struct trans { - tbus sck; + tbus sck; /* socket handle */ int mode; /* 1 tcp, 2 unix socket */ int status; int type1; /* 1 listener 2 server 3 client */ diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 77c0d10d..e5481c9c 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -819,6 +819,25 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan) return 0; } +/** + * Internal help function to close the socket + * @param self + */ +void close_rdp_socket(struct xrdp_mcs *self) +{ + if(self->iso_layer->tcp_layer) + { + if(self->iso_layer->tcp_layer->trans) + { + g_tcp_close(self->iso_layer->tcp_layer->trans->sck); + self->iso_layer->tcp_layer->trans->sck = 0 ; + g_writeln("xrdp_mcs_disconnect - socket closed"); + return ; + } + } + g_writeln("Failed to close socket"); +} + /*****************************************************************************/ /* returns error */ int APP_CC @@ -833,7 +852,8 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self) if (xrdp_iso_init(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); + close_rdp_socket(self); + DEBUG((" out xrdp_mcs_disconnect error - 1")); return 1; } @@ -844,11 +864,13 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self) if (xrdp_iso_send(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); + close_rdp_socket(self); + DEBUG((" out xrdp_mcs_disconnect error - 2")); return 1; } free_stream(s); - DEBUG((" out xrdp_mcs_disconnect")); + close_rdp_socket(self); + DEBUG(("xrdp_mcs_disconnect - close sent")); return 0; } diff --git a/sesman/auth.h b/sesman/auth.h index 09bec2e9..39acc0b8 100644 --- a/sesman/auth.h +++ b/sesman/auth.h @@ -36,7 +36,7 @@ * */ long DEFAULT_CC -auth_userpass(char* user, char* pass); +auth_userpass(char* user, char* pass, int *errorcode); /** * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index da6ab919..6ecb47b1 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -35,8 +35,9 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) int display = 0; tbus data; struct session_item *s_item; + int errorcode = 0 ; - data = auth_userpass(s->username, s->password); + data = auth_userpass(s->username, s->password,&errorcode); if (s->type == SCP_GW_AUTHENTICATION) { @@ -47,14 +48,14 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) if (1 == access_login_allowed(s->username)) { /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(c, 0); + scp_v0s_replyauthentication(c, errorcode); log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", s->username); /* g_writeln("Connection allowed"); */ } else { - scp_v0s_replyauthentication(c, 3); + scp_v0s_replyauthentication(c, 32+3); /* all first 32 are reserved for PAM errors */ log_message(LOG_LEVEL_INFO, "Username okey but group problem for " "user: %s", s->username); /* g_writeln("user password ok, but group problem"); */ @@ -65,7 +66,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) /* g_writeln("username or password error"); */ log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", s->username); - scp_v0s_replyauthentication(c, 2); + scp_v0s_replyauthentication(c, errorcode); } auth_end(data); diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index 295fbce4..d3f0ab7f 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -50,7 +50,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) retries = g_cfg->sec.login_retry; current_try = retries; - data = auth_userpass(s->username, s->password); + data = auth_userpass(s->username, s->password,NULL); /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ while ((!data) && ((retries == 0) || (current_try > 0))) @@ -65,7 +65,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { case SCP_SERVER_STATE_OK: /* all ok, we got new username and password */ - data = auth_userpass(s->username, s->password); + data = auth_userpass(s->username, s->password,NULL); /* one try less */ if (current_try > 0) diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c index 0e20007d..9d1da0f5 100644 --- a/sesman/scp_v1_mng.c +++ b/sesman/scp_v1_mng.c @@ -42,7 +42,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) int scount; int end = 0; - data = auth_userpass(s->username, s->password); + data = auth_userpass(s->username, s->password,NULL); /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ if (!data) diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c index b81398de..b7a7bef7 100644 --- a/sesman/verify_user_pam.c +++ b/sesman/verify_user_pam.c @@ -98,9 +98,11 @@ get_service_name(char *service_name) } /******************************************************************************/ -/* returns long, zero is no go */ +/* returns long, zero is no go + Stores the detailed error code in the errorcode variable*/ + long DEFAULT_CC -auth_userpass(char *user, char *pass) +auth_userpass(char *user, char *pass, int *errorcode) { int error; struct t_auth_info *auth_info; @@ -116,6 +118,9 @@ auth_userpass(char *user, char *pass) if (error != PAM_SUCCESS) { + if(errorcode!=NULL){ + *errorcode = error ; + } g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); g_free(auth_info); return 0; @@ -125,16 +130,27 @@ auth_userpass(char *user, char *pass) if (error != PAM_SUCCESS) { + if(errorcode!=NULL){ + *errorcode = error ; + } g_printf("pam_authenticate failed: %s\r\n", pam_strerror(auth_info->ph, error)); g_free(auth_info); return 0; } - + /* From man page: + The pam_acct_mgmt function is used to determine if the users account is + valid. It checks for authentication token and account expiration and + verifies access restrictions. It is typically called after the user has + been authenticated. + */ error = pam_acct_mgmt(auth_info->ph, 0); if (error != PAM_SUCCESS) { + if(errorcode!=NULL){ + *errorcode = error ; + } g_printf("pam_acct_mgmt failed: %s\r\n", pam_strerror(auth_info->ph, error)); g_free(auth_info); diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index fb6fd5dd..2ed2c8fd 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -177,7 +177,7 @@ void DEFAULT_CC pipe_sig(int sig_num) { /* do nothing */ - g_writeln("got SIGPIPE(%d)", sig_num); + g_writeln("got XRDP SIGPIPE(%d)", sig_num); } /*****************************************************************************/ diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index fc4cf125..08abfedb 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -315,7 +315,18 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo) { self->login_window->focused_control = b; } - + /*Use the domain name as the destination IP/DNS + This is useful in a gateway setup.*/ + if (g_strncmp(name, "ip", 255) == 0) + { + /* If the first char in the domain name is '_' we use the domain name as IP*/ + if(self->session->client_info->domain[0]=='_') + { + g_strncpy(b->caption1, &self->session->client_info->domain[1], 255); + b->edit_pos = g_mbstowcs(0, b->caption1, 0); + } + + } if (g_strncmp(name, "username", 255) == 0) { g_strncpy(b->caption1, self->session->client_info->username, 255); diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 9b0de186..0f2fae2a 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -17,10 +17,12 @@ * * module manager */ - +#define ACCESS #include "xrdp.h" #include "log.h" -#define ACCESS +#ifdef ACCESS +#include "security/_pam_types.h" +#endif /*****************************************************************************/ struct xrdp_mm *APP_CC @@ -187,9 +189,17 @@ xrdp_mm_send_login(struct xrdp_mm *self) } /* send domain */ - index = g_strlen(self->wm->client_info->domain); - out_uint16_be(s, index); - out_uint8a(s, self->wm->client_info->domain, index); + if(self->wm->client_info->domain[0]!='_') + { + index = g_strlen(self->wm->client_info->domain); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->domain, index); + } + else + { + out_uint16_be(s, 0); + /* out_uint8a(s, "", 0); */ + } /* send program / shell */ index = g_strlen(self->wm->client_info->program); @@ -1060,12 +1070,12 @@ xrdp_mm_sesman_data_in(struct trans *trans) int access_control(char *username, char *password, char *srv) { int reply; - int rec = 1; // failure + int rec = 32+1; /* 32 is reserved for PAM failures this means connect failure */ struct stream *in_s; struct stream *out_s; unsigned long version; unsigned short int dummy; - unsigned short int ok; + unsigned short int pAM_errorcode; unsigned short int code; unsigned long size; int index; @@ -1117,17 +1127,17 @@ int access_control(char *username, char *password, char *srv) if ((size == 14) && (version == 0)) { in_uint16_be(in_s, code); - in_uint16_be(in_s, ok); + in_uint16_be(in_s, pAM_errorcode); /* this variable holds the PAM error code if the variable is >32 it is a "invented" code */ in_uint16_be(in_s, dummy); - if (code != 4) + if (code != 4) /*0x04 means SCP_GW_AUTHENTICATION*/ { log_message(LOG_LEVEL_ERROR, "Returned cmd code from " "sesman is corrupt"); } else { - rec = ok; /* here we read the reply from the access control */ + rec = pAM_errorcode; /* here we read the reply from the access control */ } } else @@ -1189,6 +1199,82 @@ void cleanup_states(struct xrdp_mm *self) self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */ } } +#ifdef ACCESS +const char *getPAMError(const int pamError) +{ + switch(pamError){ + case PAM_SUCCESS: + return "Success"; + case PAM_OPEN_ERR: + return "dlopen() failure"; + case PAM_SYMBOL_ERR: + return "Symbol not found"; + case PAM_SERVICE_ERR: + return "Error in service module"; + case PAM_SYSTEM_ERR: + return "System error"; + case PAM_BUF_ERR: + return "Memory buffer error"; + case PAM_PERM_DENIED: + return "Permission denied"; + case PAM_AUTH_ERR: + return "Authentication failure"; + case PAM_CRED_INSUFFICIENT: + return "Insufficient credentials to access authentication data"; + case PAM_AUTHINFO_UNAVAIL: + return "Authentication service cannot retrieve authentication info."; + case PAM_USER_UNKNOWN: + return "User not known to the underlying authentication module"; + case PAM_MAXTRIES: + return "Have exhasted maximum number of retries for service."; + case PAM_NEW_AUTHTOK_REQD: + return "Authentication token is no longer valid; new one required."; + case PAM_ACCT_EXPIRED: + return "User account has expired"; + case PAM_CRED_UNAVAIL: + return "Authentication service cannot retrieve user credentials"; + case PAM_CRED_EXPIRED: + return "User credentials expired"; + case PAM_CRED_ERR: + return "Failure setting user credentials"; + case PAM_NO_MODULE_DATA: + return "No module specific data is present"; + case PAM_BAD_ITEM: + return "Bad item passed to pam_*_item()"; + case PAM_CONV_ERR: + return "Conversation error"; + case PAM_AUTHTOK_ERR: + return "Authentication token manipulation error"; + case PAM_AUTHTOK_LOCK_BUSY: + return "Authentication token lock busy"; + case PAM_AUTHTOK_DISABLE_AGING: + return "Authentication token aging disabled"; + case PAM_TRY_AGAIN: + return "Failed preliminary check by password service"; + case PAM_IGNORE: + return "Please ignore underlying account module"; + case PAM_MODULE_UNKNOWN: + return "Module is unknown"; + case PAM_AUTHTOK_EXPIRED: + return "Authentication token expired"; + case PAM_CONV_AGAIN: + return "Conversation is waiting for event"; + case PAM_INCOMPLETE: + return "Application needs to call libpam again"; + case 32+1: + return "Error connecting to PAM"; + case 32+3: + return "Username okey but group problem"; + default:{ + char replytxt[80]; + g_sprintf(replytxt,"Not defined PAM error:%d",pamError); + return replytxt ; + } + + } + +} +#endif /*****************************************************************************/ int APP_CC xrdp_mm_connect(struct xrdp_mm *self) @@ -1282,7 +1368,6 @@ xrdp_mm_connect(struct xrdp_mm *self) { int reply; char replytxt[80]; - char replymessage[4][80] = {"Ok", "Sesman connect failure", "User or password error", "Privilege group error"}; xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); /* g_writeln("we use pam modules to check if we can approve this user"); */ @@ -1300,15 +1385,8 @@ xrdp_mm_connect(struct xrdp_mm *self) /* access_control return 0 on success */ reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); - - if (reply >= 0 && reply < 4) - { - g_sprintf(replytxt, "Reply from access control: %s", replymessage[reply]); - } - else - { - g_sprintf(replytxt, "Reply from access control undefined"); - } + + g_sprintf(replytxt, "Reply from access control: %s", getPAMError(reply)); xrdp_wm_log_msg(self->wm, replytxt); log_message(LOG_LEVEL_INFO, replytxt); diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index e3b846ea..070dc697 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -197,14 +197,14 @@ xrdp_process_main_loop(struct xrdp_process *self) break; } } - + /* send disconnect message if possible */ libxrdp_disconnect(self->session); } else { g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); } - + /* Run end in module */ xrdp_process_mod_end(self); libxrdp_exit(self->session); self->session = 0; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 24362f54..27a794a0 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -540,7 +540,12 @@ xrdp_wm_init(struct xrdp_wm *self) names->auto_free = 1; values = list_create(); values->auto_free = 1; - g_strncpy(section_name, self->session->client_info->domain, 255); + /* domain names that starts with '_' are reserved for IP/DNS to simplify + * for the user in a gateway setup */ + if(self->session->client_info->domain[0]!='_') + { + g_strncpy(section_name, self->session->client_info->domain, 255); + } if (section_name[0] == 0) { diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index ed6fa4c5..b6bf8fc8 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -137,7 +137,7 @@ void DEFAULT_CC pipe_sig(int sig_num) { /* do nothing */ - g_writeln("got SIGPIPE(%d)", sig_num); + g_writeln("got XRDP WIN SIGPIPE(%d)", sig_num); } /*****************************************************************************/ From 0770f217fa314cd0ae2546e2b758fbbaa3e07e09 Mon Sep 17 00:00:00 2001 From: ArvidNorr Date: Mon, 28 Jan 2013 15:31:51 +0100 Subject: [PATCH 2/3] PAM error text can be configured --- sesman/verify_user.c | 2 +- sesman/verify_user_kerberos.c | 2 +- sesman/verify_user_pam_userpass.c | 2 +- xrdp/xrdp.ini | 2 + xrdp/xrdp_mm.c | 63 ++++++++++++++++++++++++++++++- xrdp/xrdp_types.h | 1 + xrdp/xrdp_wm.c | 5 +++ 7 files changed, 73 insertions(+), 4 deletions(-) diff --git a/sesman/verify_user.c b/sesman/verify_user.c index 8765d7c2..5bd89c73 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -48,7 +48,7 @@ auth_account_disabled(struct spwd *stp); /******************************************************************************/ /* returns boolean */ long DEFAULT_CC -auth_userpass(char *user, char *pass) +auth_userpass(char *user, char *pass, int *errorcode) { char salt[13] = "$1$"; char hash[35] = ""; diff --git a/sesman/verify_user_kerberos.c b/sesman/verify_user_kerberos.c index c4a7ecde..fc0d4aa2 100644 --- a/sesman/verify_user_kerberos.c +++ b/sesman/verify_user_kerberos.c @@ -396,7 +396,7 @@ cleanup: /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char *user, char *pass) +auth_userpass(char *user, char *pass, int *errorcode) { struct k_opts opts; struct k5_data k5; diff --git a/sesman/verify_user_pam_userpass.c b/sesman/verify_user_pam_userpass.c index 9fa2d9e5..4d6aac40 100644 --- a/sesman/verify_user_pam_userpass.c +++ b/sesman/verify_user_pam_userpass.c @@ -34,7 +34,7 @@ /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char *user, char *pass) +auth_userpass(char *user, char *pass, int *errorcode) { pam_handle_t *pamh; pam_userpass_t userpass; diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index f500f63f..d4a99dfb 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -25,6 +25,8 @@ tcp_keepalive=yes #autorun=xrdp1 #hidelogwindow=yes #bulk_compression=yes +# You can set the PAM error text in a gateway setup (MAX 256 chars) +#pamerrortxt=change your password according to policy at http://url [Logging] LogFile=xrdp.log diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 0f2fae2a..28b83ad0 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1204,7 +1204,7 @@ const char *getPAMError(const int pamError) { switch(pamError){ case PAM_SUCCESS: - return "Success"; + return "Success"; case PAM_OPEN_ERR: return "dlopen() failure"; case PAM_SYMBOL_ERR: @@ -1273,6 +1273,58 @@ const char *getPAMError(const int pamError) } +} + +const char *getPAMAdditionalErrorInfo(const int pamError,struct xrdp_mm *self) +{ + switch(pamError){ + case PAM_SUCCESS: + return NULL; + case PAM_OPEN_ERR: + case PAM_SYMBOL_ERR: + case PAM_SERVICE_ERR: + case PAM_SYSTEM_ERR: + case PAM_BUF_ERR: + case PAM_PERM_DENIED: + case PAM_AUTH_ERR: + case PAM_CRED_INSUFFICIENT: + case PAM_AUTHINFO_UNAVAIL: + case PAM_USER_UNKNOWN: + case PAM_CRED_UNAVAIL: + case PAM_CRED_ERR: + case PAM_NO_MODULE_DATA: + case PAM_BAD_ITEM: + case PAM_CONV_ERR: + case PAM_AUTHTOK_ERR: + case PAM_AUTHTOK_LOCK_BUSY: + case PAM_AUTHTOK_DISABLE_AGING: + case PAM_TRY_AGAIN: + case PAM_IGNORE: + case PAM_MODULE_UNKNOWN: + case PAM_CONV_AGAIN: + case PAM_INCOMPLETE: + case _PAM_RETURN_VALUES+1: + case _PAM_RETURN_VALUES+3: + return NULL; + case PAM_MAXTRIES: + case PAM_NEW_AUTHTOK_REQD: + case PAM_ACCT_EXPIRED: + case PAM_CRED_EXPIRED: + case PAM_AUTHTOK_EXPIRED: + if(self->wm->pamerrortxt[0]) + { + return self->wm->pamerrortxt; + } + else + { + return "Authentication error - Verify that user/password is valid "; + } + default:{ + return "No expected error" ; + } + + } + } #endif /*****************************************************************************/ @@ -1368,6 +1420,7 @@ xrdp_mm_connect(struct xrdp_mm *self) { int reply; char replytxt[80]; + char *additionalError; xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); /* g_writeln("we use pam modules to check if we can approve this user"); */ @@ -1390,6 +1443,14 @@ xrdp_mm_connect(struct xrdp_mm *self) xrdp_wm_log_msg(self->wm, replytxt); log_message(LOG_LEVEL_INFO, replytxt); + additionalError = getPAMAdditionalErrorInfo(reply,self); + if(additionalError) + { + if(additionalError[0]) + { + xrdp_wm_log_msg(self->wm,additionalError); + } + } if (reply != 0) { diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index fdaed059..d99dced9 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -316,6 +316,7 @@ struct xrdp_wm int hints; int allowedchannels[MAX_NR_CHANNELS]; int allowedinitialized ; + char pamerrortxt[256]; }; /* rdp process */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 27a794a0..e779d641 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -452,6 +452,11 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name) self->hide_log_window = 1; } } + else if (g_strcasecmp(val, "pamerrortxt") == 0) + { + val = (char *)list_get_item(values, index); + g_strncpy(self->pamerrortxt,val,256); + } } } } From 876f356dad387d3d9b1a8382c0115857ca605e54 Mon Sep 17 00:00:00 2001 From: ArvidNorr Date: Thu, 31 Jan 2013 15:19:58 +0100 Subject: [PATCH 3/3] deny access if group is undefined --- sesman/access.c | 4 ++-- sesman/config.c | 7 ++++++- sesman/config.h | 6 ++++++ sesman/sesman.ini | 3 +++ xrdp/xrdp_wm.c | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/sesman/access.c b/sesman/access.c index 00c9c381..692575e5 100644 --- a/sesman/access.c +++ b/sesman/access.c @@ -42,7 +42,7 @@ access_login_allowed(char *user) return 0; } - if (0 == g_cfg->sec.ts_users_enable) + if ((0 == g_cfg->sec.ts_users_enable) && (0==g_cfg->sec.ts_always_group_check)) { LOG_DBG("Terminal Server Users group is disabled, allowing authentication", 1); @@ -57,7 +57,7 @@ access_login_allowed(char *user) if (g_cfg->sec.ts_users == gid) { - LOG_DBG("ts_users is user's primary group"); + log_message(LOG_LEVEL_DEBUG,"ts_users is user's primary group"); return 1; } diff --git a/sesman/config.c b/sesman/config.c index 9938249f..e2131c14 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -286,13 +286,18 @@ config_read_security(int file, struct config_security *sc, sc->ts_admins = gid; } } + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALWAYSGROUPCHECK)) + { + sc->ts_always_group_check = text2bool((char *)list_get_item(param_v, i)); + } } /* printing security config */ g_printf("security configuration:\r\n"); g_printf("\tAllowRootLogin: %i\r\n", sc->allow_root); g_printf("\tMaxLoginRetry: %i\r\n", sc->login_retry); - + g_printf("\tAlwaysGroupCheck: %i\r\n", sc->ts_always_group_check); + if (sc->ts_users_enable) { g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); diff --git a/sesman/config.h b/sesman/config.h index 72c6cac4..263975b3 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -56,6 +56,7 @@ #define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin" #define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers" #define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins" +#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck" #define SESMAN_CFG_SESSIONS "Sessions" #define SESMAN_CFG_SESS_MAX "MaxSessions" @@ -93,6 +94,11 @@ struct config_security */ int ts_admins_enable; int ts_admins; + /** + * @var ts_always_group_check + * @brief if the Groups are not found deny access + */ + int ts_always_group_check; }; /** diff --git a/sesman/sesman.ini b/sesman/sesman.ini index f2a210a4..571e063b 100644 --- a/sesman/sesman.ini +++ b/sesman/sesman.ini @@ -10,6 +10,9 @@ AllowRootLogin=1 MaxLoginRetry=4 TerminalServerUsers=tsusers TerminalServerAdmins=tsadmins +# When AlwaysGroupCheck = false access will be permitted +# if the group TerminalServerUsers is not defined. +AlwaysGroupCheck = false [Sessions] X11DisplayOffset=10 diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index e779d641..502eab94 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -455,7 +455,7 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name) else if (g_strcasecmp(val, "pamerrortxt") == 0) { val = (char *)list_get_item(values, index); - g_strncpy(self->pamerrortxt,val,256); + g_strncpy(self->pamerrortxt,val,255); } } }