/* called with the main thread */ static int APP_CC session_get_aval_display_from_chain(void) { int display; display = g_cfg->sess.x11_display_offset; lock_chain_acquire(); while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions) { if (!session_is_display_in_chain(display)) { if (!x_server_running_check_ports(display)) { lock_chain_release(); return display; } } display++; } lock_chain_release(); log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); return 0; }
struct session_item *DEFAULT_CC session_get_bydata(char *name, int width, int height, int bpp, int type) { struct session_chain *tmp; /*THREAD-FIX require chain lock */ lock_chain_acquire(); tmp = g_sessions; /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ switch (type) { case SCP_SESSION_TYPE_XVNC: /* 0 */ type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ break; case SCP_SESSION_TYPE_XRDP: /* 1 */ type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ break; default: lock_chain_release(); return 0; } while (tmp != 0) { if (type == SESMAN_SESSION_TYPE_XRDP) { /* only name and bpp need to match for X11rdp, it can resize */ if (g_strncmp(name, tmp->item->name, 255) == 0 && tmp->item->bpp == bpp && tmp->item->type == type) { /*THREAD-FIX release chain lock */ lock_chain_release(); return tmp->item; } } if (g_strncmp(name, tmp->item->name, 255) == 0 && tmp->item->width == width && tmp->item->height == height && tmp->item->bpp == bpp && tmp->item->type == type) { /*THREAD-FIX release chain lock */ lock_chain_release(); return tmp->item; } tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); return 0; }
void DEFAULT_CC session_sigkill_all() { struct session_chain *tmp; /*THREAD-FIX require chain lock */ lock_chain_acquire(); tmp = g_sessions; while (tmp != 0) { if (tmp->item == 0) { log_message(LOG_LEVEL_ERROR, "found null session " "descriptor!"); } else { g_sigterm(tmp->item->pid); } /* go on */ tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); }
struct session_item *DEFAULT_CC session_get_bypid(int pid) { struct session_chain *tmp; struct session_item *dummy; dummy = g_malloc(sizeof(struct session_item), 1); if (0 == dummy) { log_message(LOG_LEVEL_ERROR, "internal error", pid); return 0; } /*THREAD-FIX require chain lock */ lock_chain_acquire(); 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 */ lock_chain_release(); return 0; } if (tmp->item->pid == pid) { /*THREAD-FIX release chain lock */ g_memcpy(dummy, tmp->item, sizeof(struct session_item)); lock_chain_release(); /*return tmp->item;*/ return dummy; } /* go on */ tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); return 0; }
struct session_item* DEFAULT_CC session_get_bydata(char* name, int width, int height, int bpp) { struct session_chain* tmp; /*THREAD-FIX require chain lock */ lock_chain_acquire(); tmp = g_sessions; while (tmp != 0) { if (g_strncmp(name, tmp->item->name, 255) == 0) { if (tmp->item->type == SESMAN_SESSION_TYPE_XDMX) { /*THREAD-FIX release chain lock */ lock_chain_release(); return tmp->item; } if (tmp->item->bpp == bpp && tmp->item->width == width && tmp->item->height == height) { /*THREAD-FIX release chain lock */ lock_chain_release(); return tmp->item; } } tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); return 0; }
int DEFAULT_CC session_start(int width, int height, int bpp, int layout, char* username, char* password, char* wm, long data, unsigned char type) { int display; int pid; int xkbpid; int wmpid; int xpid; int i; char geometry[32]; char depth[32]; char screen[32]; char text[256]; char passwd_file[256]; char** pp1; struct session_chain* temp; struct list* xserver_params=0; time_t ltime; struct tm stime; char *ck_cookie; DBusConnection *connection; DBusError error; int pipefd[2]; const char *layout_name; /*THREAD-FIX lock to control g_session_count*/ lock_chain_acquire(); /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) { /*THREAD-FIX unlock chain*/ lock_chain_release(); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "max concurrent session limit exceeded. login \ for user %s denied", username); return 0; }
THREAD_RV THREAD_CC monit_thread(void* param) { lock_stopwait_acquire(); while (stop == 0) { g_sleep(g_cfg->sess.monitoring_delay); while (g_waitchild() > 0); lock_chain_acquire(); session_monit(); lock_chain_release(); } session_sigkill_all(); log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "sesman[monit_thread]: remove XRDP temp dir"); g_remove_dirs(XRDP_TEMP_DIR); g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); g_file_delete(pid_file); lock_stopwait_release(); }
struct SCP_DISCONNECTED_SESSION * session_get_byuser(char *user, int *cnt, unsigned char flags) { struct session_chain *tmp; struct SCP_DISCONNECTED_SESSION *sess; int count; int index; count = 0; /*THREAD-FIX require chain lock */ lock_chain_acquire(); tmp = g_sessions; while (tmp != 0) { LOG_DBG("user: %s", user); if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { LOG_DBG("session_get_byuser: status=%d, flags=%d, " "result=%d", (tmp->item->status), flags, ((tmp->item->status) & flags)); if ((tmp->item->status) & flags) { count++; } } /* go on */ tmp = tmp->next; } if (count == 0) { (*cnt) = 0; /*THREAD-FIX release chain lock */ lock_chain_release(); return 0; } /* malloc() an array of disconnected sessions */ sess = g_malloc(count *sizeof(struct SCP_DISCONNECTED_SESSION), 1); if (sess == 0) { (*cnt) = 0; /*THREAD-FIX release chain lock */ lock_chain_release(); return 0; } tmp = g_sessions; index = 0; while (tmp != 0) { #warning FIXME: we should get only disconnected sessions! if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { if ((tmp->item->status) & flags) { (sess[index]).SID = tmp->item->pid; (sess[index]).type = tmp->item->type; (sess[index]).height = tmp->item->height; (sess[index]).width = tmp->item->width; (sess[index]).bpp = tmp->item->bpp; #warning FIXME: setting idle times and such /*(sess[index]).connect_time.year = tmp->item->connect_time.year; (sess[index]).connect_time.month = tmp->item->connect_time.month; (sess[index]).connect_time.day = tmp->item->connect_time.day; (sess[index]).connect_time.hour = tmp->item->connect_time.hour; (sess[index]).connect_time.minute = tmp->item->connect_time.minute; (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; (sess[index]).idle_time.year = tmp->item->idle_time.year; (sess[index]).idle_time.month = tmp->item->idle_time.month; (sess[index]).idle_time.day = tmp->item->idle_time.day; (sess[index]).idle_time.hour = tmp->item->idle_time.hour; (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ (sess[index]).conn_year = tmp->item->connect_time.year; (sess[index]).conn_month = tmp->item->connect_time.month; (sess[index]).conn_day = tmp->item->connect_time.day; (sess[index]).conn_hour = tmp->item->connect_time.hour; (sess[index]).conn_minute = tmp->item->connect_time.minute; (sess[index]).idle_days = tmp->item->idle_time.day; (sess[index]).idle_hours = tmp->item->idle_time.hour; (sess[index]).idle_minutes = tmp->item->idle_time.minute; index++; } } /* go on */ tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); (*cnt) = count; return sess; }
int DEFAULT_CC session_kill(int pid) { struct session_chain *tmp; struct session_chain *prev; /*THREAD-FIX require chain lock */ lock_chain_acquire(); 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 */ lock_chain_release(); return SESMAN_SESSION_KILL_NULLITEM; } if (tmp->item->pid == pid) { /* deleting the session */ log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); g_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; } g_free(tmp); g_session_count--; /*THREAD-FIX release chain lock */ lock_chain_release(); return SESMAN_SESSION_KILL_OK; } /* go on */ prev = tmp; tmp = tmp->next; } /*THREAD-FIX release chain lock */ lock_chain_release(); return SESMAN_SESSION_KILL_NOTFOUND; }
int DEFAULT_CC send_logoff(int client, int session_id) { struct session_item* sess; xmlNodePtr node, node2; xmlDocPtr doc; xmlChar* version; xmlChar* response; xmlChar* session; xmlChar* username; xmlChar* username_value; xmlChar* id; xmlChar* id_value; xmlChar* status; xmlChar* status_value; char prop[128]; int display; if (session_id == 0) { log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "sesman[send_logoff]: " "%i is not a valid session id", session_id); return 1; } log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "sesman[send_logoff]: " "request session %i logoff", session_id); lock_chain_acquire(); sess = session_get_by_display(session_id); lock_chain_release(); if( sess == NULL) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "sesman[send_logoff]: " "The session %i did not exist", session_id); xml_send_error(client, "the session id of the request did not exist"); return 1; } session_update_status_by_user(sess->name, SESMAN_SESSION_STATUS_TO_DESTROY); version = xmlCharStrdup("1.0"); doc = xmlNewDoc(version); if (doc == NULL) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "sesman[send_logoff]: " "Unable to create the document"); g_free(sess); xmlFree(version); xmlFreeDoc(doc); return 1; } doc->encoding = xmlCharStrdup("UTF-8"); response = xmlCharStrdup("response"); session = xmlCharStrdup("session"); node = xmlNewNode(NULL, response); node2 = xmlNewNode(NULL, session); sprintf(prop, "%i", display); id = xmlCharStrdup("id"); id_value = xmlCharStrdup(prop); username = xmlCharStrdup("username"); username_value = xmlCharStrdup(sess->name); status = xmlCharStrdup("status"); status_value = xmlCharStrdup("CLOSED"); xmlSetProp(node2, id, id_value); xmlSetProp(node2, username, username_value); xmlSetProp(node2, status, status_value); xmlAddChild(node, node2); xmlDocSetRootElement(doc, node); xml_send_info(client, doc); xmlFreeDoc(doc); xmlFree(version); xmlFree(response); xmlFree(session); xmlFree(username); xmlFree(username_value); xmlFree(id); xmlFree(id_value); xmlFree(status); xmlFree(status_value); g_free(sess); return 0; }
int DEFAULT_CC send_session(int client, int session_id, char* user) { struct session_item* sess = NULL; xmlNodePtr node, node2; xmlDocPtr doc; xmlChar* version; xmlChar* response; xmlChar* session; xmlChar* id; xmlChar* id_value; xmlChar* username; xmlChar* username_value; xmlChar* status; xmlChar* status_value; log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[send_session]: " "request for session\n"); lock_chain_acquire(); if (user == NULL || user[0] == '\0') { sess = session_get_by_display(session_id); } else { sess = session_get_bydata(user); } lock_chain_release(); if( sess == NULL && session_id != 0) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "sesman[send_session]: " "the session %i did not exist",session_id); sess = g_malloc(sizeof(struct session_item), 1); sess->display = session_id; sess->status = SESMAN_SESSION_STATUS_UNKNOWN; g_snprintf(sess->name, sizeof(sess->name), "UNKNOW"); } version = xmlCharStrdup("1.0"); doc = xmlNewDoc(version); if (doc == NULL) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[send_session]: " "Unable to create the document"); if (sess != NULL) { g_free(sess); } return 1; } doc->encoding = xmlCharStrdup("UTF-8"); response = xmlCharStrdup("response"); session = xmlCharStrdup("session"); node = xmlNewNode(NULL, response); node2 = xmlNewNode(NULL, session); if (sess != NULL) { char prop[128] = {0}; g_sprintf(prop, "%i", sess->display); id = xmlCharStrdup("id"); id_value = xmlCharStrdup(prop); username = xmlCharStrdup("username"); username_value = xmlCharStrdup(sess->name); status = xmlCharStrdup("status"); status_value = xmlCharStrdup(session_get_status_string(sess->status)); xmlSetProp(node2, id, id_value); xmlSetProp(node2, username, username_value); xmlSetProp(node2, status, status_value ); xmlAddChild(node, node2); } xmlDocSetRootElement(doc, node); xml_send_info(client, doc); xmlFree(response); xmlFree(session); xmlFree(version); xmlFreeDoc(doc); if (sess != NULL) { xmlFree(id); xmlFree(id_value); xmlFree(username); xmlFree(username_value); xmlFree(status); xmlFree(status_value); g_free(sess); } return 0; }
int DEFAULT_CC send_sessions(int client) { struct session_item* sess; xmlNodePtr node, node2, node3; xmlDocPtr doc; int count, i; xmlChar* version; xmlChar* encoding; xmlChar* s_node; xmlChar* s_node2; log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[send_sessions]: " "request for sessions list"); lock_chain_acquire(); sess = (struct session_item*)session_list_session(&count); lock_chain_release(); log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[send_sessions]: " "%i count sessions",count); version = xmlCharStrdup("1.0"); doc = xmlNewDoc(version); if (doc ==NULL) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[send_sessions]: " "Unable to create the document"); return 1; } doc->encoding = xmlCharStrdup("UTF-8"); s_node = xmlCharStrdup("response"); node = xmlNewNode(NULL, s_node); s_node2 = xmlCharStrdup("sessions"); node2 = xmlNewNode(NULL, s_node2); xmlAddChild(node, node2); char prop[128]; for ( i=0 ; i<count ; i++) { g_sprintf(prop, "%i", sess[i].display); xmlChar* s_session = xmlCharStrdup("session"); xmlChar* s_id = xmlCharStrdup("id"); xmlChar* s_id_value = xmlCharStrdup(prop); xmlChar* s_username = xmlCharStrdup("username"); xmlChar* s_username_value = xmlCharStrdup(sess[i].name); xmlChar* s_status = xmlCharStrdup("status"); xmlChar* s_status_value = xmlCharStrdup(session_get_status_string(sess[i].status)); node3 = xmlNewNode(NULL, s_session); xmlSetProp(node3, s_id, s_id_value ); xmlSetProp(node3, s_username, s_username_value); xmlSetProp(node3, s_status, s_status_value ); xmlAddChild(node2, node3); xmlFree(s_session); xmlFree(s_id); xmlFree(s_id_value); xmlFree(s_username); xmlFree(s_username_value); xmlFree(s_status); xmlFree(s_status_value); } xmlAddChild(node, node2); xmlDocSetRootElement(doc, node); xml_send_info(client, doc); xmlFree(version); xmlFree(s_node); xmlFree(s_node2); g_free(sess); xmlFreeDoc(doc); return 0; }
void DEFAULT_CC scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { int display = 0; tbus data; struct session_item* s_item; tc_mutex_lock(session_creation_lock); data = auth_userpass(NULL, s->username, s->password); #ifdef CHECK_PREMIUM_EDITION bool valid = true; if (get_module_version(get_module_name()) & PREMIUM_EDITION) { printf("%s %i %i %i \n", __FUNCTION__, g_time3(), last_time_premium_edition_check, CHECK_INTERVAL); if (((g_time3() - last_time_premium_edition_check) > CHECK_INTERVAL) || last_time_premium_edition_check == 0) { printf("%s FOFOFOOF\n", __FUNCTION__); valid = check_premium_edition(); } } if (!valid) { data = 0; scp_v0s_deny_connection(c, "Unable to launch the session\nInvalid License\nPlease contact your administrator\n"); tc_mutex_unlock(session_creation_lock); return; } #endif if (data == 0) { log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "User %s failed to authenticate", s->username); scp_v0s_deny_connection(c, "Your username or \nyour password is invalid"); tc_mutex_unlock(session_creation_lock); return; } lock_chain_acquire(); s_item = session_get_bydata(s->username); lock_chain_release(); if (s_item != 0) { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "A session for User %s already exist", s->username); display = s_item->display; if (s_item->status == SESMAN_SESSION_STATUS_TO_DESTROY) { log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "Session for user %s is in destroy, unable to initialize a new session", s->username); scp_v0s_deny_connection(c, "Your last session is currently \nended, retry later"); } else { session_update_status_by_user(s_item->name, SESMAN_SESSION_STATUS_ACTIVE); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "switch from status DISCONNECTED to ACTIVE"); session_switch_resolution(s->width, s->height, display); session_add_client_pid(s_item->name, s->client_pid); scp_v0s_allow_connection(c, display); } auth_end(data); tc_mutex_unlock(session_creation_lock); return; } log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "No session already started for the user %s", s->username); if (access_login_allowed(s->username) == 0) { log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "User %s is not allow to start session", s->username); display = 0; scp_v0s_deny_connection(c, "You are not allowed\nto start a session\n"); auth_end(data); tc_mutex_unlock(session_creation_lock); return; } log_message(&(g_cfg->log), LOG_LEVEL_INFO, "granted TS access to user %s", s->username); if (SCP_SESSION_TYPE_XVNC == s->type) { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session for the user %s ...", s->username); display = session_start(s->width, s->height, s->bpp, s->username, s->password, data, SESMAN_SESSION_TYPE_XVNC, s->domain, s->program, s->directory, s->keylayout, s->client_pid, s->use_scim); } else { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session for the user %s ...", s->username); display = session_start(s->width, s->height, s->bpp, s->username, s->password, data, SESMAN_SESSION_TYPE_XRDP, s->domain, s->program, s->directory, s->keylayout, s->client_pid, s->use_scim); } auth_end(data); if (display == 0) { data = 0; scp_v0s_deny_connection(c, "Unable to launch the session\nPlease contact\nyour administrator\n"); } else { scp_v0s_allow_connection(c, display); } tc_mutex_unlock(session_creation_lock); }