Commit f26ade30 authored by Patrick Welche's avatar Patrick Welche Committed by Simon McVittie
Browse files

Implement NetBSD credentials-passing with LOCAL_PEEREID


Reviewed-by: default avatarSimon McVittie <>
Reviewed-by: default avatarAlban Crequy <>
Tested-by: default avatarPatrick Welche <>
parent fc2fa25a
......@@ -1312,6 +1312,11 @@ check_get_connection_unix_process_id (BusContext *context,
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
defined(__linux__) || \
/* In principle NetBSD should also be in that list, but
* its implementation of PID-passing doesn't work
* over a socketpair() as used in the debug-pipe transport.
* We test this functionality in a more realistic situation
* in test/dbus-daemon.c. */
warn_unexpected (connection, message, "not this error");
goto out;
......@@ -818,6 +818,11 @@ if test x$dbus_have_struct_cmsgcred = xyes; then
AC_DEFINE(HAVE_CMSGCRED,1,[Have cmsgcred structure])
AC_CHECK_MEMBER([struct unpcbid.unp_pid],
[AC_DEFINE([HAVE_UNPCBID], 1, [Have unpcbid structure])],
[[#include <sys/un.h>]])
AC_CHECK_FUNCS(getpeerucred getpeereid)
AC_CHECK_FUNCS(pipe2 accept4)
......@@ -1797,16 +1797,41 @@ _dbus_read_credentials_socket (int client_fd,
int cr_len = sizeof (cr);
if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
cr_len == sizeof (cr))
if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
pid_read =;
uid_read = cr.uid;
_dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
_dbus_strerror (errno));
else if (cr_len != sizeof (cr))
_dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
cr_len, (int) sizeof (cr));
pid_read =;
uid_read = cr.uid;
#elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
/* Another variant of the above - used on NetBSD
struct unpcbid cr;
socklen_t cr_len = sizeof (cr);
if (getsockopt (client_fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
_dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
_dbus_strerror (errno));
else if (cr_len != sizeof (cr))
_dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
cr_len, (int) sizeof (cr));
_dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
cr_len, (int) sizeof (cr), _dbus_strerror (errno));
pid_read = cr.unp_pid;
uid_read = cr.unp_euid;
#elif defined(HAVE_CMSGCRED)
/* We only check for HAVE_CMSGCRED, but we're really assuming that the
......@@ -567,6 +567,60 @@ test_creds (Fixture *f,
static void
test_processid (Fixture *f,
gconstpointer context)
const char *unique = dbus_bus_get_unique_name (f->left_conn);
DBusMessage *m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
DBusPendingCall *pc;
DBusError error = DBUS_ERROR_INIT;
guint32 pid;
if (m == NULL)
g_error ("OOM");
if (!dbus_message_append_args (m,
g_error ("OOM");
if (!dbus_connection_send_with_reply (f->left_conn, m, &pc,
pc == NULL)
g_error ("OOM");
dbus_message_unref (m);
m = NULL;
if (dbus_pending_call_get_completed (pc))
pending_call_store_reply (pc, &m);
else if (!dbus_pending_call_set_notify (pc, pending_call_store_reply,
&m, NULL))
g_error ("OOM");
while (m == NULL)
test_main_context_iterate (f->ctx, TRUE);
g_assert_cmpstr (dbus_message_get_signature (m), ==, "u");
g_assert_true (dbus_message_get_args (m, &error,
// g_assert_no_error (&error);
g_message ("GetConnectionUnixProcessID returned %u", pid);
#ifdef G_OS_UNIX
g_assert_cmpuint (pid, ==, getpid ());
#elif defined(G_OS_WIN32)
g_assert_cmpuint (pid, ==, GetCurrentProcessId ());
g_assert_not_reached ();
static void
teardown (Fixture *f,
gconstpointer context G_GNUC_UNUSED)
......@@ -632,6 +686,7 @@ main (int argc,
g_test_add ("/no-reply/timeout", Fixture, &finite_timeout_config,
setup, test_no_reply, teardown);
g_test_add ("/creds", Fixture, NULL, setup, test_creds, teardown);
g_test_add ("/processid", Fixture, NULL, setup, test_processid, teardown);
return g_test_run ();
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