summaryrefslogtreecommitdiff
blob: 8c3f571f3ca2d017ce21543c36079c67c015b3c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
http://cvsweb.openwall.com/cgi/cvsweb.cgi/~checkout~/Owl/packages/sysklogd/sysklogd-1.4.2-caen-owl-syslogd-drop-root.diff?rev=1.1;content-type=text%2Fplain
diff -upk.orig sysklogd-1.4.2.orig/sysklogd.8 sysklogd-1.4.2/sysklogd.8
--- sysklogd-1.4.2.orig/sysklogd.8	2005-08-18 14:40:25 +0000
+++ sysklogd-1.4.2/sysklogd.8	2005-08-18 14:41:26 +0000
@@ -32,6 +32,9 @@ sysklogd \- Linux system logging utiliti
 .RB [ " \-s "
 .I domainlist
 ]
+.RB [ " \-u"
+.IB username
+]
 .RB [ " \-v " ]
 .LP
 .SH DESCRIPTION
@@ -161,6 +164,19 @@ is specified and the host logging resolv
 no domain would be cut, you will have to specify two domains like:
 .BR "\-s north.de:infodrom.north.de" .
 .TP
+.BI "\-u " "username"
+This causes the
+.B syslogd
+daemon to become the named user before starting up logging.
+
+Note that when this option is in use,
+.B syslogd
+will open all log files as root when the daemon is first started;
+however, after a
+.B SIGHUP
+the files will be reopened as the non-privileged user.  You should
+take this into account when deciding the ownership of the log files.
+.TP
 .B "\-v"
 Print version and exit.
 .LP
diff -upk.orig sysklogd-1.4.2.orig/syslogd.c sysklogd-1.4.2/syslogd.c
--- sysklogd-1.4.2.orig/syslogd.c	2005-08-18 14:40:25 +0000
+++ sysklogd-1.4.2/syslogd.c	2005-08-18 14:41:26 +0000
@@ -524,6 +524,10 @@ static char sccsid[] = "@(#)syslogd.c	5.
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 #include <resolv.h>
+
+#include <pwd.h>
+#include <grp.h>
+
 #ifndef TESTING
 #include "pidfile.h"
 #endif
@@ -775,6 +779,7 @@ int	NoHops = 1;		/* Can we bounce syslog
 				   intermediate host. */
 
 char	*bind_addr = NULL;	/* bind UDP port to this interface only */
+char	*server_user = NULL;	/* user name to run server as */
 
 extern	int errno;
 
@@ -827,6 +832,21 @@ static int set_nonblock_flag(int desc)
 	return fcntl(desc, F_SETFL, flags | O_NONBLOCK);
 }
 
+static int drop_root(void)
+{
+	struct passwd *pw;
+
+	if (!(pw = getpwnam(server_user))) return -1;
+
+	if (!pw->pw_uid) return -1;
+
+	if (initgroups(server_user, pw->pw_gid)) return -1;
+	if (setgid(pw->pw_gid)) return -1;
+	if (setuid(pw->pw_uid)) return -1;
+
+	return 0;
+}
+
 int main(argc, argv)
 	int argc;
 	char **argv;
@@ -880,7 +900,7 @@ int main(argc, argv)
 		funix[i]  = -1;
 	}
 
-	while ((ch = getopt(argc, argv, "a:dhf:i:l:m:np:rs:v")) != EOF)
+	while ((ch = getopt(argc, argv, "a:dhf:i:l:m:np:rs:u:v")) != EOF)
 		switch((char)ch) {
 		case 'a':
 			if (nfunix < MAXFUNIX)
@@ -933,6 +953,9 @@ int main(argc, argv)
 			}
 			StripDomains = crunch_list(optarg);
 			break;
+		case 'u':
+			server_user = optarg;
+			break;
 		case 'v':
 			printf("syslogd %s.%s\n", VERSION, PATCHLEVEL);
 			exit (0);
@@ -1100,6 +1123,11 @@ int main(argc, argv)
 		kill (ppid, SIGTERM);
 #endif
 
+	if (server_user && drop_root()) {
+		dprintf("syslogd: failed to drop root\n");
+		exit(1);
+	}
+
 	/* Main loop begins here. */
 	for (;;) {
 		int nfds;
@@ -1254,7 +1282,7 @@ int main(argc, argv)
 int usage()
 {
 	fprintf(stderr, "usage: syslogd [-drvh] [-l hostlist] [-m markinterval] [-n] [-p path]\n" \
-		" [-s domainlist] [-f conffile] [-i IP address]\n");
+		" [-s domainlist] [-f conffile] [-i IP address] [-u username]\n");
 	exit(1);
 }