portable: Enable unpriv operation

This does not yet support directory images properly
as systemd itself does not support unpriv directory
images properly yet.

The user profiles are a copy of the system profiles but without
DynamicUser=yes (can't be used by user managers) and without
ProtectHome=yes (this masks /home which breaks StateDirectory= which
is lcoated inside /home)
This commit is contained in:
Daan De Meyer
2026-01-21 15:09:46 +01:00
parent 1a239eae8e
commit 824fcb95c9
34 changed files with 1009 additions and 215 deletions
+2 -2
View File
@@ -663,7 +663,7 @@ static int pick_image_search_path(
}
case RUNTIME_SCOPE_USER: {
if (class != IMAGE_MACHINE)
if (!IN_SET(class, IMAGE_MACHINE, IMAGE_PORTABLE))
break;
static const uint64_t dirs[] = {
@@ -676,7 +676,7 @@ static int pick_image_search_path(
FOREACH_ELEMENT(d, dirs) {
_cleanup_free_ char *p = NULL;
r = sd_path_lookup(*d, "machines", &p);
r = sd_path_lookup(*d, image_dirname_to_string(class), &p);
if (r == -ENXIO) /* No XDG_RUNTIME_DIR set */
continue;
if (r < 0)
+1 -1
View File
@@ -4512,7 +4512,7 @@ Architecture dissected_image_architecture(DissectedImage *m) {
}
bool dissected_image_is_portable(DissectedImage *m) {
return m && strv_env_pairs_get(m->os_release, "PORTABLE_PREFIXES");
return m && (strv_env_pairs_get(m->os_release, "PORTABLE_PREFIXES") || strv_env_pairs_get(m->os_release, "PORTABLE_SCOPE"));
}
bool dissected_image_is_initrd(DissectedImage *m) {
+67 -3
View File
@@ -5,10 +5,70 @@
#include "alloc-util.h"
#include "fs-util.h"
#include "nulstr-util.h"
#include "path-lookup.h"
#include "portable-util.h"
#include "string-util.h"
#include "strv.h"
int find_portable_profile(const char *name, const char *unit, char **ret_path) {
int portable_profile_dirs(RuntimeScope scope, char ***ret) {
_cleanup_strv_free_ char **dirs = NULL;
int r;
assert(ret);
switch (scope) {
case RUNTIME_SCOPE_SYSTEM:
r = strv_from_nulstr(&dirs, PORTABLE_PROFILE_DIRS);
if (r < 0)
return r;
break;
case RUNTIME_SCOPE_USER: {
_cleanup_free_ char *d = NULL;
r = xdg_user_config_dir("systemd/portable/profile", &d);
if (r < 0 && r != -ENXIO)
return r;
if (r >= 0) {
r = strv_consume(&dirs, TAKE_PTR(d));
if (r < 0)
return r;
}
r = xdg_user_runtime_dir("systemd/portable/profile", &d);
if (r < 0 && r != -ENXIO)
return r;
if (r >= 0) {
r = strv_consume(&dirs, TAKE_PTR(d));
if (r < 0)
return r;
}
_fallthrough_;
}
case RUNTIME_SCOPE_GLOBAL:
r = strv_extend_strv(
&dirs,
CONF_PATHS_STRV("systemd/user/portable/profile"),
/* filter_duplicates= */ false);
if (r < 0)
return r;
break;
default:
return -EINVAL;
}
*ret = TAKE_PTR(dirs);
return 0;
}
int find_portable_profile(RuntimeScope scope, const char *name, const char *unit, char **ret_path) {
_cleanup_strv_free_ char **dirs = NULL;
const char *dot;
int r;
@@ -17,10 +77,14 @@ int find_portable_profile(const char *name, const char *unit, char **ret_path) {
assert_se(dot = strrchr(unit, '.'));
NULSTR_FOREACH(p, PORTABLE_PROFILE_DIRS) {
r = portable_profile_dirs(scope, &dirs);
if (r < 0)
return r;
STRV_FOREACH(p, dirs) {
_cleanup_free_ char *joined = NULL;
joined = strjoin(p, "/", name, "/", dot + 1, ".conf");
joined = strjoin(*p, "/", name, "/", dot + 1, ".conf");
if (!joined)
return -ENOMEM;
+2 -1
View File
@@ -6,4 +6,5 @@
#define PORTABLE_PROFILE_DIRS CONF_PATHS_NULSTR("systemd/portable/profile")
int find_portable_profile(const char *name, const char *unit, char **ret_path);
int portable_profile_dirs(RuntimeScope scope, char ***ret);
int find_portable_profile(RuntimeScope scope, const char *name, const char *unit, char **ret_path);