summaryrefslogtreecommitdiffstats
path: root/main/sysklogd/sysklogd-1.4.2-caen-owl-klogd-drop-root.diff
blob: 40b8817d4e28706f625821c8c803325b5660990f (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
http://cvsweb.openwall.com/cgi/cvsweb.cgi/~checkout~/Owl/packages/sysklogd/sysklogd-1.4.2-caen-owl-klogd-drop-root.diff?rev=1.2;content-type=text%2Fplain
diff -upk.orig sysklogd-1.4.2.orig/klogd.8 sysklogd-1.4.2/klogd.8
--- sysklogd-1.4.2.orig/klogd.8	2005-03-11 16:12:09 +0000
+++ sysklogd-1.4.2/klogd.8	2005-08-18 14:37:47 +0000
@@ -18,6 +19,12 @@ klogd \- Kernel Log Daemon
 .RB [ " \-f "
 .I fname
 ]
+.RB [ " \-u "
+.I username
+]
+.RB [ " \-j "
+.I chroot_dir
+]
 .RB [ " \-iI " ]
 .RB [ " \-n " ]
 .RB [ " \-o " ]
@@ -53,6 +60,20 @@ stderr.
 .BI "\-f " file
 Log messages to the specified filename rather than to the syslog facility.
 .TP
+.BI "\-u " username
+Tells klogd to become the specified user and drop root privileges before
+starting logging.
+.TP
+.BI "\-j " chroot_dir
+Tells klogd to
+.BR chroot (2)
+into this directory after initializing.
+This option is only valid if the \-u option is also used to run klogd
+without root privileges.
+Note that the use of this option will prevent \-i and \-I from working
+unless you set up the chroot directory in such a way that klogd can still
+read the kernel module symbols.
+.TP
 .BI "\-i \-I"
 Signal the currently executing klogd daemon.  Both of these switches control
 the loading/reloading of symbol information.  The \-i switch signals the
diff -upk.orig sysklogd-1.4.2.orig/klogd.c sysklogd-1.4.2/klogd.c
--- sysklogd-1.4.2.orig/klogd.c	2005-08-18 12:29:52 +0000
+++ sysklogd-1.4.2/klogd.c	2005-08-18 14:37:47 +0000
@@ -261,6 +261,8 @@
 #include <stdarg.h>
 #include <paths.h>
 #include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
 #include "klogd.h"
 #include "ksyms.h"
 #ifndef TESTING
@@ -315,6 +317,9 @@ static enum LOGSRC {none, proc, kernel} 
 int debugging = 0;
 int symbols_twice = 0;
 
+char *server_user = NULL;
+char *chroot_dir = NULL;
+int log_flags = 0;
 
 /* Function prototypes. */
 extern int ksyslog(int type, char *buf, int len);
@@ -535,8 +540,9 @@ static enum LOGSRC GetKernelLogSrc(void)
 	 * First do a stat to determine whether or not the proc based
 	 * file system is available to get kernel messages from.
 	 */
-	if ( use_syscall ||
-	    ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) )
+	if (!server_user &&
+	    (use_syscall ||
+	    ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT))))
 	{
 	  	/* Initialize kernel logging. */
 	  	ksyslog(1, NULL, 0);
@@ -983,6 +989,27 @@ static void LogProcLine(void)
 }
 
 
+static int drop_root(void)
+{
+	struct passwd *pw;
+
+	if (!(pw = getpwnam(server_user))) return -1;
+
+	if (!pw->pw_uid) return -1;
+
+	if (chroot_dir) {
+		if (chdir(chroot_dir)) return -1;
+		if (chroot(".")) return -1;
+	}
+
+	if (setgroups(0, NULL)) return -1;
+	if (setgid(pw->pw_gid)) return -1;
+	if (setuid(pw->pw_uid)) return -1;
+
+	return 0;
+}
+
+
 int main(argc, argv)
 
 	int argc;
@@ -1000,7 +1027,7 @@ int main(argc, argv)
 	chdir ("/");
 #endif
 	/* Parse the command-line. */
-	while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2")) != EOF)
+	while ((ch = getopt(argc, argv, "c:df:u:j:iIk:nopsvx2")) != EOF)
 		switch((char)ch)
 		{
 		    case '2':		/* Print lines with symbols twice. */
@@ -1022,6 +1049,10 @@ int main(argc, argv)
 		    case 'I':
 			SignalDaemon(SIGUSR2);
 			return(0);
+		    case 'j':		/* chroot 'j'ail */
+			chroot_dir = optarg;
+			log_flags |= LOG_NDELAY;
+			break;
 		    case 'k':		/* Kernel symbol file. */
 			symfile = optarg;
 			break;
@@ -1037,6 +1068,9 @@ int main(argc, argv)
 		    case 's':		/* Use syscall interface. */
 			use_syscall = 1;
 			break;
+		    case 'u':		/* Run as this user */
+			server_user = optarg;
+			break;
 		    case 'v':
 			printf("klogd %s.%s\n", VERSION, PATCHLEVEL);
 			exit (1);
@@ -1045,6 +1079,10 @@ int main(argc, argv)
 			break;
 		}
 
+	if (chroot_dir && !server_user) {
+		fputs("'-j' is only valid with '-u'\n", stderr);
+		exit(1);
+	}
 
 	/* Set console logging level. */
 	if ( log_level != (char *) 0 )
@@ -1158,7 +1196,7 @@ int main(argc, argv)
 		}
 	}
 	else
-		openlog("kernel", 0, LOG_KERN);
+		openlog("kernel", log_flags, LOG_KERN);
 
 
 	/* Handle one-shot logging. */
@@ -1191,6 +1229,11 @@ int main(argc, argv)
 		}
 	}
 
+	if (server_user && drop_root()) {
+		syslog(LOG_ALERT, "klogd: failed to drop root");
+		Terminate();
+	}
+
         /* The main loop. */
 	while (1)
 	{