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