Inline below is a simple patch that drops the root capabilities that aren't needed (inspired by a similar patch against the mpm_itk project!). Possibly it is a little too restrictive, extras can be added to suidcaps, but on platforms that support capabilities this will prevent things such as kernel module loading. Needed on linux is libcap, available in most distros. Note that this patch doesn't require libcap, or add an option, but if it is installed then it will take advantage of it. I don't have any other platforms to test on. The patch compiles fine but I haven't managed to test it yet. My autoconf experience is zero, so I hope that HAVE_LIBCAP is actually getting defined. Comments appreciated, I'll test it thoroughly later when I get some free time (and, if it works, remove the test message!). David --- configure.in 2007-02-22 21:50:07.000000000 +0000 +++ configure.in 2007-02-23 17:52:16.000000000 +0000 @@ -382,6 +382,17 @@ ]) ]) +AC_CHECK_FUNC(cap_init, [], [ + AC_CHECK_LIB(cap, cap_init, [ + have_libcap=yes + LIBS="$LIBS -lcap" + ]) +]) + +if test "$have_libcap" = "yes"; then + AC_DEFINE(HAVE_LIBCAP,, libcap is installed for cap_init()) +fi + AC_CHECK_FUNC(fdatasync, [ have_fdatasync=yes ], [ --- src/master/main.c 2007-01-27 01:44:25.000000000 +0000 +++ src/master/main.c 2007-02-23 16:13:39.000000000 +0000 @@ -24,6 +24,9 @@ #include <syslog.h> #include <sys/stat.h> #include <sys/wait.h> +#ifdef HAVE_LIBCAP +#include <sys/capability.h> +#endif const char *process_names[PROCESS_TYPE_MAX] = { "unknown", @@ -36,6 +39,15 @@ "dict" }; +/* the capabilities that we *need* in order to operate */ +#ifdef HAVE_LIBCAP +cap_t caps; +cap_value_t suidcaps[] = { + CAP_SETUID, + CAP_NET_BIND_SERVICE +}; +#endif + static const char *configfile = SYSCONFDIR "/" PACKAGE ".conf"; static const char *env_tz; @@ -583,6 +595,18 @@ if (log_error) i_fatal("This is Dovecot's error log"); + i_info("test message, monkeys"); + /* drop capabilities that we don't need, be very restrictive */ +#ifdef HAVE_LIBCAP + i_info("Found capability support, dropping unnecessary root priviledges"); + caps = cap_init(); + cap_clear(caps); + cap_set_flag(caps, CAP_PERMITTED, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); + cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); + cap_set_proc(caps); + cap_free(caps); +#endif + lib_signals_init(); lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);