]> code.citadel.org Git - citadel.git/blobdiff - citadel/citserver.c
move session related functions to ctdlproto/serv_session.c
[citadel.git] / citadel / citserver.c
index cff393ba04e239f8f68b1543d65cc6c7e3e40c81..e7374205da18f033568ce4c00b3d668b03b7328f 100644 (file)
@@ -4,18 +4,12 @@
  * Copyright (c) 1987-2011 by the citadel.org team
  *
  * This program is open source software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License, version 3.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include "sysdep.h"
 #include "euidindex.h"
 #include "context.h"
 #include "svn_revision.h"
-
-#ifndef HAVE_SNPRINTF
-#include "snprintf.h"
-#endif
-
 #include "ctdl_module.h"
 
 char *unique_session_numbers;
@@ -169,6 +158,7 @@ void master_startup(void) {
        
        syslog(LOG_DEBUG, "master_startup() started\n");
        time(&server_startup_time);
+       get_config();
 
        syslog(LOG_INFO, "Opening databases\n");
        open_databases();
@@ -196,6 +186,9 @@ void master_startup(void) {
        urandom = fopen("/dev/urandom", "r");
        if (urandom != NULL) {
                rv = fread(&seed, sizeof seed, 1, urandom);
+               if (rv == -1)
+                       syslog(LOG_EMERG, "failed to read random seed: %s\n", 
+                              strerror(errno));
                fclose(urandom);
        }
        else {
@@ -205,9 +198,6 @@ void master_startup(void) {
        srand(seed);
        srandom(seed);
 
-       syslog(LOG_INFO, "Initializing ipgm secret\n");
-       get_config();
-       config.c_ipgm_secret = rand();
        put_config();
 
        syslog(LOG_DEBUG, "master_startup() finished\n");
@@ -221,7 +211,7 @@ void master_cleanup(int exitcode) {
        struct CleanupFunctionHook *fcn;
        static int already_cleaning_up = 0;
 
-       if (already_cleaning_up) while(1) sleep(1);
+       if (already_cleaning_up) while(1) usleep(1000000);
        already_cleaning_up = 1;
 
        /* Run any cleanup routines registered by loadable modules */
@@ -263,63 +253,6 @@ void master_cleanup(int exitcode) {
 
 
 
-/*
- * cmd_info()  -  tell the client about this server
- */
-void cmd_info(char *cmdbuf) {
-       cprintf("%d Server info:\n", LISTING_FOLLOWS);
-       cprintf("%d\n", CC->cs_pid);
-       cprintf("%s\n", config.c_nodename);
-       cprintf("%s\n", config.c_humannode);
-       cprintf("%s\n", config.c_fqdn);
-       cprintf("%s\n", CITADEL);
-       cprintf("%d\n", REV_LEVEL);
-       cprintf("%s\n", config.c_site_location);
-       cprintf("%s\n", config.c_sysadm);
-       cprintf("%d\n", SERVER_TYPE);
-       cprintf("%s\n", config.c_moreprompt);
-       cprintf("1\n"); /* 1 = yes, this system supports floors */
-       cprintf("1\n"); /* 1 = we support the extended paging options */
-       cprintf("\n");  /* nonce no longer supported */
-       cprintf("1\n"); /* 1 = yes, this system supports the QNOP command */
-
-#ifdef HAVE_LDAP
-       cprintf("1\n"); /* 1 = yes, this server is LDAP-enabled */
-#else
-       cprintf("0\n"); /* 1 = no, this server is not LDAP-enabled */
-#endif
-
-       if (config.c_auth_mode == AUTHMODE_NATIVE) {
-               cprintf("%d\n", config.c_disable_newu);
-       }
-       else {
-               cprintf("1\n"); /* "create new user" does not work with non-native auth modes */
-       }
-
-       cprintf("%s\n", config.c_default_cal_zone);
-
-       /* thread load averages -- temporarily disabled during refactoring of this code */
-       cprintf("0\n");         /* load average */
-       cprintf("0\n");         /* worker average */
-       cprintf("0\n");         /* thread count */
-
-       cprintf("1\n");         /* yes, Sieve mail filtering is supported */
-       cprintf("%d\n", config.c_enable_fulltext);
-       cprintf("%s\n", svn_revision());
-
-       if (config.c_auth_mode == AUTHMODE_NATIVE) {
-               cprintf("%d\n", openid_level_supported); /* OpenID is enabled when using native auth */
-       }
-       else {
-               cprintf("0\n"); /* OpenID is disabled when using non-native auth */
-       }
-
-       cprintf("%d\n", config.c_guest_logins);
-       
-       cprintf("000\n");
-}
-
-
 /*
  * returns an asterisk if there are any instant messages waiting,
  * space otherwise.
@@ -333,22 +266,6 @@ char CtdlCheckExpress(void) {
        }
 }
 
-void cmd_time(char *argbuf)
-{
-   time_t tv;
-   struct tm tmp;
-   
-   tv = time(NULL);
-   localtime_r(&tv, &tmp);
-   
-   /* timezone and daylight global variables are not portable. */
-#ifdef HAVE_STRUCT_TM_TM_GMTOFF
-   cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, tmp.tm_gmtoff, tmp.tm_isdst);
-#else
-   cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, timezone, tmp.tm_isdst);
-#endif
-}
-
 
 /*
  * Check originating host against the public_clients file.  This determines
@@ -430,7 +347,7 @@ int is_public_client(void)
                                        }
                                }
                        }
-               fclose(fp);
+               if (fp != NULL) fclose(fp);
                pc_timestamp = time(NULL);
                end_critical_section(S_PUBLIC_CLIENTS);
        }
@@ -440,7 +357,7 @@ int is_public_client(void)
        for (i=0; i<num_parms(public_clients); ++i) {
                extract_token(addrbuf, public_clients, i, '|', sizeof addrbuf);
                if (!strcasecmp(CC->cs_addr, addrbuf)) {
-                       syslog(LOG_DEBUG, "... yes it is.\n");
+                       syslog(LOG_DEBUG, "... yes its local.\n");
                        return(1);
                }
        }
@@ -451,55 +368,40 @@ int is_public_client(void)
 }
 
 
-/*
- * the client is identifying itself to the server
+
+/* 
+ * help_subst()  -  support routine for help file viewer
  */
-void cmd_iden(char *argbuf)
+void help_subst(char *strbuf, char *source, char *dest)
 {
-       int dev_code;
-       int cli_code;
-       int rev_level;
-       char desc[128];
-       char from_host[128];
-
-       if (num_parms(argbuf)<4) {
-               cprintf("%d usage error\n", ERROR + ILLEGAL_VALUE);
-               return;
-       }
+       char workbuf[SIZ];
+       int p;
 
-       dev_code = extract_int(argbuf,0);
-       cli_code = extract_int(argbuf,1);
-       rev_level = extract_int(argbuf,2);
-       extract_token(desc, argbuf, 3, '|', sizeof desc);
-
-       safestrncpy(from_host, config.c_fqdn, sizeof from_host);
-       from_host[sizeof from_host - 1] = 0;
-       if (num_parms(argbuf)>=5) extract_token(from_host, argbuf, 4, '|', sizeof from_host);
-
-       CC->cs_clientdev = dev_code;
-       CC->cs_clienttyp = cli_code;
-       CC->cs_clientver = rev_level;
-       safestrncpy(CC->cs_clientname, desc, sizeof CC->cs_clientname);
-       CC->cs_clientname[31] = 0;
-
-       /* For local sockets and public clients, trust the hostname supplied by the client */
-       if ( (CC->is_local_socket) || (is_public_client()) ) {
-               safestrncpy(CC->cs_host, from_host, sizeof CC->cs_host);
-               CC->cs_host[sizeof CC->cs_host - 1] = 0;
-               CC->cs_addr[0] = 0;
+       while (p = pattern2(strbuf, source), (p >= 0)) {
+               strcpy(workbuf, &strbuf[p + strlen(source)]);
+               strcpy(&strbuf[p], dest);
+               strcat(strbuf, workbuf);
        }
+}
 
-       syslog(LOG_NOTICE, "Client %d/%d/%01d.%02d (%s) from %s\n",
-               dev_code,
-               cli_code,
-               (rev_level / 100),
-               (rev_level % 100),
-               desc,
-               CC->cs_host
-       );
-       cprintf("%d Ok\n",CIT_OK);
+void do_help_subst(char *buffer)
+{
+       char buf2[16];
+
+       help_subst(buffer, "^nodename", config.c_nodename);
+       help_subst(buffer, "^humannode", config.c_humannode);
+       help_subst(buffer, "^fqdn", config.c_fqdn);
+       help_subst(buffer, "^username", CC->user.fullname);
+       snprintf(buf2, sizeof buf2, "%ld", CC->user.usernum);
+       help_subst(buffer, "^usernum", buf2);
+       help_subst(buffer, "^sysadm", config.c_sysadm);
+       help_subst(buffer, "^variantname", CITADEL);
+       snprintf(buf2, sizeof buf2, "%d", config.c_maxsessions);
+       help_subst(buffer, "^maxsessions", buf2);
+       help_subst(buffer, "^bbsdir", ctdl_message_dir);
 }
 
+
 typedef const char *ccharp;
 /*
  * display system messages or help
@@ -652,7 +554,7 @@ void GenerateRoomDisplay(char *real_room,
        if (viewed->room.QRflags & QR_PRIVATE) {
                CtdlRoomAccess(&viewed->room, &viewer->user, &ra, NULL);
                if ( (ra & UA_KNOWN) == 0) {
-                       strcpy(real_room, "<private room>");
+                       strcpy(real_room, " ");
                }
        }
 
@@ -689,14 +591,14 @@ int CtdlAccessCheck(int required_level) {
 
        if (CC->user.axlevel >= AxAideU) return(0);
        if (required_level >= ac_aide) {
-               cprintf("%d This command requires Aide access.\n",
+               cprintf("%d This command requires Admin access.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
                return(-1);
        }
 
        if (is_room_aide()) return(0);
        if (required_level >= ac_room_aide) {
-               cprintf("%d This command requires Aide or Room Aide access.\n",
+               cprintf("%d This command requires Admin or Room Admin access.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
                return(-1);
        }
@@ -707,84 +609,7 @@ int CtdlAccessCheck(int required_level) {
 
 
 
-/*
- * Terminate another running session
- */
-void cmd_term(char *cmdbuf)
-{
-       int session_num;
-       int terminated = 0;
-
-       session_num = extract_int(cmdbuf, 0);
 
-       terminated = CtdlTerminateOtherSession(session_num);
-
-       if (terminated < 0) {
-               cprintf("%d You can't kill your own session.\n", ERROR + ILLEGAL_VALUE);
-               return;
-       }
-
-       if (terminated & TERM_FOUND) {
-               if (terminated == TERM_KILLED) {
-                       cprintf("%d Session terminated.\n", CIT_OK);
-               }
-               else {
-                       cprintf("%d You are not allowed to do that.\n",
-                               ERROR + HIGHER_ACCESS_REQUIRED);
-               }
-       }
-       else {
-               cprintf("%d No such session.\n", ERROR + ILLEGAL_VALUE);
-       }
-}
-
-
-/* 
- * get the paginator prompt
- */
-void cmd_more(char *argbuf) {
-       cprintf("%d %s\n", CIT_OK, config.c_moreprompt);
-}
-
-
-/*
- * echo 
- */
-void cmd_echo(char *etext)
-{
-       cprintf("%d %s\n", CIT_OK, etext);
-}
-
-
-/* 
- * Perform privilege escalation for an internal program
- */
-void cmd_ipgm(char *argbuf)
-{
-       int secret;
-
-       secret = extract_int(argbuf, 0);
-
-       /* For security reasons, we do NOT allow this command to run
-        * over the network.  Local sockets only.
-        */
-       if (!CC->is_local_socket) {
-               sleep(5);
-               cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
-       }
-       else if (secret == config.c_ipgm_secret) {
-               CC->internal_pgm = 1;
-               strcpy(CC->curr_user, "<internal program>");
-               CC->cs_flags = CC->cs_flags|CS_STEALTH;
-               cprintf("%d Authenticated as an internal program.\n", CIT_OK);
-       }
-       else {
-               sleep(5);
-               cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
-               syslog(LOG_ERR, "Warning: ipgm authentication failed.\n");
-               CC->kill_me = KILLME_AUTHFAILED;
-       }
-}
 
 
 /*
@@ -817,7 +642,7 @@ void cmd_down(char *argbuf) {
                cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN); 
        }
        CC->kill_me = KILLME_SERVER_SHUTTING_DOWN;
-       CtdlThreadStopAll();
+       server_shutting_down = 1;
 }
 
 
@@ -829,7 +654,7 @@ void cmd_halt(char *argbuf) {
        if (CtdlAccessCheck(ac_aide)) return;
 
        cprintf("%d Halting server.  Goodbye.\n", CIT_OK);
-       CtdlThreadStopAll();
+       server_shutting_down = 1;
        shutdown_and_halt = 1;
 }
 
@@ -866,30 +691,12 @@ void cmd_scdn(char *argbuf)
 }
 
 
-/*
- * Set or unset asynchronous protocol mode
- */
-void cmd_asyn(char *argbuf)
-{
-       int new_state;
-
-       new_state = extract_int(argbuf, 0);
-       if ((new_state == 0) || (new_state == 1)) {
-               CC->is_async = new_state;
-       }
-       cprintf("%d %d\n", CIT_OK, CC->is_async);
-}
-
-
 
 /*
  * Back-end function for starting a session
  */
 void begin_session(CitContext *con)
 {
-       socklen_t len;
-       struct sockaddr_in sin;
-
        /* 
         * Initialize some variables specific to our context.
         */
@@ -914,7 +721,6 @@ void begin_session(CitContext *con)
        safestrncpy(con->cs_addr, "", sizeof con->cs_addr);
        con->cs_UDSclientUID = -1;
        con->cs_host[sizeof con->cs_host - 1] = 0;
-       len = sizeof sin;
        if (!CC->is_local_socket) {
                locate_host(con->cs_host, sizeof con->cs_host,
                        con->cs_addr, sizeof con->cs_addr,
@@ -994,31 +800,12 @@ void citproto_begin_session() {
 }
 
 
-void cmd_noop(char *argbuf)
-{
-       cprintf("%d%cok\n", CIT_OK, CtdlCheckExpress() );
-}
-
-
-void cmd_qnop(char *argbuf)
-{
-       /* do nothing, this command returns no response */
+void citproto_begin_admin_session() {
+       CC->internal_pgm = 1;
+       cprintf("%d %s Citadel server ADMIN CONNECTION ready.\n", CIT_OK, config.c_nodename);
 }
 
 
-void cmd_quit(char *argbuf)
-{
-       cprintf("%d Goodbye.\n", CIT_OK);
-       CC->kill_me = KILLME_CLIENT_LOGGED_OUT;
-}
-
-
-void cmd_lout(char *argbuf)
-{
-       if (CC->logged_in) 
-               CtdlUserLogout();
-       cprintf("%d logged out.\n", CIT_OK);
-}
 
 
 /*
@@ -1037,10 +824,14 @@ void do_command_loop(void) {
 
        /* Log the server command, but don't show passwords... */
        if ( (strncasecmp(cmdbuf, "PASS", 4)) && (strncasecmp(cmdbuf, "SETP", 4)) ) {
-               syslog(LOG_INFO, "CtdlCommand [%s] [%s] %s\n", CTDLUSERIP, CC->curr_user, cmdbuf);
+               syslog(LOG_INFO, "[%d][%s(%ld)] %s",
+                       CC->cs_pid, CC->curr_user, CC->user.usernum, cmdbuf
+               );
        }
        else {
-               syslog(LOG_INFO, "CtdlCommand [%s] [%s] <password command hidden from log>\n", CTDLUSERIP, CC->curr_user);
+               syslog(LOG_INFO, "[%d][%s(%ld)] <password command hidden from log>",
+                       CC->cs_pid, CC->curr_user, CC->user.usernum
+               );
        }
 
        buffer_output();
@@ -1093,23 +884,13 @@ void do_async_loop(void) {
 CTDL_MODULE_INIT(citserver)
 {
        if (!threading) {
-               CtdlRegisterProtoHook(cmd_noop, "NOOP", "no operation");
-               CtdlRegisterProtoHook(cmd_qnop, "QNOP", "no operation with no response");
-               CtdlRegisterProtoHook(cmd_quit, "QUIT", "log out and disconnect from server");
-               CtdlRegisterProtoHook(cmd_lout, "LOUT", "log out but do not disconnect from server");
-               CtdlRegisterProtoHook(cmd_asyn, "ASYN", "enable asynchronous server responses");
-               CtdlRegisterProtoHook(cmd_info, "INFO", "fetch server capabilities and configuration");
+
                CtdlRegisterProtoHook(cmd_mesg, "MESG", "fetch system banners");
                CtdlRegisterProtoHook(cmd_emsg, "EMSG", "submit system banners");
-               CtdlRegisterProtoHook(cmd_echo, "ECHO", "echo text back to the client");
-               CtdlRegisterProtoHook(cmd_more, "MORE", "fetch the paginator prompt");
-               CtdlRegisterProtoHook(cmd_iden, "IDEN", "identify the client software and location");
-               CtdlRegisterProtoHook(cmd_ipgm, "IPGM", "perform privilege escalation for internal programs");
-               CtdlRegisterProtoHook(cmd_term, "TERM", "terminate another running session");
+;
                CtdlRegisterProtoHook(cmd_down, "DOWN", "perform a server shutdown");
                CtdlRegisterProtoHook(cmd_halt, "HALT", "halt the server without exiting the server process");
                CtdlRegisterProtoHook(cmd_scdn, "SCDN", "schedule or cancel a server shutdown");
-               CtdlRegisterProtoHook(cmd_time, "TIME", "fetch the date and time from the server");
        }
         /* return our id for the Log */
        return "citserver";