0d83b87
--- dbus-0.61/bus/selinux.c.selinux-avc-audit	2006-02-24 14:41:15.000000000 -0500
0d83b87
+++ dbus-0.61/bus/selinux.c	2006-02-24 14:41:15.000000000 -0500
0d83b87
@@ -38,6 +38,9 @@
0d83b87
 #include <selinux/flask.h>
0d83b87
 #include <signal.h>
0d83b87
 #include <stdarg.h>
0d83b87
+#ifdef HAVE_LIBAUDIT
0d83b87
+#include <libaudit.h>
0d83b87
+#endif /* HAVE_LIBAUDIT */
0d83b87
 #endif /* HAVE_SELINUX */
0d83b87
 
0d83b87
 #define BUS_SID_FROM_SELINUX(sid)  ((BusSELinuxID*) (sid))
0d83b87
@@ -100,12 +103,40 @@
0d83b87
  * @param variable argument list
0d83b87
  */
0d83b87
 #ifdef HAVE_SELINUX
0d83b87
+#ifdef HAVE_LIBAUDIT
0d83b87
+static int audit_fd = -1;
0d83b87
+static void audit_init(void)
0d83b87
+{
0d83b87
+  audit_fd = audit_open();
0d83b87
+  if (audit_fd < 0) {
0d83b87
+    /* If kernel doesn't support audit, bail out */
0d83b87
+    if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
0d83b87
+      return;
0d83b87
+    /* If user bus, bail out */
0d83b87
+    if (errno == EPERM && getuid() != 0)
0d83b87
+      return;
0d83b87
+    _dbus_warn ("Failed opening connection to the audit subsystem");
0d83b87
+  }
0d83b87
+}
0d83b87
+#endif /* HAVE_LIBAUDIT */
0d83b87
+
0d83b87
 static void 
0d83b87
 log_callback (const char *fmt, ...) 
0d83b87
 {
0d83b87
   va_list ap;
0d83b87
   va_start(ap, fmt);
0d83b87
+#ifdef HAVE_LIBAUDIT
0d83b87
+  {
0d83b87
+     char buf[PATH_MAX*2];
0d83b87
+
0d83b87
+	/* FIXME: need to change this to show real user */
0d83b87
+     vsnprintf(buf, sizeof(buf), fmt, ap);
0d83b87
+     audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
0d83b87
+                                NULL, getuid());
0d83b87
+  }
0d83b87
+#else
0d83b87
   vsyslog (LOG_INFO, fmt, ap);
0d83b87
+#endif /* HAVE_LIBAUDIT */
0d83b87
   va_end(ap);
0d83b87
 }
0d83b87
 
0d83b87
@@ -313,6 +344,10 @@
0d83b87
 
0d83b87
   freecon (bus_context);
0d83b87
   
0d83b87
+#ifdef HAVE_LIBAUDIT
0d83b87
+  audit_init ();
0d83b87
+#endif /* HAVE_LIBAUDIT */
0d83b87
+
0d83b87
   return TRUE;
0d83b87
 #else
0d83b87
   return TRUE;
0d83b87
@@ -937,6 +972,9 @@
0d83b87
 #endif /* DBUS_ENABLE_VERBOSE_MODE */
0d83b87
 
0d83b87
       avc_destroy ();
0d83b87
+#ifdef HAVE_LIBAUDIT
0d83b87
+      audit_close (audit_fd);
0d83b87
+#endif /* HAVE_LIBAUDIT */
0d83b87
     }
0d83b87
 #endif /* HAVE_SELINUX */
0d83b87
 }
0d83b87
--- dbus-0.61/configure.in.selinux-avc-audit	2006-02-24 11:36:29.000000000 -0500
0d83b87
+++ dbus-0.61/configure.in	2006-02-24 14:55:17.000000000 -0500
0d83b87
@@ -67,6 +67,7 @@
0d83b87
 AC_ARG_ENABLE(mono_docs, AS_HELP_STRING([--enable-mono-docs],[build mono docs]),enable_mono_docs=$enableval,enable_mono_docs=no)
0d83b87
 AC_ARG_ENABLE(python, AS_HELP_STRING([--enable-python],[build python bindings]),enable_python=$enableval,enable_python=auto)
0d83b87
 AC_ARG_ENABLE(selinux, AS_HELP_STRING([--enable-selinux],[build with SELinux support]),enable_selinux=$enableval,enable_selinux=auto)
0d83b87
+AC_ARG_ENABLE(libaudit,          [  --enable-libaudit    build audit daemon support for SELinux],enable_libaudit=$enableval,enable_libaudit=auto)
0d83b87
 AC_ARG_ENABLE(dnotify, AS_HELP_STRING([--enable-dnotify],[build with dnotify support (linux only)]),enable_dnotify=$enableval,enable_dnotify=auto)
0d83b87
 
0d83b87
 AC_ARG_WITH(xml, AS_HELP_STRING([--with-xml=[libxml/expat]],[XML library to use]))
0d83b87
@@ -851,6 +852,27 @@
0d83b87
    AC_DEFINE(DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX,1,[Use dnotify on Linux])
0d83b87
 fi
0d83b87
 
0d83b87
+# libaudit detection
0d83b87
+if test x$enable_libaudit = xno ; then
0d83b87
+    have_libaudit=no;
0d83b87
+else
0d83b87
+    # See if we have audit daemon & capabilities library
0d83b87
+    AC_CHECK_LIB(audit, audit_log_user_avc_message, 
0d83b87
+                 have_libaudit=yes, have_libaudit=no)
0d83b87
+    if test x$have_libaudit = xyes ; then
0d83b87
+        AC_CHECK_LIB(cap, cap_set_proc, 
0d83b87
+                 have_libaudit=yes, have_libaudit=no)
0d83b87
+    fi
0d83b87
+fi
0d83b87
+
0d83b87
+AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
0d83b87
+
0d83b87
+if test x$have_libaudit = xyes ; then
0d83b87
+    SELINUX_LIBS="$SELINUX_LIBS -laudit"
0d83b87
+    LIBS="-lcap $LIBS"
0d83b87
+    AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support])
0d83b87
+fi
0d83b87
+
0d83b87
 #### Set up final flags
0d83b87
 DBUS_CLIENT_CFLAGS=
0d83b87
 DBUS_CLIENT_LIBS=
abd219a
--- dbus-0.61-orig/dbus/dbus-sysdeps-util.c.selinux-avc-audit	2006-02-24 10:46:45.000000000 -0500
abd219a
+++ dbus-0.61/dbus/dbus-sysdeps-util.c	2006-04-04 13:00:04.000000000 -0400
abd219a
@@ -42,6 +42,11 @@
abd219a
 #include <sys/socket.h>
abd219a
 #include <dirent.h>
abd219a
 #include <sys/un.h>
abd219a
+#ifdef HAVE_LIBAUDIT
abd219a
+#include <sys/prctl.h>
abd219a
+#include <sys/capability.h>
abd219a
+#include <libaudit.h>
abd219a
+#endif /* HAVE_LIBAUDIT */
abd219a
 
abd219a
 #ifndef O_BINARY
abd219a
 #define O_BINARY 0
abd219a
@@ -247,6 +252,55 @@
abd219a
                         dbus_gid_t     gid,
abd219a
                         DBusError     *error)
abd219a
 {
abd219a
+  int priv = FALSE;
abd219a
+  
abd219a
+#ifdef HAVE_LIBAUDIT
abd219a
+  /* have a tmp set of caps that we use to transition to the usr/grp dbus should
abd219a
+   * run as ... doesn't really help. But keeps people happy.
abd219a
+   */
abd219a
+  cap_t new_caps = NULL;
abd219a
+
abd219a
+  priv = !getuid();
abd219a
+  if (priv)
abd219a
+    {
abd219a
+      cap_value_t new_cap_list[] = { CAP_AUDIT_WRITE };
abd219a
+      cap_value_t tmp_cap_list[] = { CAP_AUDIT_WRITE, CAP_SETUID, CAP_SETGID };
abd219a
+      cap_t tmp_caps = cap_init();
abd219a
+      
abd219a
+      if (!tmp_caps || !(new_caps = cap_init()))
abd219a
+        {
abd219a
+          dbus_set_error (error, DBUS_ERROR_FAILED,
abd219a
+                          "Failed to initialize drop of capabilities\n");
abd219a
+          if (tmp_caps)
abd219a
+            cap_free(tmp_caps);
abd219a
+          return FALSE;
abd219a
+        }
abd219a
+
abd219a
+      /* assume these work... */
abd219a
+      cap_set_flag(new_caps, CAP_PERMITTED, 1, new_cap_list, CAP_SET);
abd219a
+      cap_set_flag(new_caps, CAP_EFFECTIVE, 1, new_cap_list, CAP_SET);
abd219a
+      cap_set_flag(tmp_caps, CAP_PERMITTED, 3, tmp_cap_list, CAP_SET);
abd219a
+      cap_set_flag(tmp_caps, CAP_EFFECTIVE, 3, tmp_cap_list, CAP_SET);
abd219a
+      
abd219a
+      if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
abd219a
+        {
abd219a
+          dbus_set_error (error, _dbus_error_from_errno (errno),
abd219a
+                          "Failed to set keep-capabilities: %s\n",
abd219a
+                          _dbus_strerror (errno));
abd219a
+          cap_free(tmp_caps);
abd219a
+          goto fail;
abd219a
+        }
abd219a
+      if (cap_set_proc(tmp_caps))
abd219a
+        {
abd219a
+          dbus_set_error (error, DBUS_ERROR_FAILED,
abd219a
+                          "Failed to drop capabilities\n");
abd219a
+          cap_free(tmp_caps);
abd219a
+          goto fail;
abd219a
+        }
abd219a
+      cap_free(tmp_caps);
abd219a
+    }
abd219a
+#endif /* HAVE_LIBAUDIT */
abd219a
+
abd219a
   /* setgroups() only works if we are a privileged process,
abd219a
    * so we don't return error on failure; the only possible
abd219a
    * failure is that we don't have perms to do it.
abd219a
@@ -265,7 +319,7 @@
abd219a
       dbus_set_error (error, _dbus_error_from_errno (errno),
abd219a
                       "Failed to set GID to %lu: %s", gid,
abd219a
                       _dbus_strerror (errno));
abd219a
-      return FALSE;
abd219a
+      goto fail;
abd219a
     }
abd219a
   
abd219a
   if (setuid (uid) < 0)
abd219a
@@ -273,10 +327,42 @@
abd219a
       dbus_set_error (error, _dbus_error_from_errno (errno),
abd219a
                       "Failed to set UID to %lu: %s", uid,
abd219a
                       _dbus_strerror (errno));
abd219a
-      return FALSE;
abd219a
+      goto fail;
abd219a
     }
abd219a
   
abd219a
-  return TRUE;
abd219a
+#ifdef HAVE_LIBAUDIT
abd219a
+    if (priv)
abd219a
+      {
abd219a
+        if (cap_set_proc(new_caps))
abd219a
+          {
abd219a
+            dbus_set_error (error, DBUS_ERROR_FAILED,
abd219a
+                            "Failed to drop capabilities\n");
abd219a
+            goto fail;
abd219a
+          }
abd219a
+        cap_free(new_caps);
abd219a
+        
abd219a
+        if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == -1)
abd219a
+          { /* should always work, if it did above */
abd219a
+            dbus_set_error (error, _dbus_error_from_errno (errno),
abd219a
+                            "Failed to unset keep-capabilities: %s\n",
abd219a
+                            _dbus_strerror (errno));
abd219a
+            return FALSE;
abd219a
+          }
abd219a
+      }
abd219a
+#endif
abd219a
+
abd219a
+ return TRUE;
abd219a
+
abd219a
+ fail:
abd219a
+#ifdef HAVE_LIBAUDIT
abd219a
+  if (priv)
abd219a
+    {
abd219a
+      /* should always work, if it did above */
abd219a
+      prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
abd219a
+      cap_free(new_caps);
abd219a
+    }
abd219a
+#endif
abd219a
+  return FALSE;
abd219a
 }
abd219a
 
abd219a
 /** Installs a UNIX signal handler