core: Make DelegateNamespaces= work for user managers with CAP_SYS_ADMIN (#36771)

Currently DelegateNamespaces= only works for services spawned by the
system manager. User managers will always unshare the user namespace
first even if they're running with CAP_SYS_ADMIN.

Let's add support for DelegateNamespaces= for user managers if they're
running with CAP_SYS_ADMIN. By default, we'll still delegate all
namespaces
for user managers, but this can now be overridden by explicitly passing
DelegateNamespaces=.

If a user manager is running without CAP_SYS_ADMIN, the user manager is
still always unshared first just like before.
This commit is contained in:
Yu Watanabe
2025-03-20 06:28:18 +09:00
committed by GitHub
7 changed files with 92 additions and 56 deletions
+7 -3
View File
@@ -1669,13 +1669,17 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
if (STR_IN_SET(field, "RestrictNamespaces",
"DelegateNamespaces")) {
bool invert = false;
unsigned long all = UPDATE_FLAG(NAMESPACE_FLAGS_ALL, CLONE_NEWUSER, !streq(field, "DelegateNamespaces"));
unsigned long flags;
r = parse_boolean(eq);
if (r > 0)
flags = 0;
/* RestrictNamespaces= value gets stored into a field with reverse semantics (the
* namespaces which are retained), so RestrictNamespaces=true means we retain no
* access to any namespaces and vice-versa. */
flags = streq(field, "RestrictNamespaces") ? 0 : all;
else if (r == 0)
flags = NAMESPACE_FLAGS_ALL;
flags = streq(field, "RestrictNamespaces") ? all : 0;
else {
if (eq[0] == '~') {
invert = true;
@@ -1688,7 +1692,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
}
if (invert)
flags = (~flags) & NAMESPACE_FLAGS_ALL;
flags = (~flags) & all;
r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t) flags);
if (r < 0)