Set correct address when using --address=systemd:

When dbus gets launched through systemd, we need to create an address
string based on the sockets passed.

The _dbus_append_addres_from_socket() function is responsible for
extracting the address information from the file-descriptor and
formatting it in a dbus friendly way.

This fixes bus activation when running dbus under a systemd session.

https://bugs.freedesktop.org/show_bug.cgi?id=50962

Signed-off-by: Simon Peeters <peeters.simon@gmail.com>
This commit is contained in:
Simon Peeters 2012-10-07 16:59:30 +02:00 committed by Colin Walters
parent 778e2a5a91
commit d728fdc655
3 changed files with 99 additions and 15 deletions

View file

@ -149,7 +149,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
}
else if (strcmp (method, "systemd") == 0)
{
int n, *fds;
int i, n, *fds;
DBusString address;
n = _dbus_listen_systemd_sockets (&fds, error);
@ -159,27 +159,39 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
}
_dbus_string_init_const (&address, "systemd:");
if (!_dbus_string_init (&address))
goto systemd_oom;
for (i = 0; i < n; i++)
{
if (i > 0)
{
if (!_dbus_string_append (&address, ";"))
goto systemd_oom;
}
if (!_dbus_append_address_from_socket (fds[i], &address, error))
goto systemd_err;
}
*server_p = _dbus_server_new_for_socket (fds, n, &address, NULL);
if (*server_p == NULL)
{
int i;
for (i = 0; i < n; i++)
{
_dbus_close_socket (fds[i], NULL);
}
dbus_free (fds);
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
}
goto systemd_oom;
dbus_free (fds);
return DBUS_SERVER_LISTEN_OK;
}
systemd_oom:
_DBUS_SET_OOM (error);
systemd_err:
for (i = 0; i < n; i++)
{
_dbus_close_socket (fds[i], NULL);
}
dbus_free (fds);
_dbus_string_free (&address);
return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
}
#ifdef DBUS_ENABLE_LAUNCHD
else if (strcmp (method, "launchd") == 0)
{

View file

@ -55,6 +55,7 @@
#include <netinet/in.h>
#include <netdb.h>
#include <grp.h>
#include <arpa/inet.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
@ -4160,4 +4161,71 @@ _dbus_check_setuid (void)
#endif
}
/**
* Read the address from the socket and append it to the string
*
* @param fd the socket
* @param address
* @param error return location for error code
*/
dbus_bool_t
_dbus_append_address_from_socket (int fd,
DBusString *address,
DBusError *error)
{
union {
struct sockaddr sa;
struct sockaddr_storage storage;
struct sockaddr_un un;
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
} socket;
char hostip[INET6_ADDRSTRLEN];
int size = sizeof (socket);
if (getsockname (fd, &socket.sa, &size))
goto err;
switch (socket.sa.sa_family)
{
case AF_UNIX:
if (socket.un.sun_path[0]=='\0')
{
if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1])))
return TRUE;
}
else
{
if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path))
return TRUE;
}
break;
case AF_INET:
if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
hostip, ntohs (socket.ipv4.sin_port)))
return TRUE;
break;
#ifdef AF_INET6
case AF_INET6:
if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u",
hostip, ntohs (socket.ipv6.sin6_port)))
return TRUE;
break;
#endif
default:
dbus_set_error (error,
_dbus_error_from_errno (EINVAL),
"Failed to read address from socket: Unknown socket type.");
return FALSE;
}
err:
dbus_set_error (error,
_dbus_error_from_errno (errno),
"Failed to open socket: %s",
_dbus_strerror (errno));
return FALSE;
}
/* tests in dbus-sysdeps-util.c */

View file

@ -138,6 +138,10 @@ dbus_bool_t _dbus_parse_uid (const DBusString *uid_str,
void _dbus_close_all (void);
dbus_bool_t _dbus_append_address_from_socket (int fd,
DBusString *address,
DBusError *error);
/** @} */
DBUS_END_DECLS