Commit 7936d37e authored by Colin Walters's avatar Colin Walters
Browse files

RHEL-4: Import dbus-0.22-cap-audit-write.patch

parent f352fdcc
......@@ -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 */
}
......@@ -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=
......
......@@ -38,6 +38,13 @@
#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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment