GDBusServer: Accept empty authorization identity for EXTERNAL mechanism

RFC 4422 appendix A defines the empty authorization identity to mean
the identity that the server associated with its authentication
credentials. In this case, this means whatever uid is in the
GCredentials object.

In particular, this means that clients in a different Linux user
namespace can authenticate against our server and will be authorized
as the version of their uid that is visible in the server's namespace,
even if the corresponding numeric uid returned by geteuid() in the
client's namespace was different. systemd's sd-bus has relied on this
since commit
1ed4723d38.

[Originally part of a larger commit; commit message added by smcv]

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Giuseppe Scrivano 2020-09-14 16:28:10 +02:00 committed by Simon McVittie
parent a7d2e727ee
commit b51e3ab09e

View File

@ -201,14 +201,24 @@ data_matches_credentials (const gchar *data,
if (credentials == NULL)
goto out;
if (data == NULL || data_len == 0)
goto out;
#if defined(G_OS_UNIX)
{
gint64 alleged_uid;
gchar *endp;
/* If we were unable to find out the uid, then nothing
* can possibly match it. */
if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1)
goto out;
/* An empty authorization identity means we want to be
* whatever identity the out-of-band credentials say we have
* (RFC 4422 appendix A.1). This effectively matches any uid. */
if (data == NULL || data_len == 0)
{
match = TRUE;
goto out;
}
/* on UNIX, this is the uid as a string in base 10 */
alleged_uid = g_ascii_strtoll (data, &endp, 10);
if (*endp == '\0')