diff options
Diffstat (limited to 'contrib/sendmail/src/control.c')
-rw-r--r-- | contrib/sendmail/src/control.c | 437 |
1 files changed, 0 insertions, 437 deletions
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c deleted file mode 100644 index 0d7ee0b43be6..000000000000 --- a/contrib/sendmail/src/control.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - * - */ - -#include <sendmail.h> - -SM_RCSID("@(#)$Id: control.c,v 8.126 2004/08/04 20:54:00 ca Exp $") - -#include <sm/fdset.h> - -/* values for cmd_code */ -#define CMDERROR 0 /* bad command */ -#define CMDRESTART 1 /* restart daemon */ -#define CMDSHUTDOWN 2 /* end daemon */ -#define CMDHELP 3 /* help */ -#define CMDSTATUS 4 /* daemon status */ -#define CMDMEMDUMP 5 /* dump memory, to find memory leaks */ -#if _FFR_CONTROL_MSTAT -# define CMDMSTAT 6 /* daemon status, more info, tagged data */ -#endif /* _FFR_CONTROL_MSTAT */ - -struct cmd -{ - char *cmd_name; /* command name */ - int cmd_code; /* internal code, see below */ -}; - -static struct cmd CmdTab[] = -{ - { "help", CMDHELP }, - { "restart", CMDRESTART }, - { "shutdown", CMDSHUTDOWN }, - { "status", CMDSTATUS }, - { "memdump", CMDMEMDUMP }, -#if _FFR_CONTROL_MSTAT - { "mstat", CMDMSTAT }, -#endif /* _FFR_CONTROL_MSTAT */ - { NULL, CMDERROR } -}; - - - -static void controltimeout __P((int)); -int ControlSocket = -1; - -/* -** OPENCONTROLSOCKET -- create/open the daemon control named socket -** -** Creates and opens a named socket for external control over -** the sendmail daemon. -** -** Parameters: -** none. -** -** Returns: -** 0 if successful, -1 otherwise -*/ - -int -opencontrolsocket() -{ -# if NETUNIX - int save_errno; - int rval; - long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN; - struct sockaddr_un controladdr; - - if (ControlSocketName == NULL || *ControlSocketName == '\0') - return 0; - - if (strlen(ControlSocketName) >= sizeof controladdr.sun_path) - { - errno = ENAMETOOLONG; - return -1; - } - - rval = safefile(ControlSocketName, RunAsUid, RunAsGid, RunAsUserName, - sff, S_IRUSR|S_IWUSR, NULL); - - /* if not safe, don't create */ - if (rval != 0) - { - errno = rval; - return -1; - } - - ControlSocket = socket(AF_UNIX, SOCK_STREAM, 0); - if (ControlSocket < 0) - return -1; - if (SM_FD_SETSIZE > 0 && ControlSocket >= SM_FD_SETSIZE) - { - clrcontrol(); - errno = EINVAL; - return -1; - } - - (void) unlink(ControlSocketName); - memset(&controladdr, '\0', sizeof controladdr); - controladdr.sun_family = AF_UNIX; - (void) sm_strlcpy(controladdr.sun_path, ControlSocketName, - sizeof controladdr.sun_path); - - if (bind(ControlSocket, (struct sockaddr *) &controladdr, - sizeof controladdr) < 0) - { - save_errno = errno; - clrcontrol(); - errno = save_errno; - return -1; - } - - if (geteuid() == 0) - { - uid_t u = 0; - - if (RunAsUid != 0) - u = RunAsUid; - else if (TrustedUid != 0) - u = TrustedUid; - - if (u != 0 && - chown(ControlSocketName, u, -1) < 0) - { - save_errno = errno; - sm_syslog(LOG_ALERT, NOQID, - "ownership change on %s to uid %d failed: %s", - ControlSocketName, (int) u, - sm_errstring(save_errno)); - message("050 ownership change on %s to uid %d failed: %s", - ControlSocketName, (int) u, - sm_errstring(save_errno)); - closecontrolsocket(true); - errno = save_errno; - return -1; - } - } - - if (chmod(ControlSocketName, S_IRUSR|S_IWUSR) < 0) - { - save_errno = errno; - closecontrolsocket(true); - errno = save_errno; - return -1; - } - - if (listen(ControlSocket, 8) < 0) - { - save_errno = errno; - closecontrolsocket(true); - errno = save_errno; - return -1; - } -# endif /* NETUNIX */ - return 0; -} -/* -** CLOSECONTROLSOCKET -- close the daemon control named socket -** -** Close a named socket. -** -** Parameters: -** fullclose -- if set, close the socket and remove it; -** otherwise, just remove it -** -** Returns: -** none. -*/ - -void -closecontrolsocket(fullclose) - bool fullclose; -{ -# if NETUNIX - long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN; - - if (ControlSocket >= 0) - { - int rval; - - if (fullclose) - { - (void) close(ControlSocket); - ControlSocket = -1; - } - - rval = safefile(ControlSocketName, RunAsUid, RunAsGid, - RunAsUserName, sff, S_IRUSR|S_IWUSR, NULL); - - /* if not safe, don't unlink */ - if (rval != 0) - return; - - if (unlink(ControlSocketName) < 0) - { - sm_syslog(LOG_WARNING, NOQID, - "Could not remove control socket: %s", - sm_errstring(errno)); - return; - } - } -# endif /* NETUNIX */ - return; -} -/* -** CLRCONTROL -- reset the control connection -** -** Parameters: -** none. -** -** Returns: -** none. -** -** Side Effects: -** releases any resources used by the control interface. -*/ - -void -clrcontrol() -{ -# if NETUNIX - if (ControlSocket >= 0) - (void) close(ControlSocket); - ControlSocket = -1; -# endif /* NETUNIX */ -} -/* -** CONTROL_COMMAND -- read and process command from named socket -** -** Read and process the command from the opened socket. -** Exits when done since it is running in a forked child. -** -** Parameters: -** sock -- the opened socket from getrequests() -** e -- the current envelope -** -** Returns: -** none. -*/ - -static jmp_buf CtxControlTimeout; - -/* ARGSUSED0 */ -static void -controltimeout(timeout) - int timeout; -{ - /* - ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD - ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE - ** DOING. - */ - - errno = ETIMEDOUT; - longjmp(CtxControlTimeout, 1); -} - -void -control_command(sock, e) - int sock; - ENVELOPE *e; -{ - volatile int exitstat = EX_OK; - SM_FILE_T *s = NULL; - SM_EVENT *ev = NULL; - SM_FILE_T *traffic; - SM_FILE_T *oldout; - char *cmd; - char *p; - struct cmd *c; - char cmdbuf[MAXLINE]; - char inp[MAXLINE]; - - sm_setproctitle(false, e, "control cmd read"); - - if (TimeOuts.to_control > 0) - { - /* handle possible input timeout */ - if (setjmp(CtxControlTimeout) != 0) - { - if (LogLevel > 2) - sm_syslog(LOG_NOTICE, e->e_id, - "timeout waiting for input during control command"); - exit(EX_IOERR); - } - ev = sm_setevent(TimeOuts.to_control, controltimeout, - TimeOuts.to_control); - } - - s = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &sock, - SM_IO_RDWR, NULL); - if (s == NULL) - { - int save_errno = errno; - - (void) close(sock); - errno = save_errno; - exit(EX_IOERR); - } - (void) sm_io_setvbuf(s, SM_TIME_DEFAULT, NULL, - SM_IO_NBF, SM_IO_BUFSIZ); - - if (sm_io_fgets(s, SM_TIME_DEFAULT, inp, sizeof inp) == NULL) - { - (void) sm_io_close(s, SM_TIME_DEFAULT); - exit(EX_IOERR); - } - (void) sm_io_flush(s, SM_TIME_DEFAULT); - - /* clean up end of line */ - fixcrlf(inp, true); - - sm_setproctitle(false, e, "control: %s", inp); - - /* break off command */ - for (p = inp; isascii(*p) && isspace(*p); p++) - continue; - cmd = cmdbuf; - while (*p != '\0' && - !(isascii(*p) && isspace(*p)) && - cmd < &cmdbuf[sizeof cmdbuf - 2]) - *cmd++ = *p++; - *cmd = '\0'; - - /* throw away leading whitespace */ - while (isascii(*p) && isspace(*p)) - p++; - - /* decode command */ - for (c = CmdTab; c->cmd_name != NULL; c++) - { - if (sm_strcasecmp(c->cmd_name, cmdbuf) == 0) - break; - } - - switch (c->cmd_code) - { - case CMDHELP: /* get help */ - traffic = TrafficLogFile; - TrafficLogFile = NULL; - oldout = OutChannel; - OutChannel = s; - help("control", e); - TrafficLogFile = traffic; - OutChannel = oldout; - break; - - case CMDRESTART: /* restart the daemon */ - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, "OK\r\n"); - exitstat = EX_RESTART; - break; - - case CMDSHUTDOWN: /* kill the daemon */ - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, "OK\r\n"); - exitstat = EX_SHUTDOWN; - break; - - case CMDSTATUS: /* daemon status */ - proc_list_probe(); - { - int qgrp; - long bsize; - long free; - - /* XXX need to deal with different partitions */ - qgrp = e->e_qgrp; - if (!ISVALIDQGRP(qgrp)) - qgrp = 0; - free = freediskspace(Queue[qgrp]->qg_qdir, &bsize); - - /* - ** Prevent overflow and don't lose - ** precision (if bsize == 512) - */ - - if (free > 0) - free = (long)((double) free * - ((double) bsize / 1024)); - - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "%d/%d/%ld/%d\r\n", - CurChildren, MaxChildren, - free, getla()); - } - proc_list_display(s, ""); - break; - -# if _FFR_CONTROL_MSTAT - case CMDMSTAT: /* daemon status, extended, tagged format */ - proc_list_probe(); - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "C:%d\r\nM:%d\r\nL:%d\r\n", - CurChildren, MaxChildren, - getla()); - printnqe(s, "Q:"); - disk_status(s, "D:"); - proc_list_display(s, "P:"); - break; -# endif /* _FFR_CONTROL_MSTAT */ - - case CMDMEMDUMP: /* daemon memory dump, to find memory leaks */ -# if SM_HEAP_CHECK - /* dump the heap, if we are checking for memory leaks */ - if (sm_debug_active(&SmHeapCheck, 2)) - { - sm_heap_report(s, sm_debug_level(&SmHeapCheck) - 1); - } - else - { - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "Memory dump unavailable.\r\n"); - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "To fix, run sendmail with -dsm_check_heap.4\r\n"); - } -# else /* SM_HEAP_CHECK */ - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "Memory dump unavailable.\r\n"); - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "To fix, rebuild with -DSM_HEAP_CHECK\r\n"); -# endif /* SM_HEAP_CHECK */ - break; - - case CMDERROR: /* unknown command */ - (void) sm_io_fprintf(s, SM_TIME_DEFAULT, - "Bad command (%s)\r\n", cmdbuf); - break; - } - (void) sm_io_close(s, SM_TIME_DEFAULT); - if (ev != NULL) - sm_clrevent(ev); - exit(exitstat); -} |