]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/misc-progs/restartsyslogd.c
Diverse Fixes.
[people/pmueller/ipfire-2.x.git] / src / misc-progs / restartsyslogd.c
CommitLineData
cd1a2927
MT
1/* This file is part of the IPCop Firewall.\r
2 *\r
3 * This program is distributed under the terms of the GNU General Public\r
4 * Licence. See the file COPYING for details.\r
5 *\r
6 * Copyright (C) 2003-07-12 Robert Kerr <rkerr@go.to>\r
7 *\r
8 * $Id: restartsyslogd.c,v 1.2.2.3 2004/12/14 17:56:37 gespinasse Exp $\r
9 *\r
10 */\r
11\r
12#include <stdio.h>\r
13#include <stdlib.h>\r
14#include <unistd.h>\r
15#include <string.h>\r
16#include <sys/stat.h>\r
17#include <sys/types.h>\r
18#include <fcntl.h>\r
19#include <signal.h>\r
20#include <errno.h>\r
21#include "libsmooth.h"\r
22#include "setuid.h"\r
23\r
24#define ERR_ANY 1\r
25#define ERR_SETTINGS 2 /* error in settings file */\r
26#define ERR_ETC 3 /* error with /etc permissions */\r
27#define ERR_CONFIG 4 /* error updated sshd_config */\r
28#define ERR_SYSLOG 5 /* error restarting syslogd */\r
29\r
30int main(void)\r
31{\r
32 char buffer[STRING_SIZE], hostname[STRING_SIZE];\r
33 int config_fd,rc,fd,pid;\r
34 struct stat st;\r
35 struct keyvalue *kv = NULL;\r
36 memset(buffer, 0, STRING_SIZE);\r
37 memset(hostname, 0, STRING_SIZE);\r
38\r
39 if (!(initsetuid()))\r
40 exit(1);\r
41\r
42\r
43 /* Read in and verify config */\r
44 kv=initkeyvalues();\r
45\r
46 if (!readkeyvalues(kv, CONFIG_ROOT "/logging/settings"))\r
47 {\r
48 fprintf(stderr, "Cannot read syslog settings\n");\r
49 exit(ERR_SETTINGS);\r
50 }\r
51\r
52 if (!findkey(kv, "ENABLE_REMOTELOG", buffer))\r
53 {\r
54 fprintf(stderr, "Cannot read ENABLE_REMOTELOG\n");\r
55 exit(ERR_SETTINGS);\r
56 }\r
57\r
58 if (!findkey(kv, "REMOTELOG_ADDR", hostname))\r
59 {\r
60 fprintf(stderr, "Cannot read REMOTELOG_ADDR\n");\r
61 exit(ERR_SETTINGS);\r
62 }\r
63\r
64 if (strspn(hostname, VALID_FQDN) != strlen(hostname))\r
65 {\r
66 fprintf(stderr, "Bad REMOTELOG_ADDR: %s\n", hostname);\r
67 exit(ERR_SETTINGS);\r
68 }\r
69\r
70 freekeyvalues(kv);\r
71\r
72\r
73 /* If anyone other than root can write to /etc this would be totally\r
74 * insecure - same if anyone other than root owns /etc, as they could\r
75 * change the file mode to give themselves or anyone else write access. */\r
76 if(lstat("/etc",&st))\r
77 {\r
78 perror("Unable to stat /etc");\r
79 exit(ERR_ETC);\r
80 }\r
81 if(!S_ISDIR(st.st_mode))\r
82 {\r
83 fprintf(stderr,"/etc is not a directory?!\n");\r
84 exit(ERR_ETC);\r
85 }\r
86 if ( st.st_uid != 0 || st.st_mode & S_IWOTH ||\r
87 ((st.st_gid != 0) && (st.st_mode & S_IWGRP)) )\r
88 {\r
89 fprintf(stderr,"/etc is owned/writable by non-root users\n");\r
90 exit(ERR_ETC);\r
91 }\r
92\r
93 /* O_CREAT with O_EXCL will make open() fail if the file already exists -\r
94 * mostly to prevent 2 copies running at once */\r
95 if ((config_fd = open( "/etc/syslog.conf.new", O_WRONLY|O_CREAT|O_EXCL, 0644 )) == -1 )\r
96 {\r
97 perror("Unable to open new config file");\r
98 exit(ERR_CONFIG);\r
99 }\r
100\r
101 if (!strcmp(buffer,"on"))\r
102 snprintf(buffer, STRING_SIZE - 1, "/bin/sed -e 's/^#\\?\\(\\*\\.\\*[[:blank:]]\\+@\\).\\+$/\\1%s/' /etc/syslog.conf >&%d", hostname, config_fd );\r
103 else\r
104 snprintf(buffer, STRING_SIZE - 1, "/bin/sed -e 's/^#\\?\\(\\*\\.\\*[[:blank:]]\\+@.\\+\\)$/#\\1/' /etc/syslog.conf >&%d", config_fd );\r
105\r
106 /* if the return code isn't 0 failsafe */\r
107 if ((rc = unpriv_system(buffer,99,99)) != 0)\r
108 {\r
109 fprintf(stderr, "sed returned bad exit code: %d\n", rc);\r
110 close(config_fd);\r
111 unlink("/etc/syslog.conf.new");\r
112 exit(ERR_CONFIG);\r
113 }\r
114 close(config_fd);\r
115 if (rename("/etc/syslog.conf.new","/etc/syslog.conf") == -1)\r
116 {\r
117 perror("Unable to replace old config file");\r
118 unlink("/etc/syslog.conf.new");\r
119 exit(ERR_CONFIG);\r
120 }\r
121\r
122\r
123 /* Get syslogd to read the new config file */\r
124 if ((fd = open("/var/run/syslogd.pid", O_RDONLY)) == -1)\r
125 {\r
126 if(errno == ENOENT)\r
127 {\r
128 /* pid file doesn't exists.. restart syslog */\r
129 if((rc = safe_system("/usr/sbin/syslogd -m 0")) == 0 )\r
130 return 0;\r
131 else\r
132 {\r
133 fprintf(stderr,\r
134 "Unable to restart syslogd - returned exit code %d\n", rc);\r
135 exit(ERR_SYSLOG);\r
136 }\r
137 } else {\r
138 /* Something odd is going on, failsafe */\r
139 perror("Unable to open pid file");\r
140 exit(ERR_SYSLOG);\r
141 }\r
142 }\r
143\r
144 memset(buffer, 0, STRING_SIZE);\r
145 if (read(fd, buffer, STRING_SIZE - 1) == -1)\r
146 {\r
147 close(fd);\r
148 perror("Couldn't read from pid file");\r
149 exit(ERR_SYSLOG);\r
150 }\r
151 close(fd);\r
152 /* strtol does sanity checks that atoi doesn't do */\r
153 errno = 0;\r
154 pid = (int)strtol(buffer, (char **)NULL, 10);\r
155 if (errno || pid <= 1)\r
156 {\r
157 fprintf(stderr, "Bad pid value\n");\r
158 exit(ERR_SYSLOG);\r
159 }\r
160 if (kill(pid, SIGHUP) == -1)\r
161 {\r
162 fprintf(stderr, "Unable to send SIGHUP\n");\r
163 exit(ERR_SYSLOG);\r
164 }\r
165\r
166 return 0;\r
167}\r