[Dovecot] Simple patch

David lists at edeca.net
Fri Feb 23 19:33:04 UTC 2007


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);


More information about the dovecot mailing list