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
|
diff --git a/lib/gprocess.h b/lib/gprocess.h
index cda35b0..5c449f7 100644
--- a/lib/gprocess.h
+++ b/lib/gprocess.h
@@ -28,9 +28,14 @@
#include "syslog-ng.h"
#include <sys/types.h>
+#include <sys/utsname.h>
#if ENABLE_LINUX_CAPS
# include <sys/capability.h>
+#
+# ifndef CAP_SYSLOG
+# define CAP_SYSLOG 34
+# endif
#endif
typedef enum
@@ -78,5 +83,8 @@ void g_process_finish(void);
void g_process_add_option_group(GOptionContext *ctx);
+extern int kernel_version;
+extern void get_kernel_version(void);
+#define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z)
#endif
diff --git a/modules/affile/affile.c b/modules/affile/affile.c
index e145324..886fa72 100644
--- a/modules/affile/affile.c
+++ b/modules/affile/affile.c
@@ -59,7 +59,12 @@ affile_open_file(gchar *name, gint flags,
if (privileged)
{
g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
- g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version < LINUX_VERSION(2, 6, 38))
+ g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
+ else
+ g_process_cap_modify(CAP_SYSLOG, TRUE);
}
else
{
diff --git a/syslog-ng/main.c b/syslog-ng/main.c
index 9880c1f..ee5031b 100644
--- a/syslog-ng/main.c
+++ b/syslog-ng/main.c
@@ -67,6 +67,7 @@ static gboolean syntax_only = FALSE;
static gboolean display_version = FALSE;
static gchar *ctlfilename = PATH_CONTROL_SOCKET;
static gchar *preprocess_into = NULL;
+int kernel_version;
static volatile sig_atomic_t sig_hup_received = FALSE;
static volatile sig_atomic_t sig_term_received = FALSE;
@@ -363,6 +364,20 @@ version(void)
ON_OFF_STR(ENABLE_PACCT_MODULE));
}
+void
+get_kernel_version(void) {
+ static struct utsname uts;
+ int x = 0, y = 0, z = 0;
+
+ if (uname(&uts) == -1) {
+ fprintf(stderr, "Unable to retrieve kernel version.\n");
+ exit(1);
+ }
+
+ sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
+ kernel_version = LINUX_VERSION(x, y, z);
+}
+
int
main(int argc, char *argv[])
{
@@ -379,9 +394,20 @@ main(int argc, char *argv[])
* indicate readability. Enabling/disabling cap_sys_admin on every poll
* invocation seems to be too expensive. So I enable it for now. */
- g_process_set_caps("cap_net_bind_service,cap_net_broadcast,cap_net_raw,"
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version < LINUX_VERSION(2, 6, 34))
+ g_process_set_caps("cap_net_bind_service,cap_net_broadcast,cap_net_raw,"
"cap_dac_read_search,cap_dac_override,cap_chown,cap_fowner=p "
"cap_sys_admin=ep");
+ else if (kernel_version < LINUX_VERSION(2, 6, 38))
+ g_process_set_caps("cap_net_bind_service,cap_net_broadcast,cap_net_raw,"
+ "cap_dac_read_search,cap_dac_override,cap_chown,cap_fowner,"
+ "cap_sys_admin=p");
+ else
+ g_process_set_caps("cap_net_bind_service,cap_net_broadcast,cap_net_raw,"
+ "cap_dac_read_search,cap_dac_override,cap_chown,cap_fowner,"
+ "cap_syslog=p");
ctx = g_option_context_new("syslog-ng");
g_process_add_option_group(ctx);
msg_add_option_group(ctx);
|