mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-04-25 21:20:43 +02:00
Merge branch 'unix-gids' into 'master'
Add UnixGroupIDs to connection credentials See merge request dbus/dbus!105 Fixes: dbus/dbus#196
This commit is contained in:
commit
6884f63e0e
5 changed files with 189 additions and 34 deletions
57
bus/driver.c
57
bus/driver.c
|
|
@ -1904,6 +1904,59 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the unix group ids of credentials @credentials, if available, into
|
||||
* the a{sv} @asv_iter. Return #FALSE on OOM.
|
||||
*/
|
||||
static dbus_bool_t
|
||||
bus_driver_credentials_fill_unix_gids (DBusCredentials *credentials,
|
||||
DBusMessageIter *asv_iter)
|
||||
{
|
||||
const dbus_gid_t *gids = NULL;
|
||||
size_t n_gids = 0;
|
||||
|
||||
if (!_dbus_credentials_get_unix_gids (credentials, &gids, &n_gids))
|
||||
return TRUE;
|
||||
|
||||
if (sizeof (dbus_gid_t) == sizeof (dbus_uint32_t))
|
||||
{
|
||||
return _dbus_asv_add_fixed_array (asv_iter, "UnixGroupIDs",
|
||||
DBUS_TYPE_UINT32, gids, n_gids);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we can't represent > 32-bit uids; if your system needs them, please
|
||||
* add UnixGroupIDs64 to the spec or something */
|
||||
dbus_uint32_t *gids_u32;
|
||||
size_t i;
|
||||
dbus_bool_t result;
|
||||
|
||||
gids_u32 = dbus_new (dbus_uint32_t, n_gids);
|
||||
if (gids_u32 == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_gids; i++)
|
||||
{
|
||||
if (gids[i] > _DBUS_UINT32_MAX)
|
||||
{
|
||||
/* At least one gid is unrepresentable, so behave as though
|
||||
* we didn't know the group IDs at all (not an error, just
|
||||
* success with less information) */
|
||||
dbus_free (gids_u32);
|
||||
return TRUE;
|
||||
}
|
||||
gids_u32[i] = gids[i];
|
||||
}
|
||||
|
||||
result = _dbus_asv_add_fixed_array (asv_iter, "UnixGroupIDs",
|
||||
DBUS_TYPE_UINT32, gids_u32, n_gids);
|
||||
|
||||
dbus_free (gids_u32);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the credentials of connection @conn (or the bus daemon itself,
|
||||
* if @conn is #NULL) into the a{sv} @asv_iter. Return #FALSE on OOM.
|
||||
|
|
@ -1943,6 +1996,10 @@ bus_driver_fill_connection_credentials (DBusCredentials *credentials,
|
|||
!_dbus_asv_add_uint32 (asv_iter, "UnixUserID", uid))
|
||||
return FALSE;
|
||||
|
||||
if (credentials != NULL &&
|
||||
!bus_driver_credentials_fill_unix_gids (credentials, asv_iter))
|
||||
return FALSE;
|
||||
|
||||
if (windows_sid != NULL)
|
||||
{
|
||||
DBusString str;
|
||||
|
|
|
|||
|
|
@ -295,6 +295,63 @@ _dbus_asv_add_object_path (DBusMessageIter *arr_iter,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new entry in an a{sv} (map from string to variant)
|
||||
* with an array of a fixed-length basic type (excluding unix fd).
|
||||
*
|
||||
* If this function fails, the a{sv} must be abandoned, for instance
|
||||
* with _dbus_asv_abandon().
|
||||
*
|
||||
* @param arr_iter the iterator which is appending to the array
|
||||
* @param key a UTF-8 key for the map
|
||||
* @param value the value
|
||||
* @param n_elements the number of elements to append
|
||||
* @returns #TRUE on success, or #FALSE if not enough memory
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_asv_add_fixed_array (DBusMessageIter *arr_iter,
|
||||
const char *key,
|
||||
char element_type,
|
||||
const void *value,
|
||||
int n_elements)
|
||||
{
|
||||
const char type[] = { DBUS_TYPE_ARRAY, element_type, 0 };
|
||||
DBusMessageIter entry_iter;
|
||||
DBusMessageIter var_iter;
|
||||
DBusMessageIter array_iter;
|
||||
|
||||
_dbus_assert (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD);
|
||||
|
||||
if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, type, &var_iter))
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_message_iter_open_container (&var_iter, DBUS_TYPE_ARRAY, type + 1,
|
||||
&array_iter))
|
||||
{
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_append_fixed_array (&array_iter, element_type,
|
||||
&value, n_elements))
|
||||
{
|
||||
dbus_message_iter_abandon_container (&var_iter, &array_iter);
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_close_container (&var_iter, &array_iter))
|
||||
{
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new entry in an a{sv} (map from string to variant)
|
||||
* with a byte array value.
|
||||
|
|
@ -314,37 +371,6 @@ _dbus_asv_add_byte_array (DBusMessageIter *arr_iter,
|
|||
const void *value,
|
||||
int n_elements)
|
||||
{
|
||||
DBusMessageIter entry_iter;
|
||||
DBusMessageIter var_iter;
|
||||
DBusMessageIter byte_array_iter;
|
||||
|
||||
if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key, "ay", &var_iter))
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_message_iter_open_container (&var_iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_BYTE_AS_STRING,
|
||||
&byte_array_iter))
|
||||
{
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_append_fixed_array (&byte_array_iter, DBUS_TYPE_BYTE,
|
||||
&value, n_elements))
|
||||
{
|
||||
dbus_message_iter_abandon_container (&var_iter, &byte_array_iter);
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_close_container (&var_iter, &byte_array_iter))
|
||||
{
|
||||
_dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return _dbus_asv_add_fixed_array (arr_iter, key, DBUS_TYPE_BYTE, value,
|
||||
n_elements);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ dbus_bool_t _dbus_asv_add_string (DBusMessageIter *arr_iter,
|
|||
dbus_bool_t _dbus_asv_add_object_path (DBusMessageIter *arr_iter,
|
||||
const char *key,
|
||||
const char *value);
|
||||
dbus_bool_t _dbus_asv_add_fixed_array (DBusMessageIter *arr_iter,
|
||||
const char *key,
|
||||
char element_type,
|
||||
const void *value,
|
||||
int n_elements);
|
||||
dbus_bool_t _dbus_asv_add_byte_array (DBusMessageIter *arr_iter,
|
||||
const char *key,
|
||||
const void *value,
|
||||
|
|
|
|||
|
|
@ -6725,6 +6725,18 @@
|
|||
<entry>UINT32</entry>
|
||||
<entry>The numeric Unix user ID, as defined by POSIX</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>UnixGroupIDs</entry>
|
||||
<entry>ARRAY of UINT32</entry>
|
||||
<entry>The numeric Unix group IDs (including both the primary
|
||||
group and the supplementary groups), as defined by POSIX, in
|
||||
numerically sorted order. This array is either complete or
|
||||
absent: if the message bus is able to determine some but not
|
||||
all of the caller's groups, or if one of the groups is not
|
||||
representable in a UINT32, it must not add this credential
|
||||
to the dictionary.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>ProcessID</entry>
|
||||
<entry>UINT32</entry>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
#ifdef DBUS_UNIX
|
||||
# include <pwd.h>
|
||||
# include <unistd.h>
|
||||
# include <stdlib.h>
|
||||
# include <search.h>
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef HAVE_GIO_UNIX
|
||||
|
|
@ -392,6 +394,20 @@ test_no_reply (Fixture *f,
|
|||
dbus_clear_message (&reply);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static int
|
||||
gid_cmp (const void *ap, const void *bp)
|
||||
{
|
||||
gid_t a = *(const gid_t *)ap;
|
||||
gid_t b = *(const gid_t *)bp;
|
||||
if (a < b)
|
||||
return -1;
|
||||
if (a > b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_creds (Fixture *f,
|
||||
gconstpointer context)
|
||||
|
|
@ -408,7 +424,8 @@ test_creds (Fixture *f,
|
|||
SEEN_UNIX_USER = 1,
|
||||
SEEN_PID = 2,
|
||||
SEEN_WINDOWS_SID = 4,
|
||||
SEEN_LINUX_SECURITY_LABEL = 8
|
||||
SEEN_LINUX_SECURITY_LABEL = 8,
|
||||
SEEN_UNIX_GROUPS = 16,
|
||||
} seen = 0;
|
||||
|
||||
if (m == NULL)
|
||||
|
|
@ -458,6 +475,44 @@ test_creds (Fixture *f,
|
|||
seen |= SEEN_UNIX_USER;
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
}
|
||||
else if (g_strcmp0 (name, "UnixGroupIDs") == 0)
|
||||
{
|
||||
#ifdef G_OS_UNIX
|
||||
guint32 *groups;
|
||||
gid_t egid = getegid();
|
||||
gid_t *actual_groups;
|
||||
int len, ret, i;
|
||||
size_t nmemb;
|
||||
DBusMessageIter array_iter;
|
||||
|
||||
g_assert (!(seen & SEEN_UNIX_GROUPS));
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&var_iter), ==,
|
||||
DBUS_TYPE_ARRAY);
|
||||
dbus_message_iter_recurse (&var_iter, &array_iter);
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&array_iter), ==,
|
||||
DBUS_TYPE_UINT32);
|
||||
dbus_message_iter_get_fixed_array (&array_iter, &groups, &len);
|
||||
g_test_message ("%s of this process present (%d groups)", name, len);
|
||||
g_assert_cmpint (len, >=, 1);
|
||||
|
||||
actual_groups = g_new0 (gid_t, len+1);
|
||||
ret = getgroups (len, actual_groups);
|
||||
if (ret < 0)
|
||||
g_error ("getgroups: %s", g_strerror (errno));
|
||||
nmemb = ret;
|
||||
if (!lfind (&egid, actual_groups, &nmemb, sizeof (gid_t), gid_cmp))
|
||||
actual_groups[ret++] = egid;
|
||||
g_assert_cmpint (ret, ==, len);
|
||||
qsort (actual_groups, len, sizeof (gid_t), gid_cmp);
|
||||
for (i = 0; i < len; i++)
|
||||
g_assert_true (groups[i] == actual_groups[i]);
|
||||
g_free (actual_groups);
|
||||
|
||||
seen |= SEEN_UNIX_GROUPS;
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
}
|
||||
else if (g_strcmp0 (name, "WindowsSID") == 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue