Began removing $Id$ tags. This will be an ongoing process.
[citadel.git] / citadel / citserver.c
index d0c7007ff37cdd020b21e8c76f7752f7c6a57d5f..48e4deae038439e250011538a2e800934481aa86 100644 (file)
@@ -1,23 +1,21 @@
 /* 
- * $Id$
- *
  * Main source module for the Citadel server
  *
- * Copyright (c) 1987-2009 by the citadel.org team
+ * Copyright (c) 1987-2010 by the citadel.org team
  *
- *  This program is free 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.
+ * This program is free 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.
  *
- *  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.
+ * 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
+ * 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"
@@ -29,7 +27,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
@@ -70,7 +67,6 @@
 #include "locate_host.h"
 #include "room_ops.h"
 #include "file_ops.h"
-#include "policy.h"
 #include "control.h"
 #include "euidindex.h"
 #include "context.h"
 
 #include "ctdl_module.h"
 
-
 char *unique_session_numbers;
 int ScheduledShutdown = 0;
 time_t server_startup_time;
 int panic_fd;
 
-/**
- * \brief print the actual stack frame.
+/*
+ * print the actual stack frame.
  */
 void cit_backtrace(void)
 {
@@ -111,8 +106,8 @@ void cit_backtrace(void)
 #endif
 }
 
-/**
- * \brief print the actual stack frame.
+/*
+ * print the actual stack frame.
  */
 void cit_panic_backtrace(int SigNum)
 {
@@ -160,7 +155,7 @@ void master_startup(void) {
        CtdlLogPrintf(CTDL_INFO, "Creating base rooms (if necessary)\n");
        CtdlCreateRoom(config.c_baseroom,       0, "", 0, 1, 0, VIEW_BBS);
        CtdlCreateRoom(AIDEROOM,                3, "", 0, 1, 0, VIEW_BBS);
-       CtdlCreateRoom(SYSCONFIGROOM,   3, "", 0, 1, 0, VIEW_BBS);
+       CtdlCreateRoom(SYSCONFIGROOM,           3, "", 0, 1, 0, VIEW_BBS);
        CtdlCreateRoom(config.c_twitroom,       0, "", 0, 1, 0, VIEW_BBS);
 
        /* The "Local System Configuration" room doesn't need to be visible */
@@ -243,7 +238,7 @@ void master_cleanup(int exitcode) {
        
        if (restart_server != 0)
                exit(1);
-       if ((running_as_daemon != 0) && (exitcode == 0))
+       if ((running_as_daemon != 0) && ((exitcode == 0) ))
                exitcode = CTDLEXIT_SHUTDOWN;
        exit(exitcode);
 }
@@ -300,6 +295,8 @@ void cmd_info(char *cmdbuf) {
        else {
                cprintf("0\n"); /* OpenID is disabled when using non-native auth */
        }
+
+       cprintf("%d\n", config.c_guest_logins);
        
        cprintf("000\n");
 }
@@ -357,10 +354,7 @@ int is_public_client(void)
 
 #define LOCALHOSTSTR "127.0.0.1"
 
-       snprintf(public_clients_file, 
-                        sizeof public_clients_file,
-                        "%s/public_clients",
-                        ctdl_etc_dir);
+       snprintf(public_clients_file, sizeof public_clients_file, "%s/public_clients", ctdl_etc_dir);
 
        /*
         * Check the time stamp on the public_clients file.  If it's been
@@ -449,8 +443,6 @@ void cmd_iden(char *argbuf)
        int rev_level;
        char desc[128];
        char from_host[128];
-       struct in_addr addr;
-       int do_lookup = 0;
 
        if (num_parms(argbuf)<4) {
                cprintf("%d usage error\n", ERROR + ILLEGAL_VALUE);
@@ -472,22 +464,11 @@ void cmd_iden(char *argbuf)
        safestrncpy(CC->cs_clientname, desc, sizeof CC->cs_clientname);
        CC->cs_clientname[31] = 0;
 
-       if (!IsEmptyStr(from_host)) {
-               if (CC->is_local_socket) do_lookup = 1;
-               else if (is_public_client()) do_lookup = 1;
-       }
-
-       if (do_lookup) {
-               CtdlLogPrintf(CTDL_DEBUG, "Looking up hostname '%s'\n", from_host);
-               if ((addr.s_addr = inet_addr(from_host)) != -1) {
-                       locate_host(CC->cs_host, sizeof CC->cs_host,
-                               CC->cs_addr, sizeof CC->cs_addr,
-                               &addr);
-               }
-               else {
-                       safestrncpy(CC->cs_host, from_host, sizeof CC->cs_host);
-                       CC->cs_host[sizeof CC->cs_host - 1] = 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;
        }
 
        CtdlLogPrintf(CTDL_NOTICE, "Client %d/%d/%01d.%02d (%s) from %s\n",
@@ -496,7 +477,8 @@ void cmd_iden(char *argbuf)
                (rev_level / 100),
                (rev_level % 100),
                desc,
-               CC->cs_host);
+               CC->cs_host
+       );
        cprintf("%d Ok\n",CIT_OK);
 }
 
@@ -682,7 +664,7 @@ int CtdlAccessCheck(int required_level) {
                return(-1);
        }
 
-       if (CC->user.axlevel >= 6) return(0);
+       if (CC->user.axlevel >= AxAideU) return(0);
        if (required_level >= ac_aide) {
                cprintf("%d This command requires Aide access.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
@@ -708,35 +690,19 @@ int CtdlAccessCheck(int required_level) {
 void cmd_term(char *cmdbuf)
 {
        int session_num;
-       CitContext *ccptr;
-       int found_it = 0;
-       int allowed = 0;
+       int terminated = 0;
 
        session_num = extract_int(cmdbuf, 0);
-       if (session_num == CC->cs_pid) {
+
+       terminated = CtdlTerminateOtherSession(session_num);
+
+       if (terminated < 0) {
                cprintf("%d You can't kill your own session.\n", ERROR + ILLEGAL_VALUE);
                return;
        }
 
-       CtdlLogPrintf(CTDL_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) {
-                       found_it = 1;
-                       if ((ccptr->user.usernum == CC->user.usernum)
-                          || (CC->user.axlevel >= 6)) {
-                               allowed = 1;
-                               ccptr->kill_me = 1;
-                       }
-                       else {
-                               allowed = 0;
-                       }
-               }
-       }
-       end_critical_section(S_SESSION_TABLE);
-
-       if (found_it) {
-               if (allowed) {
+       if (terminated & TERM_FOUND) {
+               if (terminated == TERM_KILLED) {
                        cprintf("%d Session terminated.\n", CIT_OK);
                }
                else {
@@ -750,9 +716,6 @@ void cmd_term(char *cmdbuf)
 }
 
 
-
-
-
 /* 
  * get the paginator prompt
  */
@@ -760,6 +723,7 @@ void cmd_more(char *argbuf) {
        cprintf("%d %s\n", CIT_OK, config.c_moreprompt);
 }
 
+
 /*
  * echo 
  */
@@ -769,9 +733,8 @@ void cmd_echo(char *etext)
 }
 
 
-
 /* 
- * identify as internal program
+ * Perform privilege escalation for an internal program
  */
 void cmd_ipgm(char *argbuf)
 {
@@ -784,8 +747,7 @@ void cmd_ipgm(char *argbuf)
         */
        if (!CC->is_local_socket) {
                sleep(5);
-               cprintf("%d Authentication failed.\n",
-                       ERROR + PASSWORD_REQUIRED);
+               cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
        }
        else if (secret == config.c_ipgm_secret) {
                CC->internal_pgm = 1;
@@ -795,8 +757,7 @@ void cmd_ipgm(char *argbuf)
        }
        else {
                sleep(5);
-               cprintf("%d Authentication failed.\n",
-                       ERROR + PASSWORD_REQUIRED);
+               cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED);
                CtdlLogPrintf(CTDL_ERR, "Warning: ipgm authentication failed.\n");
                CC->kill_me = 1;
        }
@@ -836,6 +797,7 @@ void cmd_down(char *argbuf) {
        CtdlThreadStopAll();
 }
 
+
 /*
  * Halt the server without exiting the server process.
  */
@@ -848,6 +810,7 @@ void cmd_halt(char *argbuf) {
        shutdown_and_halt = 1;
 }
 
+
 /*
  * Schedule or cancel a server shutdown
  */
@@ -912,8 +875,6 @@ void generate_nonce(CitContext *con) {
 }
 
 
-
-
 /*
  * Back-end function for starting a session
  */
@@ -946,15 +907,14 @@ void begin_session(CitContext *con)
        con->cs_host[sizeof con->cs_host - 1] = 0;
        len = sizeof sin;
        if (!CC->is_local_socket) {
-               if (!getpeername(con->client_socket, (struct sockaddr *) &sin, &len)) {
-                       locate_host(con->cs_host, sizeof con->cs_host,
-                               con->cs_addr, sizeof con->cs_addr,
-                               &sin.sin_addr
-                       );
-               }
+               locate_host(con->cs_host, sizeof con->cs_host,
+                       con->cs_addr, sizeof con->cs_addr,
+                       con->client_socket
+               );
        }
        else {
-               strcpy(con->cs_host, "");
+               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... */
@@ -994,10 +954,10 @@ void begin_session(CitContext *con)
        }
 
        if (!CC->is_local_socket) {
-               CtdlLogPrintf(CTDL_NOTICE, "Session started from %s [%s].\n", con->cs_host, con->cs_addr);
+               CtdlLogPrintf(CTDL_NOTICE, "Session (%s) started from %s (%s).\n", con->ServiceName, con->cs_host, con->cs_addr);
        }
        else {
-               CtdlLogPrintf(CTDL_NOTICE, "Session started via local socket.\n");
+               CtdlLogPrintf(CTDL_NOTICE, "Session (%s) started via local socket UID:%d.\n", con->ServiceName, con->cs_UDSclientUID);
        }
 
        /* Run any session startup routines registered by loadable modules */
@@ -1020,23 +980,25 @@ 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 cmd_quit(char *argbuf)
 {
        cprintf("%d Goodbye.\n", CIT_OK);
        CC->kill_me = 1;
 }
 
+
 void cmd_lout(char *argbuf)
 {
        if (CC->logged_in) 
@@ -1044,6 +1006,7 @@ void cmd_lout(char *argbuf)
        cprintf("%d logged out.\n", CIT_OK);
 }
 
+
 /*
  * This loop recognizes all server commands.
  */
@@ -1063,12 +1026,11 @@ void do_command_loop(void) {
        }
 
        /* Log the server command, but don't show passwords... */
-       if ( (strncasecmp(cmdbuf, "PASS", 4))
-          && (strncasecmp(cmdbuf, "SETP", 4)) ) {
+       if ( (strncasecmp(cmdbuf, "PASS", 4)) && (strncasecmp(cmdbuf, "SETP", 4)) ) {
                CtdlLogPrintf(CTDL_INFO, "%s\n", cmdbuf);
        }
        else {
-               CtdlLogPrintf(CTDL_INFO, "<password command sent>\n");
+               CtdlLogPrintf(CTDL_INFO, "<password command hidden from log>\n");
        }
 
        buffer_output();
@@ -1117,11 +1079,6 @@ void do_async_loop(void) {
 }
 
 
-
-
-
-
-
 /*****************************************************************************/
 /*                      MODULE INITIALIZATION STUFF                          */
 /*****************************************************************************/
@@ -1129,24 +1086,24 @@ void do_async_loop(void) {
 CTDL_MODULE_INIT(citserver)
 {
        if (!threading) {
-               CtdlRegisterProtoHook(cmd_noop, "NOOP", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_qnop, "QNOP", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_quit, "QUIT", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_lout, "LOUT", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_asyn, "ASYN", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_info, "INFO", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_mesg, "MESG", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_emsg, "EMSG", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_echo, "ECHO", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_more, "MORE", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_iden, "IDEN", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_ipgm, "IPGM", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_term, "TERM", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_down, "DOWN", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_halt, "HALT", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_scdn, "SCDN", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_time, "TIME", "Autoconverted. TODO: document me.");
+               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 Subversion id for the Log */
-       return "$Id$";
+        /* return our id for the Log */
+       return "citserver";
 }