X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcontext.c;h=81b597850b1dbfbe00396ea6119ba1014ed80e3e;hb=e2fa85ce8859f837c1280c377ba537ff6030d519;hp=953d1d6ae77b6e1c8dd1409f3eeae5bd9b985d2d;hpb=aa7365c86de8e26e796d3aa3fd605c85d8c26220;p=citadel.git diff --git a/citadel/context.c b/citadel/context.c index 953d1d6ae..81b597850 100644 --- a/citadel/context.c +++ b/citadel/context.c @@ -13,69 +13,14 @@ * GNU General Public License for more details. */ -#include "sysdep.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* -#include -*/ - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "server.h" -#include "sysdep_decls.h" -#include "citserver.h" -#include "support.h" -#include "config.h" -#include "database.h" -#include "housekeeping.h" -#include "modules/crypto/serv_crypto.h" /* Needed for init_ssl, client_write_ssl, client_read_ssl, destruct_ssl */ +#include "ctdl_module.h" +#include "serv_extensions.h" #include "ecrash.h" -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#ifndef HAVE_SNPRINTF -#include "snprintf.h" -#endif - -#include "ctdl_module.h" -#include "threads.h" +#include "citserver.h" #include "user_ops.h" +#include "locate_host.h" +#include "context.h" #include "control.h" int DebugSession = 0; @@ -88,6 +33,7 @@ CitContext *ContextList = NULL; time_t last_purge = 0; /* Last dead session purge */ int num_sessions = 0; /* Current number of sessions */ +int next_pid = 0; /* Flag for single user mode */ static int want_single_user = 0; @@ -146,26 +92,46 @@ int CtdlIsSingleUser(void) */ int CtdlTerminateOtherSession (int session_num) { + struct CitContext *CCC = CC; int ret = 0; CitContext *ccptr; + int aide; - if (session_num == CC->cs_pid) { - return TERM_NOTALLOWED; - } + if (session_num == CCC->cs_pid) return TERM_NOTALLOWED; + + aide = ( (CCC->user.axlevel >= AxAideU) || (CCC->internal_pgm) ) ; CONM_syslog(LOG_DEBUG, "Locating session to kill\n"); begin_critical_section(S_SESSION_TABLE); for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if (session_num == ccptr->cs_pid) { ret |= TERM_FOUND; - if ((ccptr->user.usernum == CC->user.usernum) - || (CC->user.axlevel >= AxAideU)) { + if ((ccptr->user.usernum == CCC->user.usernum) || aide) { ret |= TERM_ALLOWED; - ccptr->kill_me = KILLME_ADMIN_TERMINATE; } + break; } } - end_critical_section(S_SESSION_TABLE); + + if (((ret & TERM_FOUND) != 0) && ((ret & TERM_ALLOWED) != 0)) + { + if (ccptr->IO != NULL) { + AsyncIO *IO = ccptr->IO; + end_critical_section(S_SESSION_TABLE); + KillAsyncIOContext(IO); + } + else + { + if (ccptr->user.usernum == CCC->user.usernum) + ccptr->kill_me = KILLME_ADMIN_TERMINATE; + else + ccptr->kill_me = KILLME_IDLE; + end_critical_section(S_SESSION_TABLE); + } + } + else + end_critical_section(S_SESSION_TABLE); + return ret; } @@ -310,7 +276,12 @@ void terminate_all_sessions(void) for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if (ccptr->client_socket != -1) { - CON_syslog(LOG_INFO, "terminate_all_sessions() is murdering %s", ccptr->curr_user); + if (ccptr->IO != NULL) { + CON_syslog(LOG_INFO, "terminate_all_sessions() is murdering %s IO[%ld]CC[%d]", ccptr->curr_user, ccptr->IO->ID, ccptr->cs_pid); + } + else { + CON_syslog(LOG_INFO, "terminate_all_sessions() is murdering %s CC[%d]", ccptr->curr_user, ccptr->cs_pid); + } close(ccptr->client_socket); ccptr->client_socket = -1; killed++; @@ -388,7 +359,6 @@ void RemoveContext (CitContext *con) */ CitContext *CreateNewContext(void) { CitContext *me; - static int next_pid = 0; me = (CitContext *) malloc(sizeof(CitContext)); if (me == NULL) { @@ -438,7 +408,6 @@ CitContext *CreateNewContext(void) { */ CitContext *CloneContext(CitContext *CloneMe) { CitContext *me; - static int next_pid = 0; me = (CitContext *) malloc(sizeof(CitContext)); if (me == NULL) { @@ -464,7 +433,10 @@ CitContext *CloneContext(CitContext *CloneMe) { me->openid_data = NULL; me->ldap_dn = NULL; me->session_specific_data = NULL; + + me->CIT_ICAL = NULL; + me->cached_msglist = NULL; me->download_fp = NULL; me->upload_fp = NULL; me->client_socket = 0; @@ -517,6 +489,99 @@ CitContext *CtdlGetContextArray(int *count) +/* + * Back-end function for starting a session + */ +void begin_session(CitContext *con) +{ + /* + * Initialize some variables specific to our context. + */ + con->logged_in = 0; + con->internal_pgm = 0; + con->download_fp = NULL; + con->upload_fp = NULL; + con->cached_msglist = NULL; + con->cached_num_msgs = 0; + con->FirstExpressMessage = NULL; + time(&con->lastcmd); + time(&con->lastidle); + strcpy(con->lastcmdname, " "); + strcpy(con->cs_clientname, "(unknown)"); + strcpy(con->curr_user, NLI); + *con->net_node = '\0'; + *con->fake_username = '\0'; + *con->fake_hostname = '\0'; + *con->fake_roomname = '\0'; + *con->cs_clientinfo = '\0'; + safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host); + safestrncpy(con->cs_addr, "", sizeof con->cs_addr); + con->cs_UDSclientUID = -1; + con->cs_host[sizeof con->cs_host - 1] = 0; + if (!CC->is_local_socket) { + locate_host(con->cs_host, sizeof con->cs_host, + con->cs_addr, sizeof con->cs_addr, + con->client_socket + ); + } + else { + con->cs_host[0] = 0; + con->cs_addr[0] = 0; +#ifdef HAVE_STRUCT_UCRED + { + /* as http://www.wsinnovations.com/softeng/articles/uds.html told us... */ + struct ucred credentials; + socklen_t ucred_length = sizeof(struct ucred); + + /*fill in the user data structure */ + if(getsockopt(con->client_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) { + syslog(LOG_NOTICE, "could obtain credentials from unix domain socket"); + + } + else { + /* the process ID of the process on the other side of the socket */ + /* credentials.pid; */ + + /* the effective UID of the process on the other side of the socket */ + con->cs_UDSclientUID = credentials.uid; + + /* the effective primary GID of the process on the other side of the socket */ + /* credentials.gid; */ + + /* To get supplemental groups, we will have to look them up in our account + database, after a reverse lookup on the UID to get the account name. + We can take this opportunity to check to see if this is a legit account. + */ + snprintf(con->cs_clientinfo, sizeof(con->cs_clientinfo), + "PID: "F_PID_T"; UID: "F_UID_T"; GID: "F_XPID_T" ", + credentials.pid, + credentials.uid, + credentials.gid); + } + } +#endif + } + con->cs_flags = 0; + con->upload_type = UPL_FILE; + con->dl_is_net = 0; + + con->nologin = 0; + if (((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions)) || CtdlWantSingleUser()) { + con->nologin = 1; + } + + if (!CC->is_local_socket) { + syslog(LOG_NOTICE, "Session (%s) started from %s (%s).\n", con->ServiceName, con->cs_host, con->cs_addr); + } + else { + syslog(LOG_NOTICE, "Session (%s) started via local socket UID:%d.\n", con->ServiceName, con->cs_UDSclientUID); + } + + /* Run any session startup routines registered by loadable modules */ + PerformSessionHooks(EVT_START); +} + + /* * This function fills in a context and its user field correctly * Then creates/loads that user