Merge pull request #58 from ArvidNorr/pam-cont
PAM additions mostly for a gateway situation
This commit is contained in:
commit
9aa0cb4e61
@ -41,7 +41,7 @@ typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self);
|
|||||||
|
|
||||||
struct trans
|
struct trans
|
||||||
{
|
{
|
||||||
tbus sck;
|
tbus sck; /* socket handle */
|
||||||
int mode; /* 1 tcp, 2 unix socket */
|
int mode; /* 1 tcp, 2 unix socket */
|
||||||
int status;
|
int status;
|
||||||
int type1; /* 1 listener 2 server 3 client */
|
int type1; /* 1 listener 2 server 3 client */
|
||||||
|
@ -819,6 +819,25 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
|
|||||||
return 0;
|
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 */
|
/* returns error */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -833,7 +852,8 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
|
|||||||
if (xrdp_iso_init(self->iso_layer, s) != 0)
|
if (xrdp_iso_init(self->iso_layer, s) != 0)
|
||||||
{
|
{
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
DEBUG((" out xrdp_mcs_disconnect error"));
|
close_rdp_socket(self);
|
||||||
|
DEBUG((" out xrdp_mcs_disconnect error - 1"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,11 +864,13 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
|
|||||||
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
||||||
{
|
{
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
DEBUG((" out xrdp_mcs_disconnect error"));
|
close_rdp_socket(self);
|
||||||
|
DEBUG((" out xrdp_mcs_disconnect error - 2"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
DEBUG((" out xrdp_mcs_disconnect"));
|
close_rdp_socket(self);
|
||||||
|
DEBUG(("xrdp_mcs_disconnect - close sent"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ access_login_allowed(char *user)
|
|||||||
return 0;
|
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",
|
LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
|
||||||
1);
|
1);
|
||||||
@ -57,7 +57,7 @@ access_login_allowed(char *user)
|
|||||||
|
|
||||||
if (g_cfg->sec.ts_users == gid)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
long DEFAULT_CC
|
long DEFAULT_CC
|
||||||
auth_userpass(char* user, char* pass);
|
auth_userpass(char* user, char* pass, int *errorcode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -286,12 +286,17 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
sc->ts_admins = gid;
|
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 */
|
/* printing security config */
|
||||||
g_printf("security configuration:\r\n");
|
g_printf("security configuration:\r\n");
|
||||||
g_printf("\tAllowRootLogin: %i\r\n", sc->allow_root);
|
g_printf("\tAllowRootLogin: %i\r\n", sc->allow_root);
|
||||||
g_printf("\tMaxLoginRetry: %i\r\n", sc->login_retry);
|
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)
|
if (sc->ts_users_enable)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
||||||
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
||||||
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
||||||
|
#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck"
|
||||||
|
|
||||||
#define SESMAN_CFG_SESSIONS "Sessions"
|
#define SESMAN_CFG_SESSIONS "Sessions"
|
||||||
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
||||||
@ -93,6 +94,11 @@ struct config_security
|
|||||||
*/
|
*/
|
||||||
int ts_admins_enable;
|
int ts_admins_enable;
|
||||||
int ts_admins;
|
int ts_admins;
|
||||||
|
/**
|
||||||
|
* @var ts_always_group_check
|
||||||
|
* @brief if the Groups are not found deny access
|
||||||
|
*/
|
||||||
|
int ts_always_group_check;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,8 +35,9 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||||||
int display = 0;
|
int display = 0;
|
||||||
tbus data;
|
tbus data;
|
||||||
struct session_item *s_item;
|
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)
|
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))
|
if (1 == access_login_allowed(s->username))
|
||||||
{
|
{
|
||||||
/* the user is member of the correct groups. */
|
/* 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",
|
log_message(LOG_LEVEL_INFO, "Access permitted for user: %s",
|
||||||
s->username);
|
s->username);
|
||||||
/* g_writeln("Connection allowed"); */
|
/* g_writeln("Connection allowed"); */
|
||||||
}
|
}
|
||||||
else
|
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 "
|
log_message(LOG_LEVEL_INFO, "Username okey but group problem for "
|
||||||
"user: %s", s->username);
|
"user: %s", s->username);
|
||||||
/* g_writeln("user password ok, but group problem"); */
|
/* 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"); */
|
/* g_writeln("username or password error"); */
|
||||||
log_message(LOG_LEVEL_INFO, "Username or password error for user: %s",
|
log_message(LOG_LEVEL_INFO, "Username or password error for user: %s",
|
||||||
s->username);
|
s->username);
|
||||||
scp_v0s_replyauthentication(c, 2);
|
scp_v0s_replyauthentication(c, errorcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
auth_end(data);
|
auth_end(data);
|
||||||
|
@ -50,7 +50,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||||||
retries = g_cfg->sec.login_retry;
|
retries = g_cfg->sec.login_retry;
|
||||||
current_try = retries;
|
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);*/
|
/*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
|
||||||
|
|
||||||
while ((!data) && ((retries == 0) || (current_try > 0)))
|
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:
|
case SCP_SERVER_STATE_OK:
|
||||||
/* all ok, we got new username and password */
|
/* 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 */
|
/* one try less */
|
||||||
if (current_try > 0)
|
if (current_try > 0)
|
||||||
|
@ -42,7 +42,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||||||
int scount;
|
int scount;
|
||||||
int end = 0;
|
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);*/
|
/*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -10,6 +10,9 @@ AllowRootLogin=1
|
|||||||
MaxLoginRetry=4
|
MaxLoginRetry=4
|
||||||
TerminalServerUsers=tsusers
|
TerminalServerUsers=tsusers
|
||||||
TerminalServerAdmins=tsadmins
|
TerminalServerAdmins=tsadmins
|
||||||
|
# When AlwaysGroupCheck = false access will be permitted
|
||||||
|
# if the group TerminalServerUsers is not defined.
|
||||||
|
AlwaysGroupCheck = false
|
||||||
|
|
||||||
[Sessions]
|
[Sessions]
|
||||||
X11DisplayOffset=10
|
X11DisplayOffset=10
|
||||||
|
@ -48,7 +48,7 @@ auth_account_disabled(struct spwd *stp);
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* returns boolean */
|
/* returns boolean */
|
||||||
long DEFAULT_CC
|
long DEFAULT_CC
|
||||||
auth_userpass(char *user, char *pass)
|
auth_userpass(char *user, char *pass, int *errorcode)
|
||||||
{
|
{
|
||||||
char salt[13] = "$1$";
|
char salt[13] = "$1$";
|
||||||
char hash[35] = "";
|
char hash[35] = "";
|
||||||
|
@ -396,7 +396,7 @@ cleanup:
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* returns boolean */
|
/* returns boolean */
|
||||||
int DEFAULT_CC
|
int DEFAULT_CC
|
||||||
auth_userpass(char *user, char *pass)
|
auth_userpass(char *user, char *pass, int *errorcode)
|
||||||
{
|
{
|
||||||
struct k_opts opts;
|
struct k_opts opts;
|
||||||
struct k5_data k5;
|
struct k5_data k5;
|
||||||
|
@ -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
|
long DEFAULT_CC
|
||||||
auth_userpass(char *user, char *pass)
|
auth_userpass(char *user, char *pass, int *errorcode)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
struct t_auth_info *auth_info;
|
struct t_auth_info *auth_info;
|
||||||
@ -116,6 +118,9 @@ auth_userpass(char *user, char *pass)
|
|||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
if (error != PAM_SUCCESS)
|
||||||
{
|
{
|
||||||
|
if(errorcode!=NULL){
|
||||||
|
*errorcode = error ;
|
||||||
|
}
|
||||||
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
|
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
|
||||||
g_free(auth_info);
|
g_free(auth_info);
|
||||||
return 0;
|
return 0;
|
||||||
@ -125,16 +130,27 @@ auth_userpass(char *user, char *pass)
|
|||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
if (error != PAM_SUCCESS)
|
||||||
{
|
{
|
||||||
|
if(errorcode!=NULL){
|
||||||
|
*errorcode = error ;
|
||||||
|
}
|
||||||
g_printf("pam_authenticate failed: %s\r\n",
|
g_printf("pam_authenticate failed: %s\r\n",
|
||||||
pam_strerror(auth_info->ph, error));
|
pam_strerror(auth_info->ph, error));
|
||||||
g_free(auth_info);
|
g_free(auth_info);
|
||||||
return 0;
|
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);
|
error = pam_acct_mgmt(auth_info->ph, 0);
|
||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
if (error != PAM_SUCCESS)
|
||||||
{
|
{
|
||||||
|
if(errorcode!=NULL){
|
||||||
|
*errorcode = error ;
|
||||||
|
}
|
||||||
g_printf("pam_acct_mgmt failed: %s\r\n",
|
g_printf("pam_acct_mgmt failed: %s\r\n",
|
||||||
pam_strerror(auth_info->ph, error));
|
pam_strerror(auth_info->ph, error));
|
||||||
g_free(auth_info);
|
g_free(auth_info);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* returns boolean */
|
/* returns boolean */
|
||||||
int DEFAULT_CC
|
int DEFAULT_CC
|
||||||
auth_userpass(char *user, char *pass)
|
auth_userpass(char *user, char *pass, int *errorcode)
|
||||||
{
|
{
|
||||||
pam_handle_t *pamh;
|
pam_handle_t *pamh;
|
||||||
pam_userpass_t userpass;
|
pam_userpass_t userpass;
|
||||||
|
@ -177,7 +177,7 @@ void DEFAULT_CC
|
|||||||
pipe_sig(int sig_num)
|
pipe_sig(int sig_num)
|
||||||
{
|
{
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
g_writeln("got SIGPIPE(%d)", sig_num);
|
g_writeln("got XRDP SIGPIPE(%d)", sig_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -25,6 +25,8 @@ tcp_keepalive=yes
|
|||||||
#autorun=xrdp1
|
#autorun=xrdp1
|
||||||
#hidelogwindow=yes
|
#hidelogwindow=yes
|
||||||
#bulk_compression=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]
|
[Logging]
|
||||||
LogFile=xrdp.log
|
LogFile=xrdp.log
|
||||||
|
@ -315,7 +315,18 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
|
|||||||
{
|
{
|
||||||
self->login_window->focused_control = b;
|
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)
|
if (g_strncmp(name, "username", 255) == 0)
|
||||||
{
|
{
|
||||||
g_strncpy(b->caption1, self->session->client_info->username, 255);
|
g_strncpy(b->caption1, self->session->client_info->username, 255);
|
||||||
|
171
xrdp/xrdp_mm.c
171
xrdp/xrdp_mm.c
@ -17,10 +17,12 @@
|
|||||||
*
|
*
|
||||||
* module manager
|
* module manager
|
||||||
*/
|
*/
|
||||||
|
#define ACCESS
|
||||||
#include "xrdp.h"
|
#include "xrdp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#define ACCESS
|
#ifdef ACCESS
|
||||||
|
#include "security/_pam_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
struct xrdp_mm *APP_CC
|
struct xrdp_mm *APP_CC
|
||||||
@ -187,9 +189,17 @@ xrdp_mm_send_login(struct xrdp_mm *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* send domain */
|
/* send domain */
|
||||||
|
if(self->wm->client_info->domain[0]!='_')
|
||||||
|
{
|
||||||
index = g_strlen(self->wm->client_info->domain);
|
index = g_strlen(self->wm->client_info->domain);
|
||||||
out_uint16_be(s, index);
|
out_uint16_be(s, index);
|
||||||
out_uint8a(s, self->wm->client_info->domain, index);
|
out_uint8a(s, self->wm->client_info->domain, index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out_uint16_be(s, 0);
|
||||||
|
/* out_uint8a(s, "", 0); */
|
||||||
|
}
|
||||||
|
|
||||||
/* send program / shell */
|
/* send program / shell */
|
||||||
index = g_strlen(self->wm->client_info->program);
|
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 access_control(char *username, char *password, char *srv)
|
||||||
{
|
{
|
||||||
int reply;
|
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 *in_s;
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
unsigned long version;
|
unsigned long version;
|
||||||
unsigned short int dummy;
|
unsigned short int dummy;
|
||||||
unsigned short int ok;
|
unsigned short int pAM_errorcode;
|
||||||
unsigned short int code;
|
unsigned short int code;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int index;
|
int index;
|
||||||
@ -1117,17 +1127,17 @@ int access_control(char *username, char *password, char *srv)
|
|||||||
if ((size == 14) && (version == 0))
|
if ((size == 14) && (version == 0))
|
||||||
{
|
{
|
||||||
in_uint16_be(in_s, code);
|
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);
|
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 "
|
log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
|
||||||
"sesman is corrupt");
|
"sesman is corrupt");
|
||||||
}
|
}
|
||||||
else
|
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
|
else
|
||||||
@ -1189,6 +1199,134 @@ void cleanup_states(struct xrdp_mm *self)
|
|||||||
self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
|
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 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
xrdp_mm_connect(struct xrdp_mm *self)
|
xrdp_mm_connect(struct xrdp_mm *self)
|
||||||
@ -1282,7 +1420,7 @@ xrdp_mm_connect(struct xrdp_mm *self)
|
|||||||
{
|
{
|
||||||
int reply;
|
int reply;
|
||||||
char replytxt[80];
|
char replytxt[80];
|
||||||
char replymessage[4][80] = {"Ok", "Sesman connect failure", "User or password error", "Privilege group error"};
|
char *additionalError;
|
||||||
xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
|
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"); */
|
/* g_writeln("we use pam modules to check if we can approve this user"); */
|
||||||
@ -1301,17 +1439,18 @@ xrdp_mm_connect(struct xrdp_mm *self)
|
|||||||
/* access_control return 0 on success */
|
/* access_control return 0 on success */
|
||||||
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
|
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", getPAMError(reply));
|
||||||
{
|
|
||||||
g_sprintf(replytxt, "Reply from access control: %s", replymessage[reply]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_sprintf(replytxt, "Reply from access control undefined");
|
|
||||||
}
|
|
||||||
|
|
||||||
xrdp_wm_log_msg(self->wm, replytxt);
|
xrdp_wm_log_msg(self->wm, replytxt);
|
||||||
log_message(LOG_LEVEL_INFO, 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)
|
if (reply != 0)
|
||||||
{
|
{
|
||||||
|
@ -197,14 +197,14 @@ xrdp_process_main_loop(struct xrdp_process *self)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* send disconnect message if possible */
|
||||||
libxrdp_disconnect(self->session);
|
libxrdp_disconnect(self->session);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
|
g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
|
||||||
}
|
}
|
||||||
|
/* Run end in module */
|
||||||
xrdp_process_mod_end(self);
|
xrdp_process_mod_end(self);
|
||||||
libxrdp_exit(self->session);
|
libxrdp_exit(self->session);
|
||||||
self->session = 0;
|
self->session = 0;
|
||||||
|
@ -316,6 +316,7 @@ struct xrdp_wm
|
|||||||
int hints;
|
int hints;
|
||||||
int allowedchannels[MAX_NR_CHANNELS];
|
int allowedchannels[MAX_NR_CHANNELS];
|
||||||
int allowedinitialized ;
|
int allowedinitialized ;
|
||||||
|
char pamerrortxt[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* rdp process */
|
/* rdp process */
|
||||||
|
@ -446,6 +446,11 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name)
|
|||||||
val = (char *)list_get_item(values, index);
|
val = (char *)list_get_item(values, index);
|
||||||
self->hide_log_window = text2bool(val);
|
self->hide_log_window = text2bool(val);
|
||||||
}
|
}
|
||||||
|
else if (g_strcasecmp(val, "pamerrortxt") == 0)
|
||||||
|
{
|
||||||
|
val = (char *)list_get_item(values, index);
|
||||||
|
g_strncpy(self->pamerrortxt,val,255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,7 +539,12 @@ xrdp_wm_init(struct xrdp_wm *self)
|
|||||||
names->auto_free = 1;
|
names->auto_free = 1;
|
||||||
values = list_create();
|
values = list_create();
|
||||||
values->auto_free = 1;
|
values->auto_free = 1;
|
||||||
|
/* 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);
|
g_strncpy(section_name, self->session->client_info->domain, 255);
|
||||||
|
}
|
||||||
|
|
||||||
if (section_name[0] == 0)
|
if (section_name[0] == 0)
|
||||||
{
|
{
|
||||||
|
@ -137,7 +137,7 @@ void DEFAULT_CC
|
|||||||
pipe_sig(int sig_num)
|
pipe_sig(int sig_num)
|
||||||
{
|
{
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
g_writeln("got SIGPIPE(%d)", sig_num);
|
g_writeln("got XRDP WIN SIGPIPE(%d)", sig_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
Loading…
Reference in New Issue
Block a user