mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-24 07:40:07 +01:00
2007-06-13 Havoc Pennington <hp@redhat.com>
* configure.ac, bus/selinux.c, dbus/dbus-sysdeps-unix-util.c: add libaudit support, no clue what this means really but now we have it. Patches from Fedora package. * bus/bus.c (bus_context_new): move selinux initialization after changing to daemon user, patch from Fedora package * dbus/dbus-transport.c (auth_via_unix_user_function): fix a typo
This commit is contained in:
parent
15a610bc4c
commit
e3d30a0322
6 changed files with 192 additions and 13 deletions
11
ChangeLog
11
ChangeLog
|
|
@ -1,3 +1,14 @@
|
|||
2007-06-13 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* configure.ac, bus/selinux.c, dbus/dbus-sysdeps-unix-util.c: add
|
||||
libaudit support, no clue what this means really but now we have
|
||||
it. Patches from Fedora package.
|
||||
|
||||
* bus/bus.c (bus_context_new): move selinux initialization after
|
||||
changing to daemon user, patch from Fedora package
|
||||
|
||||
* dbus/dbus-transport.c (auth_via_unix_user_function): fix a typo
|
||||
|
||||
2007-06-12 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* dbus/dbus-message.c (dbus_message_iter_open_container): improve
|
||||
|
|
|
|||
10
bus/bus.c
10
bus/bus.c
|
|
@ -739,11 +739,6 @@ bus_context_new (const DBusString *config_file,
|
|||
_dbus_string_free (&pid);
|
||||
}
|
||||
|
||||
if (!bus_selinux_full_init ())
|
||||
{
|
||||
_dbus_warn ("SELinux initialization failed\n");
|
||||
}
|
||||
|
||||
if (!process_config_postinit (context, parser, error))
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
|
|
@ -767,6 +762,11 @@ bus_context_new (const DBusString *config_file,
|
|||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bus_selinux_full_init ())
|
||||
{
|
||||
_dbus_warn ("SELinux initialization failed\n");
|
||||
}
|
||||
|
||||
dbus_server_free_data_slot (&server_data_slot);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,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))
|
||||
|
|
@ -100,11 +103,50 @@ static const struct avc_lock_callback lock_cb =
|
|||
* @param variable argument list
|
||||
*/
|
||||
#ifdef HAVE_SELINUX
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
static int audit_fd = -1;
|
||||
#endif
|
||||
|
||||
static void
|
||||
audit_init(void)
|
||||
{
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
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
|
||||
if (audit_fd >= 0)
|
||||
{
|
||||
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());
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_LIBAUDIT */
|
||||
|
||||
vsyslog (LOG_INFO, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
|
@ -303,6 +345,8 @@ bus_selinux_full_init (void)
|
|||
|
||||
freecon (bus_context);
|
||||
|
||||
audit_init ();
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return TRUE;
|
||||
|
|
@ -925,12 +969,18 @@ bus_selinux_shutdown (void)
|
|||
{
|
||||
sidput (bus_sid);
|
||||
bus_sid = SECSID_WILD;
|
||||
|
||||
|
||||
#ifdef DBUS_ENABLE_VERBOSE_MODE
|
||||
bus_avc_print_stats ();
|
||||
|
||||
if (_dbus_is_verbose())
|
||||
bus_avc_print_stats ();
|
||||
|
||||
#endif /* DBUS_ENABLE_VERBOSE_MODE */
|
||||
|
||||
avc_destroy ();
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
audit_close (audit_fd);
|
||||
#endif /* HAVE_LIBAUDIT */
|
||||
}
|
||||
#endif /* HAVE_SELINUX */
|
||||
}
|
||||
|
|
|
|||
22
configure.in
22
configure.in
|
|
@ -56,6 +56,7 @@ AC_ARG_ENABLE(doxygen-docs, AS_HELP_STRING([--enable-doxygen-docs],[build DOXYGE
|
|||
AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov],[compile with coverage profiling instrumentation (gcc only)]),enable_gcov=$enableval,enable_gcov=no)
|
||||
AC_ARG_ENABLE(abstract-sockets, AS_HELP_STRING([--enable-abstract-sockets],[use abstract socket namespace (linux only)]),enable_abstract_sockets=$enableval,enable_abstract_sockets=auto)
|
||||
AC_ARG_ENABLE(selinux, AS_HELP_STRING([--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_ENABLE(dnotify, AS_HELP_STRING([--enable-dnotify],[build with dnotify support (linux only)]),enable_dnotify=$enableval,enable_dnotify=auto)
|
||||
AC_ARG_ENABLE(kqueue, AS_HELP_STRING([--enable-kqueue],[build with kqueue support]),enable_kqueue=$enableval,enable_kqueue=auto)
|
||||
AC_ARG_ENABLE(console-owner-file, AS_HELP_STRING([--enable-console-owner-file],[enable console owner file]),enable_console_owner_file=$enableval,enable_console_owner_file=auto)
|
||||
|
|
@ -904,6 +905,27 @@ fi
|
|||
|
||||
AM_CONDITIONAL(HAVE_CONSOLE_OWNER_FILE, test x$have_console_owner_file = xyes)
|
||||
|
||||
# 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="$THREAD_LIBS"
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@
|
|||
#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 */
|
||||
|
||||
#ifdef HAVE_SYS_SYSLIMITS_H
|
||||
#include <sys/syslimits.h>
|
||||
|
|
@ -273,7 +278,11 @@ _dbus_change_to_daemon_user (const char *user,
|
|||
dbus_uid_t uid;
|
||||
dbus_gid_t gid;
|
||||
DBusString u;
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
dbus_bool_t we_were_root;
|
||||
cap_t new_caps;
|
||||
#endif
|
||||
|
||||
_dbus_string_init_const (&u, user);
|
||||
|
||||
if (!_dbus_get_user_id_and_primary_group (&u, &uid, &gid))
|
||||
|
|
@ -284,6 +293,58 @@ _dbus_change_to_daemon_user (const char *user,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
we_were_root = _dbus_getuid () == 0;
|
||||
new_caps = NULL;
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
if (!we_were_root)
|
||||
{
|
||||
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: %s\n",
|
||||
_dbus_strerror (errno));
|
||||
|
||||
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) == -1)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Failed to drop capabilities: %s\n",
|
||||
_dbus_strerror (errno));
|
||||
cap_free (tmp_caps);
|
||||
goto fail;
|
||||
}
|
||||
cap_free (tmp_caps);
|
||||
}
|
||||
#endif /* HAVE_LIBAUDIT */
|
||||
|
||||
/* setgroups() only works if we are a privileged process,
|
||||
* so we don't return error on failure; the only possible
|
||||
* failure is that we don't have perms to do it.
|
||||
|
|
@ -303,7 +364,7 @@ _dbus_change_to_daemon_user (const char *user,
|
|||
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)
|
||||
|
|
@ -311,10 +372,45 @@ _dbus_change_to_daemon_user (const char *user,
|
|||
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 (!we_were_root)
|
||||
{
|
||||
if (cap_set_proc (new_caps))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Failed to drop capabilities: %s\n",
|
||||
_dbus_strerror (errno));
|
||||
goto fail;
|
||||
}
|
||||
cap_free (new_caps);
|
||||
|
||||
/* should always work, if it did above */
|
||||
if (prctl (PR_SET_KEEPCAPS, 0, 0, 0, 0) == -1)
|
||||
{
|
||||
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 (!we_were_root)
|
||||
{
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -516,9 +516,9 @@ auth_via_unix_user_function (DBusTransport *transport)
|
|||
connection = transport->connection;
|
||||
unix_user_function = transport->unix_user_function;
|
||||
unix_user_data = transport->unix_user_data;
|
||||
uid = _dbus_credentials_get_unix_uid (auth_identity),
|
||||
uid = _dbus_credentials_get_unix_uid (auth_identity);
|
||||
|
||||
_dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_unlock (connection);
|
||||
|
||||
allow = (* unix_user_function) (connection,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue