]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
RHEL-4: Import dbus-0.22-cap-audit-write.patch RHEL-4
authorColin Walters <walters@verbum.org>
Fri, 7 Jan 2011 18:36:01 +0000 (13:36 -0500)
committerColin Walters <walters@verbum.org>
Fri, 7 Jan 2011 18:36:01 +0000 (13:36 -0500)
bus/selinux.c
configure.in
dbus/dbus-sysdeps.c

index 673b2ca0954107c3cc6c3443b41db77eba6e9be0..06dae8812b3fe238af90b6bbd04d18dde5c4af05 100644 (file)
@@ -37,6 +37,9 @@
 #include <selinux/flask.h>
 #include <signal.h>
 #include <stdarg.h>
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif /* HAVE_LIBAUDIT */
 #endif /* HAVE_SELINUX */
 
 #define BUS_SID_FROM_SELINUX(sid)  ((BusSELinuxID*) (sid))
@@ -98,12 +101,40 @@ static const struct avc_lock_callback lock_cb =
  * @param variable argument list
  */
 #ifdef HAVE_SELINUX
+#ifdef HAVE_LIBAUDIT
+static int audit_fd = -1;
+static void audit_init(void)
+{
+  audit_fd = audit_open();
+  if (audit_fd < 0) {
+    /* If kernel doesn't support audit, bail out */
+    if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
+      return;
+    /* If user bus, bail out */
+    if (errno == EPERM && getuid() != 0)
+      return;
+    _dbus_warn ("Failed opening connection to the audit subsystem");
+  }
+}
+#endif /* HAVE_LIBAUDIT */
+
 static void 
 log_callback (const char *fmt, ...) 
 {
   va_list ap;
   va_start(ap, fmt);
+#ifdef HAVE_LIBAUDIT
+  {
+     char buf[PATH_MAX*2];
+
+       /* FIXME: need to change this to show real user */
+     vsnprintf(buf, sizeof(buf), fmt, ap);
+     audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
+                                NULL, getuid());
+  }
+#else
   vsyslog (LOG_INFO, fmt, ap);
+#endif /* HAVE_LIBAUDIT */
   va_end(ap);
 }
 
@@ -294,6 +325,10 @@ bus_selinux_full_init (void)
 
   freecon (bus_context);
   
+#ifdef HAVE_LIBAUDIT
+  audit_init ();
+#endif /* HAVE_LIBAUDIT */
+
   return TRUE;
 #else
   return TRUE;
@@ -866,6 +901,9 @@ bus_selinux_shutdown (void)
 #endif /* DBUS_ENABLE_VERBOSE_MODE */
 
   avc_destroy ();
+#ifdef HAVE_LIBAUDIT
+      audit_close (audit_fd);
+#endif /* HAVE_LIBAUDIT */
 #endif /* HAVE_SELINUX */
 }
 
index 83946a483cac5e7ee7d4eceff34457b5f4bf6a92..2ddded03e3c8f5493c8299a3de2f680224d998c9 100644 (file)
@@ -39,7 +39,7 @@ AC_ARG_ENABLE(mono,             [  --enable-mono         build mono bindings],en
 AC_ARG_ENABLE(mono_docs,        [  --enable-mono-docs    build mono docs],enable_mono_docs=$enableval,enable_mono_docs=auto)
 AC_ARG_ENABLE(python,           [  --enable-python       build python bindings],enable_python=$enableval,enable_python=auto)
 AC_ARG_ENABLE(selinux,          [  --enable-selinux      build with SELinux support],enable_selinux=$enableval,enable_selinux=auto)
-
+AC_ARG_ENABLE(libaudit,          [  --enable-libaudit    build audit daemon support for SELinux],enable_libaudit=$enableval,enable_libaudit=auto)
 AC_ARG_WITH(xml,                [  --with-xml=[libxml/expat]           XML library to use])
 AC_ARG_WITH(init-scripts,       [  --with-init-scripts=[redhat]        Style of init scripts to install])
 AC_ARG_WITH(session-socket-dir, [  --with-session-socket-dir=[dirname] Where to put sockets for the per-login-session message bus])
@@ -724,6 +724,27 @@ else
     SELINUX_LIBS=
 fi
 
+# libaudit detection
+if test x$enable_libaudit = xno ; then
+    have_libaudit=no;
+else
+    # See if we have audit daemon & capabilities library
+    AC_CHECK_LIB(audit, audit_log_user_avc_message,
+                 have_libaudit=yes, have_libaudit=no)
+    if test x$have_libaudit = xyes ; then
+        AC_CHECK_LIB(cap, cap_set_proc,
+                 have_libaudit=yes, have_libaudit=no)
+    fi
+fi
+
+AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
+
+if test x$have_libaudit = xyes ; then
+    SELINUX_LIBS="$SELINUX_LIBS -laudit"
+    LIBS="-lcap $LIBS"
+    AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support])
+fi
+
 #### Set up final flags
 DBUS_CLIENT_CFLAGS=
 DBUS_CLIENT_LIBS=
index 79f764d65110d73a27acd2a0ba7b43957646f250..4092ae915c96106249f17d29f3f8441bcf013601 100644 (file)
 #include <sys/socket.h>
 #include <dirent.h>
 #include <sys/un.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <sys/prctl.h>
+#include <sys/capability.h>
+#include <libaudit.h>
+#endif /* HAVE_LIBAUDIT */
+
 #include <pwd.h>
 #include <time.h>
 #include <locale.h>
@@ -3281,6 +3288,55 @@ _dbus_change_identity  (dbus_uid_t     uid,
                         dbus_gid_t     gid,
                         DBusError     *error)
 {
+  int priv = FALSE;
+
+#ifdef HAVE_LIBAUDIT
+  /* have a tmp set of caps that we use to transition to the usr/grp dbus should
+   * run as ... doesn't really help. But keeps people happy.
+   */
+  cap_t new_caps = NULL;
+
+  priv = !getuid();
+  if (priv)
+    {
+      cap_value_t new_cap_list[] = { CAP_AUDIT_WRITE };
+      cap_value_t tmp_cap_list[] = { CAP_AUDIT_WRITE, CAP_SETUID, CAP_SETGID };
+      cap_t tmp_caps = cap_init();
+
+      if (!tmp_caps || !(new_caps = cap_init()))
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "Failed to initialize drop of capabilities\n");
+          if (tmp_caps)
+            cap_free(tmp_caps);
+          return FALSE;
+        }
+
+      /* assume these work... */
+      cap_set_flag(new_caps, CAP_PERMITTED, 1, new_cap_list, CAP_SET);
+      cap_set_flag(new_caps, CAP_EFFECTIVE, 1, new_cap_list, CAP_SET);
+      cap_set_flag(tmp_caps, CAP_PERMITTED, 3, tmp_cap_list, CAP_SET);
+      cap_set_flag(tmp_caps, CAP_EFFECTIVE, 3, tmp_cap_list, CAP_SET);
+
+      if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
+        {
+          dbus_set_error (error, _dbus_error_from_errno (errno),
+                          "Failed to set keep-capabilities: %s\n",
+                          _dbus_strerror (errno));
+          cap_free(tmp_caps);
+          goto fail;
+        }
+      if (cap_set_proc(tmp_caps))
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "Failed to drop capabilities\n");
+          cap_free(tmp_caps);
+          goto fail;
+        }
+      cap_free(tmp_caps);
+    }
+#endif /* HAVE_LIBAUDIT */
+
   /* Set GID first, or the setuid may remove our permission
    * to change the GID
    */
@@ -3289,7 +3345,7 @@ _dbus_change_identity  (dbus_uid_t     uid,
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to set GID to %lu: %s", gid,
                       _dbus_strerror (errno));
-      return FALSE;
+      goto fail;
     }
   
   if (setuid (uid) < 0)
@@ -3297,10 +3353,43 @@ _dbus_change_identity  (dbus_uid_t     uid,
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to set UID to %lu: %s", uid,
                       _dbus_strerror (errno));
-      return FALSE;
+      goto fail;
     }
   
-  return TRUE;
+#ifdef HAVE_LIBAUDIT
+    if (priv)
+      {
+        if (cap_set_proc(new_caps))
+          {
+            dbus_set_error (error, DBUS_ERROR_FAILED,
+                            "Failed to drop capabilities\n");
+            goto fail;
+          }
+        cap_free(new_caps);
+
+        if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == -1)
+          { /* should always work, if it did above */
+            dbus_set_error (error, _dbus_error_from_errno (errno),
+                            "Failed to unset keep-capabilities: %s\n",
+                            _dbus_strerror (errno));
+            return FALSE;
+          }
+      }
+#endif
+
+ return TRUE;
+
+ fail:
+#ifdef HAVE_LIBAUDIT
+  if (priv)
+    {
+      /* should always work, if it did above */
+      prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
+      cap_free(new_caps);
+    }
+#endif
+  return FALSE;
+
 }
 
 /** Installs a UNIX signal handler