summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2007-06-13 16:30:43 +0000
committerHavoc Pennington <hp@redhat.com>2007-06-13 16:30:43 +0000
commite3d30a03225dd1d26012ecd39b09e4ccf91befb5 (patch)
treed912bb502f5ea4d253c4b3c6c1c5f3e4ba159297 /dbus
parent15a610bc4c87d389463112ef0ad4fde195af83ca (diff)
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
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-sysdeps-util-unix.c104
-rw-r--r--dbus/dbus-transport.c4
2 files changed, 102 insertions, 6 deletions
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c
index 339b8f96..e81c752e 100644
--- a/dbus/dbus-sysdeps-util-unix.c
+++ b/dbus/dbus-sysdeps-util-unix.c
@@ -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
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index d738cc0c..0e27dd13 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -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,