-/* This file is part of the IPCop Firewall.\r
- *\r
- * This program is distributed under the terms of the GNU General Public\r
- * Licence. See the file COPYING for details.\r
- *\r
- * Copyright (C) 2003-07-12 Robert Kerr <rkerr@go.to>\r
- *\r
- * $Id: restartsyslogd.c,v 1.2.2.3 2004/12/14 17:56:37 gespinasse Exp $\r
- *\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <string.h>\r
-#include <sys/stat.h>\r
-#include <sys/types.h>\r
-#include <fcntl.h>\r
-#include <signal.h>\r
-#include <errno.h>\r
-#include "libsmooth.h"\r
-#include "setuid.h"\r
-\r
-#define ERR_ANY 1\r
-#define ERR_SETTINGS 2 /* error in settings file */\r
-#define ERR_ETC 3 /* error with /etc permissions */\r
-#define ERR_CONFIG 4 /* error updated sshd_config */\r
-#define ERR_SYSLOG 5 /* error restarting syslogd */\r
-\r
-int main(void)\r
-{\r
- char buffer[STRING_SIZE], hostname[STRING_SIZE];\r
- int config_fd,rc,fd,pid;\r
- struct stat st;\r
- struct keyvalue *kv = NULL;\r
- memset(buffer, 0, STRING_SIZE);\r
- memset(hostname, 0, STRING_SIZE);\r
-\r
- if (!(initsetuid()))\r
- exit(1);\r
-\r
-\r
- /* Read in and verify config */\r
- kv=initkeyvalues();\r
-\r
- if (!readkeyvalues(kv, CONFIG_ROOT "/logging/settings"))\r
- {\r
- fprintf(stderr, "Cannot read syslog settings\n");\r
- exit(ERR_SETTINGS);\r
- }\r
-\r
- if (!findkey(kv, "ENABLE_REMOTELOG", buffer))\r
- {\r
- fprintf(stderr, "Cannot read ENABLE_REMOTELOG\n");\r
- exit(ERR_SETTINGS);\r
- }\r
-\r
- if (!findkey(kv, "REMOTELOG_ADDR", hostname))\r
- {\r
- fprintf(stderr, "Cannot read REMOTELOG_ADDR\n");\r
- exit(ERR_SETTINGS);\r
- }\r
-\r
- if (strspn(hostname, VALID_FQDN) != strlen(hostname))\r
- {\r
- fprintf(stderr, "Bad REMOTELOG_ADDR: %s\n", hostname);\r
- exit(ERR_SETTINGS);\r
- }\r
-\r
- freekeyvalues(kv);\r
-\r
-\r
- /* If anyone other than root can write to /etc this would be totally\r
- * insecure - same if anyone other than root owns /etc, as they could\r
- * change the file mode to give themselves or anyone else write access. */\r
- if(lstat("/etc",&st))\r
- {\r
- perror("Unable to stat /etc");\r
- exit(ERR_ETC);\r
- }\r
- if(!S_ISDIR(st.st_mode))\r
- {\r
- fprintf(stderr,"/etc is not a directory?!\n");\r
- exit(ERR_ETC);\r
- }\r
- if ( st.st_uid != 0 || st.st_mode & S_IWOTH ||\r
- ((st.st_gid != 0) && (st.st_mode & S_IWGRP)) )\r
- {\r
- fprintf(stderr,"/etc is owned/writable by non-root users\n");\r
- exit(ERR_ETC);\r
- }\r
-\r
- /* O_CREAT with O_EXCL will make open() fail if the file already exists -\r
- * mostly to prevent 2 copies running at once */\r
- if ((config_fd = open( "/etc/syslog.conf.new", O_WRONLY|O_CREAT|O_EXCL, 0644 )) == -1 )\r
- {\r
- perror("Unable to open new config file");\r
- exit(ERR_CONFIG);\r
- }\r
-\r
- if (!strcmp(buffer,"on"))\r
- snprintf(buffer, STRING_SIZE - 1, "/bin/sed -e 's/^#\\?\\(\\*\\.\\*[[:blank:]]\\+@\\).\\+$/\\1%s/' /etc/syslog.conf >&%d", hostname, config_fd );\r
- else\r
- snprintf(buffer, STRING_SIZE - 1, "/bin/sed -e 's/^#\\?\\(\\*\\.\\*[[:blank:]]\\+@.\\+\\)$/#\\1/' /etc/syslog.conf >&%d", config_fd );\r
-\r
- /* if the return code isn't 0 failsafe */\r
- if ((rc = unpriv_system(buffer,99,99)) != 0)\r
- {\r
- fprintf(stderr, "sed returned bad exit code: %d\n", rc);\r
- close(config_fd);\r
- unlink("/etc/syslog.conf.new");\r
- exit(ERR_CONFIG);\r
- }\r
- close(config_fd);\r
- if (rename("/etc/syslog.conf.new","/etc/syslog.conf") == -1)\r
- {\r
- perror("Unable to replace old config file");\r
- unlink("/etc/syslog.conf.new");\r
- exit(ERR_CONFIG);\r
- }\r
-\r
-\r
- /* Get syslogd to read the new config file */\r
- if ((fd = open("/var/run/syslogd.pid", O_RDONLY)) == -1)\r
- {\r
- if(errno == ENOENT)\r
- {\r
- /* pid file doesn't exists.. restart syslog */\r
- if((rc = safe_system("/usr/sbin/syslogd -m 0")) == 0 )\r
- return 0;\r
- else\r
- {\r
- fprintf(stderr,\r
- "Unable to restart syslogd - returned exit code %d\n", rc);\r
- exit(ERR_SYSLOG);\r
- }\r
- } else {\r
- /* Something odd is going on, failsafe */\r
- perror("Unable to open pid file");\r
- exit(ERR_SYSLOG);\r
- }\r
- }\r
-\r
- memset(buffer, 0, STRING_SIZE);\r
- if (read(fd, buffer, STRING_SIZE - 1) == -1)\r
- {\r
- close(fd);\r
- perror("Couldn't read from pid file");\r
- exit(ERR_SYSLOG);\r
- }\r
- close(fd);\r
- /* strtol does sanity checks that atoi doesn't do */\r
- errno = 0;\r
- pid = (int)strtol(buffer, (char **)NULL, 10);\r
- if (errno || pid <= 1)\r
- {\r
- fprintf(stderr, "Bad pid value\n");\r
- exit(ERR_SYSLOG);\r
- }\r
- if (kill(pid, SIGHUP) == -1)\r
- {\r
- fprintf(stderr, "Unable to send SIGHUP\n");\r
- exit(ERR_SYSLOG);\r
- }\r
-\r
- return 0;\r
-}\r