1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 #include <pwd.h>
5 #include <grp.h>
6 #include <stdio.h>
7 #include "error.h"
8 #include "strerr.h"
9 #include "open.h"
10 #include "buffer.h"
11
12 #if defined(__sun__) && defined(__sparc__) && defined(__unix__) && defined(__svr4__)
13 #define SOLARIS
14 #include <sys/utsname.h>
15 #include "scan.h"
16 #endif
17
18 #ifndef SOLARIS
19 #include <paths.h>
20 #endif
21 #ifndef _PATH_KLOG
22 #define _PATH_KLOG "/dev/klog"
23 #endif
24
25 #define USAGE1 " unix|inet|klog|ucspi acct logacct [/etc/sv] [/logdir]"
26 #define USAGE2 " notify acct grp [/etc/sv] [pipe]"
27
28 #define VERSION "$Id: socklog-conf.c,v 1.14 2006/03/06 12:56:34 pape Exp $"
29 #define WARNING "socklog-conf: warning: "
30 #define FATAL "socklog-conf: fatal: "
31
32 #define CONF_DIR "/etc/sv"
33 #define LOG_DIR_UNIX "/var/log/socklog"
34 #define LOG_DIR_INET "/var/log/socklog-inet"
35 #define LOG_DIR_UCSPI_TCP "/var/log/socklog-ucspi-tcp"
36 #define LOG_DIR_KLOG "/var/log/socklog-klog"
37 #define PATH_NOTIFY "/var/log/socklog/.notify"
38
39 #define CONF_UNIX 0
40 #define CONF_INET 1
41 #define CONF_UCSPI_TCP 2
42 #define CONF_NOTIFY 3
43 #define CONF_KLOG 4
44
45 const char *progname;
46
usage()47 void usage() {
48 strerr_warn3("usage: ", progname, USAGE1, 0);
49 strerr_die4x(1, "usage: ", progname, USAGE2, "\n");
50 }
51
52 const char *dir;
53 const char *fn;
54 char buf[1024];
55 int fd;
56 buffer b;
57
58 char *user;
59 char *loguser;
60 const char *path;
61
62 struct passwd *upw, *pw;
63 struct group *gr;
64
fail()65 void fail() {
66 if (fn[0] == '/')
67 strerr_die4sys(111, FATAL, "unable to create ", fn, ": ");
68 else
69 strerr_die6sys(111, FATAL, "unable to create ", dir, "/", fn, ": ");
70 }
71
start(const char * s)72 void start(const char *s) {
73 fn = s;
74 fd = open_trunc(fn);
75 if (fd == -1) fail();
76 buffer_init(&b, write, fd, buf, sizeof buf);
77 }
78
outs(const char * s)79 void outs(const char *s) {
80 if (buffer_puts(&b, s) == -1) fail();
81 }
82
finish(void)83 void finish(void) {
84 if (buffer_flush(&b) == -1) fail();
85 if (fsync(fd) == -1) fail();
86 close(fd);
87 }
88
perm(int mode)89 void perm(int mode) { if (chmod(fn, mode) == -1) fail(); }
90
mkfile(const char * f,const char * s)91 void mkfile(const char *f, const char *s) {
92 start(f);
93 outs(s); outs("\n");
94 finish();
95 }
96
makedir(const char * s)97 void makedir(const char *s) {
98 fn =s;
99 if (mkdir(fn, 0750) == -1) fail();
100 }
makechdir(const char * s)101 void makechdir(const char *s) {
102 makedir(s);
103 if (chown(s, pw->pw_uid, pw->pw_gid) == -1)
104 strerr_die6sys(111, FATAL, "unable to set owner of ", dir, "/", s, ": ");
105 }
106
conf_unix()107 void conf_unix() {
108 #ifdef SOLARIS
109 #if WANT_SUN_DOOR
110 struct utsname u;
111 unsigned long sunos_version;
112 uname(&u);
113 scan_ulong(u.release+strlen(u.release)-1, &sunos_version);
114 #endif
115 #endif
116 makedir("socklog-unix");
117 perm(0750);
118 makedir("socklog-unix/log");
119 perm(0755);
120
121 makechdir(path);
122 if (symlink(path, "socklog-unix/log/main") == -1)
123 strerr_die4sys(111, FATAL, "unable to link ", path, ": ");
124 makechdir("socklog-unix/log/main/auth");
125 mkfile("socklog-unix/log/main/auth/config", "s999999\nn5\n-*\n+auth.*\n+authpriv.*");
126 makechdir("socklog-unix/log/main/cron");
127 mkfile("socklog-unix/log/main/cron/config", "s999999\nn5\n-*\n+cron.*");
128 makechdir("socklog-unix/log/main/daemon");
129 mkfile("socklog-unix/log/main/daemon/config", "s999999\nn5\n-*\n+daemon.*");
130 makechdir("socklog-unix/log/main/debug");
131 mkfile("socklog-unix/log/main/debug/config", "s999999\nn5\n-*\n+*.debug*");
132 makechdir("socklog-unix/log/main/ftp");
133 mkfile("socklog-unix/log/main/ftp/config", "s999999\nn5\n-*\n+ftp.*");
134 makechdir("socklog-unix/log/main/kern");
135 mkfile("socklog-unix/log/main/kern/config", "s999999\nn5\n-*\n+kern.*");
136 makechdir("socklog-unix/log/main/local");
137 mkfile("socklog-unix/log/main/local/config", "s999999\nn5\n-*\n+local.*");
138 makechdir("socklog-unix/log/main/mail");
139 mkfile("socklog-unix/log/main/mail/config", "s999999\nn5\n-*\n+mail.*");
140 makechdir("socklog-unix/log/main/main");
141 mkfile("socklog-unix/log/main/main/config", "s999999\nn10");
142 makechdir("socklog-unix/log/main/news");
143 mkfile("socklog-unix/log/main/news/config", "s999999\nn5\n-*\n+news.*");
144 makechdir("socklog-unix/log/main/syslog");
145 mkfile("socklog-unix/log/main/syslog/config", "s999999\nn5\n-*\n+syslog.*");
146 makechdir("socklog-unix/log/main/user");
147 mkfile("socklog-unix/log/main/user/config", "s999999\nn5\n-*\n+user.*");
148
149 start("socklog-unix/run");
150 outs("#!/bin/sh\n");
151 outs("exec 2>&1\n");
152 #ifndef SOLARIS
153 outs("exec chpst -U"); outs(user); outs(" socklog unix /dev/log\n");
154 #else
155 outs("exec chpst -U"); outs(user); outs(" socklog sun_stream /dev/log");
156 #if WANT_SUN_DOOR
157 if (sunos_version == 7) outs(" /etc/.syslog_door");
158 if (sunos_version >= 8) outs(" /var/run/syslog_door");
159 #endif
160 outs("\n");
161 #endif
162 finish();
163 perm(0750);
164
165 start("socklog-unix/check");
166 outs("#!/bin/sh\n");
167 outs("exec 2>/dev/null\n");
168 outs("exec socklog-check unix /dev/log\n");
169 finish();
170 perm(0755);
171
172 start("socklog-unix/log/run");
173 outs("#!/bin/sh\n");
174 outs("exec chpst -u");
175 outs(loguser);
176 outs(" svlogd \\\n");
177 outs(" main/main main/auth main/cron main/daemon main/debug main/ftp \\\n");
178 outs(" main/kern main/local main/mail main/news main/syslog main/user\n");
179 finish();
180 perm(0750);
181 }
182
conf_inet()183 void conf_inet() {
184 makedir("socklog-inet");
185 perm(0750);
186 makedir("socklog-inet/log");
187 perm(0755);
188
189 makechdir(path);
190 if (symlink(path, "socklog-inet/log/main") == -1)
191 strerr_die4sys(111, FATAL, "unable to link ", path, ": ");
192 makechdir("socklog-inet/log/main/main");
193 mkfile("socklog-inet/log/main/main/config", "s999999\nn10");
194
195 start("socklog-inet/run");
196 outs("#!/bin/sh\n");
197 outs("exec 2>&1\n");
198 outs("exec chpst -U"); outs(user); outs(" socklog inet 0 514\n");
199 finish();
200 perm(0750);
201
202 start("socklog-inet/log/run");
203 outs("#!/bin/sh\n");
204 outs("exec chpst -u");
205 outs(loguser);
206 outs(" svlogd -t main/main\n");
207 finish();
208 perm(0750);
209 }
210
conf_ucspi_tcp()211 void conf_ucspi_tcp() {
212 makedir("socklog-ucspi-tcp");
213 perm(0750);
214 makedir("socklog-ucspi-tcp/log");
215 perm(0755);
216
217 makechdir(path);
218 if (symlink(path, "socklog-ucspi-tcp/log/main") == -1)
219 strerr_die4sys(111, FATAL, "unable to link ", path, ": ");
220 makechdir("socklog-ucspi-tcp/log/main/main");
221 mkfile("socklog-ucspi-tcp/log/main/main/config", "s999999\nn10");
222
223 start("socklog-ucspi-tcp/run");
224 outs("#!/bin/sh\n");
225 outs("PORT=10116\n");
226 outs("exec 2>&1\n");
227 outs("exec tcpsvd -vllogserver -u");
228 outs(user);
229 outs(" 0 \"$PORT\" socklog ucspi TCPREMOTEIP\n");
230 finish();
231 perm(0750);
232
233 start("socklog-ucspi-tcp/log/run");
234 outs("#!/bin/sh\n");
235 outs("exec chpst -u");
236 outs(loguser);
237 outs(" svlogd -t main/main\n");
238 finish();
239 perm(0750);
240 }
241
conf_klog()242 void conf_klog() {
243 makedir("socklog-klog");
244 perm(0750);
245 makedir("socklog-klog/log");
246 perm(0755);
247
248 makechdir(path);
249 if (symlink(path, "socklog-klog/log/main") == -1)
250 strerr_die4sys(111, FATAL, "unable to link ", path, ": ");
251 makechdir("socklog-klog/log/main/main");
252 mkfile("socklog-klog/log/main/main/config", "s999999\nn10");
253
254 start("socklog-klog/run");
255 outs("#!/bin/sh\n");
256 outs("exec <"); outs(_PATH_KLOG); outs("\n");
257 outs("exec 2>&1\n");
258 outs("exec chpst -u");
259 outs(user);
260 outs(" socklog ucspi\n");
261 finish();
262 perm(0750);
263
264 start("socklog-klog/log/run");
265 outs("#!/bin/sh\n");
266 outs("exec chpst -u");
267 outs(loguser);
268 outs(" svlogd -t main/main\n");
269 finish();
270 perm(0750);
271 }
272
conf_notify()273 void conf_notify() {
274 makedir("socklog-notify");
275 perm(0755);
276
277 umask(007);
278 if (mkfifo(path, 0620) == -1)
279 strerr_die4sys(111, FATAL, "unable to create \"", path, "\": ");
280 umask(022);
281 if (chown(path, upw->pw_uid, gr->gr_gid) == -1)
282 strerr_die4sys(111, FATAL, "unable to set owner of ", path, ": ");
283
284 start("socklog-notify/run");
285 outs("#!/bin/sh -e\n");
286 outs("MAILTO=root\n");
287 outs("PIPE="); outs(path); outs("\n\n");
288 outs("if [ ! -p \"$PIPE\" ]; then mkfifo -m0620 \"$PIPE\"; chown ");
289 outs(user); outs(":"); outs(loguser);
290 outs(" \"$PIPE\"; fi\n");
291 outs("exec <> \"$PIPE\"\n");
292 outs("exec chpst -u");
293 outs(user);
294 outs(" uncat -s49999 -t180 \\\n");
295 outs(" env MAILUSER=log MAILNAME='socklog notify' \\\n");
296 outs(" mail -s socklog-notify $MAILTO\n");
297 finish();
298 perm(0750);
299 }
300
main(int argc,char ** argv)301 int main(int argc, char **argv) {
302 int mode =0;
303
304 progname =*argv++;
305 umask(022);
306
307 if (! *argv) usage();
308 switch (**argv) {
309 case 'u':
310 if (! *(++*argv)) usage();
311 switch (**argv) {
312 case 'n':
313 mode =CONF_UNIX;
314 break;
315 case 'c':
316 mode =CONF_UCSPI_TCP;
317 break;
318 default:
319 usage();
320 }
321 break;
322 case 'i':
323 mode =CONF_INET;
324 break;
325 case 'n':
326 mode =CONF_NOTIFY;
327 break;
328 case 'k':
329 mode =CONF_KLOG;
330 break;
331 case '-':
332 if ((*argv)[1] && (*argv)[1] == 'V') {
333 strerr_warn2(VERSION, "\n", 0);
334 }
335 default:
336 usage();
337 }
338 argv++;
339
340 user =*argv++;
341 if (!user) usage();
342 loguser =*argv++;
343 if (!loguser) usage();
344 dir =*argv++;
345 if (!dir) {
346 dir =CONF_DIR;
347 } else {
348 if (dir[0] != '/') usage();
349 if (*argv) {
350 path =*argv;
351 if (path[0] != '/') usage();
352 }
353 }
354
355 upw =getpwnam(user);
356 if (!upw) strerr_die3x(111, FATAL, "unknown account ", user);
357 if (mode != CONF_NOTIFY) {
358 pw =getpwnam(loguser);
359 if (!pw) strerr_die3x(111, FATAL, "unknown account ", loguser);
360 } else {
361 gr =getgrnam(loguser);
362 if (!gr) strerr_die3x(111, FATAL, "unknown group ", loguser);
363 }
364
365 if (chdir(dir) == -1) {
366 if (errno != error_noent)
367 strerr_die4sys(111, FATAL, "unable to switch to ", dir, ": ");
368
369 if (mkdir(dir, 0700) == -1)
370 strerr_die4sys(111, FATAL, "unable to create ", dir, ": ");
371 if (chmod(dir, 0750) == -1)
372 strerr_die4sys(111, FATAL, "unable to set mode of ", dir, ": ");
373 if (chdir(dir) == -1)
374 strerr_die4sys(111, FATAL, "unable to switch to ", dir, ": ");
375 }
376
377 switch(mode) {
378 case CONF_UNIX:
379 if (!path) path =LOG_DIR_UNIX;
380 conf_unix();
381 break;
382 case CONF_INET:
383 if (!path) path =LOG_DIR_INET;
384 conf_inet();
385 break;
386 case CONF_UCSPI_TCP:
387 if (!path) path =LOG_DIR_UCSPI_TCP;
388 conf_ucspi_tcp();
389 break;
390 case CONF_KLOG:
391 if (!path) path =LOG_DIR_KLOG;
392 conf_klog();
393 break;
394 case CONF_NOTIFY:
395 if (!path) path =PATH_NOTIFY;
396 conf_notify();
397 break;
398 }
399 return(0);
400 }
401