summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sesman/access.c4
-rw-r--r--sesman/config.c69
-rw-r--r--sesman/config.h58
-rw-r--r--sesman/sesman.c23
-rw-r--r--sesman/sesman.ini19
-rw-r--r--sesman/session.c227
-rw-r--r--sesman/session.h75
7 files changed, 445 insertions, 30 deletions
diff --git a/sesman/access.c b/sesman/access.c
index 594120d6..96750c3f 100644
--- a/sesman/access.c
+++ b/sesman/access.c
@@ -26,8 +26,6 @@
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
-//#include <unistd.h>
-//#include <pwd.h>
extern struct config_sesman g_cfg;
@@ -76,7 +74,7 @@ access_login_allowed(char* user)
while (0!=groups->gr_mem[i])
{
LOG_DBG("user: %s", groups->gr_mem[i]);
- if (0==strcmp(groups->gr_mem[i], user)) return 1;
+ if (0==g_strcmp(groups->gr_mem[i], user)) return 1;
i++;
}
diff --git a/sesman/config.c b/sesman/config.c
index d96bb45a..5dd0d748 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -74,6 +74,9 @@ config_read(struct config_sesman* cfg)
/* read security config */
config_read_security(fd, &(cfg->sec), param_n, param_v);
+ /* read session config */
+ config_read_sessions(fd, &(cfg->sess), param_n, param_v);
+
/* cleanup */
list_delete(sec);
list_delete(param_v);
@@ -206,6 +209,7 @@ config_read_security(int file, struct config_security* sc, struct list* param_n,
{
int i;
char* buf;
+ struct group* g;
list_clear(param_v);
list_clear(param_n);
@@ -225,13 +229,21 @@ config_read_security(int file, struct config_security* sc, struct list* param_n,
}
if (0 == g_strncasecmp(buf, SESMAN_CFG_SEC_USR_GROUP, 20))
{
- sc->ts_users_enable=1;
- sc->ts_users=(getgrnam((char*)list_get_item(param_v, i))->gr_gid);
+ g=getgrnam((char*)list_get_item(param_v, i));
+ if (0!=g)
+ {
+ sc->ts_users_enable=1;
+ sc->ts_users=g->gr_gid;
+ }
}
if (0 == g_strncasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP, 20))
{
- sc->ts_admins_enable=1;
- sc->ts_admins=(getgrnam((char*)list_get_item(param_v, i))->gr_gid);
+ g=getgrnam((char*)list_get_item(param_v, i));
+ if (0!=g)
+ {
+ sc->ts_admins_enable=1;
+ sc->ts_admins=g->gr_gid;
+ }
}
}
@@ -258,3 +270,52 @@ config_read_security(int file, struct config_security* sc, struct list* param_n,
return 0;
}
+/******************************************************************************/
+int DEFAULT_CC
+config_read_sessions(int file, struct config_sessions* se, struct list* param_n,
+ struct list* param_v)
+{
+ int i;
+ char* buf;
+
+ list_clear(param_v);
+ list_clear(param_n);
+
+ /* setting defaults */
+ se->max_sessions=0;
+ se->max_idle_time=0;
+ se->max_disc_time=0;
+ se->kill_disconnected=0;
+
+ file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v);
+ for (i = 0; i < param_n->count; i++)
+ {
+ buf = (char*)list_get_item(param_n, i);
+ if (0 == g_strncasecmp(buf, SESMAN_CFG_SESS_MAX, 20))
+ {
+ se->max_sessions = g_atoi((char*)list_get_item(param_v, i));
+ }
+ if (0 == g_strncasecmp(buf, SESMAN_CFG_SESS_KILL_DISC, 20))
+ {
+ se->kill_disconnected = text2bool((char*)list_get_item(param_v, i));
+ }
+ if (0 == g_strncasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT, 20))
+ {
+ se->max_idle_time=g_atoi((char*)list_get_item(param_v, i));
+ }
+ if (0 == g_strncasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT, 20))
+ {
+ se->max_disc_time=g_atoi((char*)list_get_item(param_v, i));
+ }
+ }
+
+ /* printing security config */
+ g_printf("session configuration:\r\n");
+ g_printf("\tMaxSessions: %i\r\n", se->max_sessions);
+ g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected);
+ g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time);
+ g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time);
+
+ return 0;
+}
+
diff --git a/sesman/config.h b/sesman/config.h
index c73d35da..6f66d579 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -59,15 +59,12 @@
#define SESMAN_CFG_SESS_MAX "MaxSessions"
#define SESMAN_CFG_SESS_KILL_DISC "KillDisconnected"
#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit"
+#define SESMAN_CFG_SESS_DISC_LIMIT "DisconnectedTimeLimit"
/**
*
- * @struct config_sesman
- * @brief \t struct that contains \t sesman configuration
- *
- * This \t struct contains all of \t sesman configuration parameters\n
- * Every parameter in \t [globals] is a member of this struct, other
- * sections options are embedded in this \t struct as member structures
+ * @struct config_security
+ * @brief \t struct that contains \t sesman access control configuration
*
*/
struct config_security
@@ -93,6 +90,36 @@ struct config_security
/**
*
+ * @struct config_sessions
+ * @brief \t struct that contains \t sesman session handling configuration
+ *
+ */
+struct config_sessions
+{
+ /**
+ * @var max_sessions
+ * @brief maximum number of allowed sessions. 0 for unlimited
+ */
+ int max_sessions;
+ /**
+ * @var max_idle_time
+ * @brief maximum idle time for each session
+ */
+ int max_idle_time;
+ /**
+ * @var max_disc_time
+ * @brief maximum disconnected time for each session
+ */
+ int max_disc_time;
+ /**
+ * @var kill_disconnected
+ * @brief enables automatic killing of disconnected session
+ */
+ int kill_disconnected;
+};
+
+/**
+ *
* @struct config_sesman
* @brief \t struct that contains \t sesman configuration
*
@@ -133,6 +160,11 @@ struct config_sesman
* @brief Security configuration options \t struct
*/
struct config_security sec;
+ /**
+ * @var sess
+ * @brief Session configuration options \t struct
+ */
+ struct config_sessions sess;
};
/**
@@ -173,7 +205,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, struc
/**
*
- * @brief Reads sesman [iSecurity] configuration section
+ * @brief Reads sesman [Security] configuration section
*
* @param cfg pointer to configuration object to be replaced
*
@@ -183,4 +215,16 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, struc
int DEFAULT_CC
config_read_security(int file, struct config_security* sc, struct list* param_n, struct list* param_v);
+/**
+ *
+ * @brief Reads sesman [Sessions] configuration section
+ *
+ * @param cfg pointer to configuration object to be replaced
+ *
+ * @return 0 on success, 1 on failure
+ *
+ */
+int DEFAULT_CC
+config_read_sessions(int file, struct config_sessions* ss, struct list* param_n, struct list* param_v);
+
#endif
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 30cbd44f..5fbbdb6f 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -32,14 +32,25 @@
int g_sck;
int g_pid;
unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 };
+#ifdef OLDSESSION
struct session_item g_session_items[100]; /* sesman.h */
+extern int g_session_count;
+#endif
struct config_sesman g_cfg; /* config.h */
-/******************************************************************************/
+/**
+ *
+ * trigger when a child process (a session) dies
+ *
+ * @param s received signal
+ *
+ */
static void DEFAULT_CC
cterm(int s)
{
+#ifdef OLDSESSION
int i;
+#endif
int pid;
if (g_getpid() != g_pid)
@@ -49,13 +60,18 @@ cterm(int s)
pid = g_waitchild();
if (pid > 0)
{
+#ifdef OLDSESSION
for (i = 0; i < 100; i++)
{
if (g_session_items[i].pid == pid)
{
g_memset(g_session_items + i, 0, sizeof(struct session_item));
+ g_session_count--;
}
}
+#else
+ session_kill(pid);
+#endif
}
}
@@ -133,7 +149,8 @@ sesman_main_loop()
display = 0;
if (data)
{
- s_item = session_find_item(user, width, height, bpp);
+ //s_item = session_find_item(user, width, height, bpp);
+ s_item = session_get_bydata(user, width, height, bpp);
if (s_item != 0)
{
display = s_item->display;
@@ -325,7 +342,9 @@ main(int argc, char** argv)
}
/* signal handling */
+#ifdef OLDSESSION
g_memset(&g_session_items, 0, sizeof(g_session_items));
+#endif
g_pid = g_getpid();
g_signal(1, sig_sesman_reload_cfg); /* SIGHUP */
g_signal(2, sig_sesman_shutdown); /* SIGINT */
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index 7f98e5e1..4c5f5a18 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -4,14 +4,19 @@ EnableUserWindowManager=1
UserWindowManager=startwm.sh
DefaultWindowManager=startwm.sh
+[Security]
+AllowRootLogin=1
+TerminalServerUsers=tsusers
+TerminalServerAdmins=tsadmins
+
+[Sessions]
+MaxSessions=10
+KillDisconnected=0
+IdleTimeLimit=0
+DisconnectedTimeLimit=0
+
[Logging]
-LogFile=/usr/local/xrdp/sesman.log
+LogFile=./sesman.log
LogLevel=DEBUG
EnableSyslog=0
SyslogLevel=DEBUG
-
-[Security]
-AllowRootLogin=1
-#TerminalServerUsers=tsusers
-#TerminalServerAdmins=tsadmins
-
diff --git a/sesman/session.c b/sesman/session.c
index b02dec69..826e4036 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -21,16 +21,24 @@
*/
+#include <stdlib.h>
+
#include "sesman.h"
extern unsigned char g_fixedkey[8];
-extern struct session_item g_session_items[100]; /* sesman.h */
extern struct config_sesman g_cfg; /* config.h */
+#ifdef OLDSESSION
+extern struct session_item g_session_items[100]; /* sesman.h */
+#else
+struct session_chain* g_sessions;
+#endif
+int g_session_count;
/******************************************************************************/
struct session_item* DEFAULT_CC
-session_find_item(char* name, int width, int height, int bpp)
+session_get_bydata(char* name, int width, int height, int bpp)
{
+#ifdef OLDSESSION
int i;
for (i = 0; i < 100; i++)
@@ -43,6 +51,27 @@ session_find_item(char* name, int width, int height, int bpp)
return g_session_items + i;
}
}
+#else
+ struct session_chain* tmp;
+
+ /*THREAD-FIX require chain lock */
+ tmp=g_sessions;
+
+ while (tmp != 0)
+ {
+ if (g_strncmp(name, tmp->item->name, 255) == 0 &&
+ tmp->item->width == width &&
+ tmp->item->height == height &&
+ tmp->item->bpp == bpp)
+ {
+ /*THREAD-FIX release chain lock */
+ return tmp->item;
+ }
+ tmp=tmp->next;
+ }
+
+ /*THREAD-FIX release chain lock */
+#endif
return 0;
}
@@ -73,10 +102,40 @@ session_start(int width, int height, int bpp, char* username, char* password,
char cur_dir[256];
char text[256];
char passwd_file[256];
+#ifndef OLDSESSION
+ struct session_chain* temp;
+#endif
+
+ /*THREAD-FIX lock to control g_session_count*/
+ /* check to limit concurrent sessions */
+ if (g_session_count >= g_cfg.sess.max_sessions)
+ {
+ log_message(LOG_LEVEL_INFO, "max concurrent session limit exceeded. login for user %s denied", username);
+ return 0;
+ }
+
+#ifndef OLDSESSION
+ temp=malloc(sizeof(struct session_chain));
+ if (temp == 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "cannot create new chain element - user %s", username);
+ return 0;
+ }
+ temp->item = malloc(sizeof(struct session_item));
+ if (temp->item == 0)
+ {
+ free(temp);
+ log_message(LOG_LEVEL_ERROR, "cannot create new session item - user %s", username);
+ return 0;
+ }
+#endif
g_get_current_dir(cur_dir, 255);
display = 10;
- while (x_server_running(display) && display < 50)
+ /*while (x_server_running(display) && display < 50)*/
+ /* we search for a free display up to max_sessions */
+ /* we should need no more displays than this */
+ while (x_server_running(display) && (display <= g_cfg.sess.max_sessions))
{
display++;
}
@@ -159,6 +218,7 @@ session_start(int width, int height, int bpp, char* username, char* password,
}
else /* parent */
{
+#ifdef OLDSESSION
g_session_items[display].pid = pid;
g_strcpy(g_session_items[display].name, username);
g_session_items[display].display = display;
@@ -166,8 +226,169 @@ session_start(int width, int height, int bpp, char* username, char* password,
g_session_items[display].height = height;
g_session_items[display].bpp = bpp;
g_session_items[display].data = data;
+
+ g_session_items[display].connect_time=g_time1();
+ g_session_items[display].disconnect_time=(time_t) 0;
+ g_session_items[display].idle_time=(time_t) 0;
+
+ g_session_items[display].type=SESMAN_SESSION_TYPE_XVNC;
+ g_session_items[display].status=SESMAN_SESSION_STATUS_ACTIVE;
+
+ g_session_count++;
+#else
+ temp->item->pid=pid;
+ temp->item->display=display;
+ temp->item->width=width;
+ temp->item->height=height;
+ temp->item->bpp=bpp;
+ temp->item->data=data;
+ g_strncpy(temp->item->name, username, 255);
+
+ temp->item->connect_time=g_time1();
+ temp->item->disconnect_time=(time_t) 0;
+ temp->item->idle_time=(time_t) 0;
+
+ temp->item->type=SESMAN_SESSION_TYPE_XVNC;
+ temp->item->status=SESMAN_SESSION_STATUS_ACTIVE;
+
+ /*THREAD-FIX lock the chain*/
+ temp->next=g_sessions;
+ g_sessions=temp;
+ g_session_count++;
+ /*THERAD-FIX free the chain*/
+#endif
g_sleep(5000);
}
return display;
}
+/*
+SESMAN_SESSION_TYPE_XRDP 1
+SESMAN_SESSION_TYPE_XVNC 2
+
+SESMAN_SESSION_STATUS_ACTIVE 1
+SESMAN_SESSION_STATUS_IDLE 2
+SESMAN_SESSION_STATUS_DISCONNECTED 3
+
+struct session_item
+{
+ char name[256];
+ int pid;
+ int display;
+ int width;
+ int height;
+ int bpp;
+ long data;
+
+ / *
+ unsigned char status;
+ unsigned char type;
+ * /
+
+ / *
+ time_t connect_time;
+ time_t disconnect_time;
+ time_t idle_time;
+ * /
+};
+
+struct session_chain
+{
+ struct session_chain* next;
+ struct session_item* item;
+};
+*/
+
+#ifndef OLDSESSION
+
+/******************************************************************************/
+int DEFAULT_CC
+session_kill(int pid)
+{
+ struct session_chain* tmp;
+ struct session_chain* prev;
+
+ /*THREAD-FIX require chain lock */
+ tmp=g_sessions;
+ prev=0;
+
+ while (tmp != 0)
+ {
+ if (tmp->item == 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "session descriptor for pid %d is null!", pid);
+ if (prev == 0)
+ {
+ /* prev does no exist, so it's the first element - so we set g_sessions */
+ g_sessions = tmp->next;
+ }
+ else
+ {
+ prev->next = tmp->next;
+ }
+ /*THREAD-FIX release chain lock */
+ return SESMAN_SESSION_KILL_NULLITEM;
+ }
+
+ if (tmp->item->pid == pid)
+ {
+ /* deleting the session */
+ log_message(LOG_LEVEL_INFO, "session %d - user %s - terminated", tmp->item->pid, tmp->item->name);
+ free(tmp->item);
+ if (prev == 0)
+ {
+ /* prev does no exist, so it's the first element - so we set g_sessions */
+ g_sessions = tmp->next;
+ }
+ else
+ {
+ prev->next = tmp->next;
+ }
+ free(tmp);
+ g_session_count--;
+ /*THREAD-FIX release chain lock */
+ return SESMAN_SESSION_KILL_OK;
+ }
+
+ /* go on */
+ prev = tmp;
+ tmp=tmp->next;
+ }
+
+ /*THREAD-FIX release chain lock */
+ return SESMAN_SESSION_KILL_NOTFOUND;
+}
+
+/******************************************************************************/
+struct session_item* DEFAULT_CC
+session_get_bypid(int pid)
+{
+ struct session_chain* tmp;
+
+ /*THREAD-FIX require chain lock */
+ tmp=g_sessions;
+ while (tmp != 0)
+ {
+ if (tmp->item == 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "session descriptor for pid %d is null!", pid);
+ /*THREAD-FIX release chain lock */
+ return 0;
+ }
+
+ if (tmp->item->pid == pid)
+ {
+ /*THREAD-FIX release chain lock */
+ return tmp->item;
+ }
+
+ /* go on */
+ tmp=tmp->next;
+ }
+
+ /*THREAD-FIX release chain lock */
+ return 0;
+}
+
+#endif
+
diff --git a/sesman/session.h b/sesman/session.h
index c8615c05..5d677911 100644
--- a/sesman/session.h
+++ b/sesman/session.h
@@ -24,6 +24,20 @@
#ifndef SESSION_H
#define SESSION_H
+#define SESMAN_SESSION_TYPE_XRDP 1
+#define SESMAN_SESSION_TYPE_XVNC 2
+
+#define SESMAN_SESSION_STATUS_ACTIVE 1
+#define SESMAN_SESSION_STATUS_IDLE 2
+#define SESMAN_SESSION_STATUS_DISCONNECTED 3
+/* future expansion
+#define SESMAN_SESSION_STATUS_REMCONTROL 4
+*/
+
+#define SESMAN_SESSION_KILL_OK 0
+#define SESMAN_SESSION_KILL_NULLITEM 1
+#define SESMAN_SESSION_KILL_NOTFOUND 2
+
struct session_item
{
char name[256];
@@ -33,17 +47,70 @@ struct session_item
int height;
int bpp;
long data;
+
+ /* status info */
+ unsigned char status;
+ unsigned char type;
+
+ /* time data */
+ time_t connect_time;
+ time_t disconnect_time;
+ time_t idle_time;
};
-/******************************************************************************/
+struct session_chain
+{
+ struct session_chain* next;
+ struct session_item* item;
+};
+
+/**
+ *
+ * finds a session matching the supplied parameters
+ *
+ * @return session data or 0
+ *
+ */
struct session_item* DEFAULT_CC
-session_find_item(char* name, int width, int height, int bpp);
+session_get_bydata(char* name, int width, int height, int bpp);
+#ifndef session_find_item
+ #define session_find_item(a, b, c, d) session_get_bydata(a, b, c, d);
+#endif
-/******************************************************************************/
-/* returns 0 if error else the display number the session was started on */
+/**
+ *
+ * starts a session
+ *
+ * @return 0 on error, display number if success
+ *
+ */
int DEFAULT_CC
session_start(int width, int height, int bpp, char* username, char* password,
long data);
+/**
+ *
+ * kills a session
+ *
+ * @param the id of the session to be killed
+ *
+ * @return
+ *
+ */
+int DEFAULT_CC
+session_kill(int pid);
+
+/**
+ *
+ * retrieves a session's descriptor
+ *
+ * @param pid the session pid
+ *
+ * @return a pointer to the session descriptor on success, NULL otherwise
+ *
+ */
+struct session_item* DEFAULT_CC
+session_get_bypid(int pid);
+
#endif