]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/misc-progs/logwatch.c
tor: added daemon stats and little changes on styling
[people/teissler/ipfire-2.x.git] / src / misc-progs / logwatch.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: logwatch.c,v 1.2 2003/12/11 11:25:54 riddles Exp $
9 *
10 */
11
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <grp.h>
17 #include <pwd.h>
18 #include <sys/types.h>
19 #include "libsmooth.h"
20 #include "setuid.h"
21
22 /* Lots of distros just run logwatch as root from cron, but logwatch doesn't
23 * need any root privs, just the ability to access it's filter scripts
24 * (/etc/log.d/) and the log files (under /var/log/). By creating a logwatch
25 * user and group and ensuring it has read access to the logs we can run
26 * logwatch unprivileged. Apart from the principle of least privilege running
27 * logwatch as root turns out to be doubly a bad idea because a flaw in the way
28 * it works:
29 *
30 * http://www.securityfocus.com/archive/1/327833/2003-07-01/2003-07-07/0
31 *
32 * This wrapper program should be run as root, but not installed setuid root,
33 * it's basic aim is to allow a root cron job to safely run logcheck; as such
34 * it will drop privileges, becoming the locheck user & group then run
35 * logcheck. In many ways this is much the same as getting cron to run
36 * su -s /etc/log.d/scripts/logwatch.pl
37 * the wrapper however is able to read configuration info from /var/ipcop and
38 * pass the correct args to logwatch
39 */
40
41 int main(void)
42 {
43 char buffer[STRING_SIZE];
44 struct keyvalue *kv = NULL;
45 struct passwd *pw;
46 gid_t groups[2];
47 char * argv[4];
48
49 if(getuid())
50 {
51 fprintf(stderr, "logwatch should be ran by root\n");
52 exit(1);
53 }
54
55 /* Read in and verify config */
56 kv=initkeyvalues();
57
58 if (!readkeyvalues(kv, CONFIG_ROOT "/logging/settings"))
59 {
60 fprintf(stderr, "Cannot read syslog settings\n");
61 exit(1);
62 }
63
64 if (!findkey(kv, "LOGWATCH_LEVEL", buffer))
65 {
66 fprintf(stderr, "Cannot read LOGWATCH_LEVEL\n");
67 exit(1);
68 }
69
70 if (strcmp(buffer,"Low") && strcmp(buffer,"Med") && strcmp(buffer,"High"))
71 {
72 fprintf(stderr, "Bad LOGWATCH_LEVEL: %s\n", buffer);
73 exit(1);
74 }
75
76 freekeyvalues(kv);
77
78
79 /* lookup logwatch user */
80 if(!(pw = getpwnam("logwatch")))
81 {
82 fprintf(stderr,"Couldn't find logwatch user.\n");
83 exit(1);
84 }
85 /* paranoia... */
86 memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
87 endpwent();
88
89 /* more paranoia */
90 if(!pw->pw_uid || !pw->pw_gid)
91 {
92 fprintf(stderr,"logwatch user appears to be UID or GID 0, aborting.\n");
93 exit(1);
94 }
95
96 /* drop privs */
97 groups[0] = groups[1] = pw->pw_gid;
98 if (setgroups(1,groups)) { perror("Couldn't clear group list"); exit(1); }
99 if (setgid(pw->pw_gid)) { perror("Couldn't setgid(logwatch)"); exit(1); }
100 if (setuid(pw->pw_uid)) { perror("Couldn't setuid(logwatch)"); exit(1); }
101
102 /* ok, spawn logwatch */
103 argv[0] = "logwatch.pl";
104 argv[1] = "--detail";
105 argv[2] = buffer;
106 argv[3] = NULL;
107 execve("/usr/share/logwatch/scripts/logwatch.pl", argv, trusted_env);
108
109 /* shouldn't get here - execve replaces current running process */
110 perror("logwatch: execve failed");
111 exit(1);
112 }