diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 814400ad43..237394b1fa 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -4913,6 +4913,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PassPacketInfo = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly b AcceptFileDescriptors = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Timestamping = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveOnStop = ...;
@@ -5584,6 +5586,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
@@ -6188,6 +6192,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
@@ -12099,6 +12105,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
PrivatePIDs were added in version 257.
ProtectHostnameEx,
PassPIDFD,
+ AcceptFileDescriptors,
DelegateNamespaces, and
RemoveSubgroup() were added in version 258.
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index b43f8e685b..91552d691f 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -771,6 +771,17 @@
+
+ AcceptFileDescriptors=
+
+ Takes a boolean value. This controls the SO_PASSRIGHTS socket
+ option, which when disabled prohibits the peer from sending SCM_RIGHTS
+ ancillary messages (aka file descriptors) via AF_UNIX sockets. Defaults to
+ .
+
+
+
+
Timestamping=
Takes one of off, us (alias:
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index b07b3c93c5..de96f00a15 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -89,6 +89,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
SD_BUS_PROPERTY("PassPIDFD", "b", bus_property_get_bool, offsetof(Socket, pass_pidfd), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("AcceptFileDescriptors", "b", bus_property_get_bool, offsetof(Socket, pass_rights), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Timestamping", "s", property_get_timestamping, offsetof(Socket, timestamping), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -201,6 +202,9 @@ static int bus_socket_set_transient_property(
if (streq(name, "PassPacketInfo"))
return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error);
+ if (streq(name, "AcceptFileDescriptors"))
+ return bus_set_transient_bool(u, name, &s->pass_rights, message, flags, error);
+
if (streq(name, "Timestamping"))
return bus_set_transient_socket_timestamping(u, name, &s->timestamping, message, flags, error);
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
index e3c2333731..918228fea1 100644
--- a/src/core/load-fragment-gperf.gperf.in
+++ b/src/core/load-fragment-gperf.gperf.in
@@ -513,6 +513,7 @@ Socket.PassCredentials, config_parse_bool,
Socket.PassPIDFD, config_parse_bool, 0, offsetof(Socket, pass_pidfd)
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo)
+Socket.AcceptFileDescriptors, config_parse_bool, 0, offsetof(Socket, pass_rights)
Socket.Timestamping, config_parse_socket_timestamping, 0, offsetof(Socket, timestamping)
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port)
diff --git a/src/core/socket.c b/src/core/socket.c
index 6d69d6cb42..e5cff0de76 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -129,6 +129,7 @@ static void socket_init(Unit *u) {
s->max_connections = 64;
+ s->pass_rights = true; /* defaults to enabled in kernel */
s->priority = -1;
s->ip_tos = -1;
s->ip_ttl = -1;
@@ -613,6 +614,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sPassPIDFD: %s\n"
"%sPassSecurity: %s\n"
"%sPassPacketInfo: %s\n"
+ "%sAcceptFileDescriptors: %s\n"
"%sTCPCongestion: %s\n"
"%sRemoveOnStop: %s\n"
"%sWritable: %s\n"
@@ -635,6 +637,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(s->pass_pidfd),
prefix, yes_no(s->pass_sec),
prefix, yes_no(s->pass_pktinfo),
+ prefix, yes_no(s->pass_rights),
prefix, strna(s->tcp_congestion),
prefix, yes_no(s->remove_on_stop),
prefix, yes_no(s->writable),
@@ -1098,6 +1101,13 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
log_unit_warning_errno(UNIT(s), r, SOCKET_OPTION_WARNING_FORMAT_STR, "packet info");
}
+ if (!s->pass_rights) {
+ r = setsockopt_int(fd, SOL_SOCKET, SO_PASSRIGHTS, false);
+ if (r < 0)
+ log_unit_full_errno(UNIT(s), ERRNO_IS_NEG_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, r,
+ SOCKET_OPTION_WARNING_FORMAT_STR, "SO_PASSRIGHTS");
+ }
+
if (s->timestamping != SOCKET_TIMESTAMPING_OFF) {
r = setsockopt_int(fd, SOL_SOCKET,
s->timestamping == SOCKET_TIMESTAMPING_NS ? SO_TIMESTAMPNS : SO_TIMESTAMP,
diff --git a/src/core/socket.h b/src/core/socket.h
index 99fcc0cbe6..70291fb0d2 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -134,6 +134,7 @@ typedef struct Socket {
bool pass_pidfd;
bool pass_sec;
bool pass_pktinfo;
+ bool pass_rights;
SocketTimestamping timestamping;
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index aebeaa15ce..ce56defeac 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -2586,6 +2586,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
"PassPIDFD",
"PassSecurity",
"PassPacketInfo",
+ "AcceptFileDescriptors",
"ReusePort",
"RemoveOnStop",
"PassFileDescriptorsToExec",