core: populate $REMOTE_ADDR for AF_UNIX sockets

Set the $REMOTE_ADDR environment variable for AF_UNIX socket connections
when using per-connection socket activation (Accept=yes). $REMOTE_ADDR
will now contain the remote socket's file system path (starting with a
slash "/") or its address in the abstract namespace (starting with an
at symbol "@").

This information is essential for identifying the remote peer in AF_UNIX
socket connections, but it's not easy to obtain in a shell script for
example without pulling in a ton of additional tools. By setting
$REMOTE_ADDR, we make this information readily available to the
activated service.
This commit is contained in:
Kamil Szczęk
2024-06-12 00:11:10 +01:00
committed by Luca Boccassi
parent bd6e5b4d93
commit 608bfe76c1
3 changed files with 36 additions and 17 deletions
+18 -13
View File
@@ -1723,27 +1723,32 @@ static int service_spawn_internal(
* in ENOTCONN), and just use whate we can use. */
if (getpeername(s->socket_fd, &sa.sa, &salen) >= 0 &&
IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK, AF_UNIX)) {
_cleanup_free_ char *addr = NULL;
char *t;
unsigned port;
r = sockaddr_pretty(&sa.sa, salen, true, false, &addr);
r = sockaddr_pretty(&sa.sa, salen, /* translate_ipv6= */ true, /* include_port= */ false, &addr);
if (r < 0)
return r;
t = strjoin("REMOTE_ADDR=", addr);
if (!t)
return -ENOMEM;
our_env[n_env++] = t;
if (sa.sa.sa_family != AF_UNIX || IN_SET(addr[0], '/', '@')) {
t = strjoin("REMOTE_ADDR=", addr);
if (!t)
return -ENOMEM;
our_env[n_env++] = t;
}
r = sockaddr_port(&sa.sa, &port);
if (r < 0)
return r;
if (IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
unsigned port;
if (asprintf(&t, "REMOTE_PORT=%u", port) < 0)
return -ENOMEM;
our_env[n_env++] = t;
r = sockaddr_port(&sa.sa, &port);
if (r < 0)
return r;
if (asprintf(&t, "REMOTE_PORT=%u", port) < 0)
return -ENOMEM;
our_env[n_env++] = t;
}
}
}