diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml index 87bc2b36eb..76ea0550d7 100644 --- a/man/systemd-mount.xml +++ b/man/systemd-mount.xml @@ -159,6 +159,14 @@ Additional mount options for the mount point. + + + + Let the specified user USER own the mounted file system. + This is done by appending and options to the list + of mount options. Only certain file systems support this option. + + diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 403f288b57..0fa0472ee1 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -28,6 +28,7 @@ #include "glob-util.h" #include "hexdecoct.h" #include "path-util.h" +#include "special.h" #include "string-util.h" #include "strv.h" #include "unit-name.h" @@ -673,7 +674,7 @@ int slice_build_parent_slice(const char *slice, char **ret) { if (!slice_name_is_valid(slice)) return -EINVAL; - if (streq(slice, "-.slice")) { + if (streq(slice, SPECIAL_ROOT_SLICE)) { *ret = NULL; return 0; } @@ -686,7 +687,7 @@ int slice_build_parent_slice(const char *slice, char **ret) { if (dash) strcpy(dash, ".slice"); else { - r = free_and_strdup(&s, "-.slice"); + r = free_and_strdup(&s, SPECIAL_ROOT_SLICE); if (r < 0) { free(s); return r; @@ -710,7 +711,7 @@ int slice_build_subslice(const char *slice, const char*name, char **ret) { if (!unit_prefix_is_valid(name)) return -EINVAL; - if (streq(slice, "-.slice")) + if (streq(slice, SPECIAL_ROOT_SLICE)) subslice = strappend(name, ".slice"); else { char *e; @@ -735,7 +736,7 @@ bool slice_name_is_valid(const char *name) { if (!unit_name_is_valid(name, UNIT_NAME_PLAIN)) return false; - if (streq(name, "-.slice")) + if (streq(name, SPECIAL_ROOT_SLICE)) return true; e = endswith(name, ".slice"); diff --git a/src/core/slice.c b/src/core/slice.c index 5ab1e6f898..fef47b04fe 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -59,30 +59,24 @@ static void slice_set_state(Slice *t, SliceState state) { } static int slice_add_parent_slice(Slice *s) { - char *a, *dash; - Unit *parent; + Unit *u = UNIT(s), *parent; + _cleanup_free_ char *a = NULL; int r; assert(s); - if (UNIT_ISSET(UNIT(s)->slice)) + if (UNIT_ISSET(u->slice)) return 0; - if (unit_has_name(UNIT(s), SPECIAL_ROOT_SLICE)) - return 0; + r = slice_build_parent_slice(u->id, &a); + if (r <= 0) /* 0 means root slice */ + return r; - a = strdupa(UNIT(s)->id); - dash = strrchr(a, '-'); - if (dash) - strcpy(dash, ".slice"); - else - a = (char*) SPECIAL_ROOT_SLICE; - - r = manager_load_unit(UNIT(s)->manager, a, NULL, NULL, &parent); + r = manager_load_unit(u->manager, a, NULL, NULL, &parent); if (r < 0) return r; - unit_ref_set(&UNIT(s)->slice, parent); + unit_ref_set(&u->slice, parent); return 0; } diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 7e61332e52..531edc6847 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -61,7 +61,7 @@ static int create_disk( const char *password, const char *options) { - _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL, + _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL, *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL; _cleanup_fclose_ FILE *f = NULL; const char *dmname; @@ -90,18 +90,14 @@ static int create_disk( if (!e) return log_oom(); - r = unit_name_build("systemd-cryptsetup", e, ".service", &n); - if (r < 0) - return log_error_errno(r, "Failed to generate unit name: %m"); - - p = strjoin(arg_dest, "/", n); - if (!p) - return log_oom(); - u = fstab_node_to_udev_node(device); if (!u) return log_oom(); + r = unit_name_build("systemd-cryptsetup", e, ".service", &n); + if (r < 0) + return log_error_errno(r, "Failed to generate unit name: %m"); + u_escaped = specifier_escape(u); if (!u_escaped) return log_oom(); @@ -114,14 +110,11 @@ static int create_disk( if (!password_escaped) return log_oom(); - f = fopen(p, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", p); - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(arg_dest, NULL, n, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-cryptsetup-generator\n\n" "[Unit]\n" "Description=Cryptography Setup for %%I\n" "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n" @@ -210,7 +203,7 @@ static int create_disk( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write file %s: %m", p); + return log_error_errno(r, "Failed to write unit file %s: %m", n); if (!noauto) { r = generator_add_symlink(arg_dest, d, "wants", n); diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 22c4ae9861..95bc5e38d5 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -102,7 +102,7 @@ static int add_swap( struct mntent *me, MountpointFlags flags) { - _cleanup_free_ char *name = NULL, *unit = NULL; + _cleanup_free_ char *name = NULL; _cleanup_fclose_ FILE *f = NULL; int r; @@ -123,19 +123,9 @@ static int add_swap( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - unit = strjoin(arg_dest, "/", name); - if (!unit) - return log_oom(); - - f = fopen(unit, "wxe"); - if (!f) - return log_error_errno(errno, - errno == EEXIST ? - "Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?" : - "Failed to create unit file %s: %m", - unit); - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f); + if (r < 0) + return r; fputs("# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" @@ -153,7 +143,7 @@ static int add_swap( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", unit); + return log_error_errno(r, "Failed to write unit file %s: %m", name); /* use what as where, to have a nicer error message */ r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL); @@ -323,10 +313,9 @@ static int add_mount( _cleanup_free_ char *name = NULL, - *automount_name = NULL, *automount_unit = NULL, + *automount_name = NULL, *filtered = NULL, *where_escaped = NULL; - const char *unit; _cleanup_fclose_ FILE *f = NULL; int r; @@ -363,20 +352,11 @@ static int add_mount( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - unit = strjoina(dest, "/", name); - - f = fopen(unit, "wxe"); - if (!f) - return log_error_errno(errno, - errno == EEXIST ? - "Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?" : - "Failed to create unit file %s: %m", - unit); - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(dest, "/etc/fstab", name, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", @@ -461,7 +441,7 @@ static int add_mount( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", unit); + return log_error_errno(r, "Failed to write unit file %s: %m", name); if (flags & MAKEFS) { r = generator_hook_up_mkfs(dest, what, where, fstype); @@ -487,19 +467,13 @@ static int add_mount( if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); - automount_unit = strjoin(dest, "/", automount_name); - if (!automount_unit) - return log_oom(); - fclose(f); - f = fopen(automount_unit, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit); - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-fstab-generator\n\n" "[Unit]\n" "SourcePath=%s\n" "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n", @@ -534,7 +508,7 @@ static int add_mount( r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit); + return log_error_errno(r, "Failed to write unit file %s: %m", automount_name); r = generator_add_symlink(dest, post, (flags & NOFAIL) ? "wants" : "requires", automount_name); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 94e250b94a..32b2045696 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -344,16 +344,13 @@ static int user_mkdir_runtime_path(User *u) { if (path_is_mount_point(u->runtime_path, NULL, 0) <= 0) { _cleanup_free_ char *t = NULL; - (void) mkdir_label(u->runtime_path, 0700); + r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu%s", + u->uid, u->gid, u->manager->runtime_dir_size, + mac_smack_use() ? ",smackfsroot=*" : ""); + if (r < 0) + return log_oom(); - if (mac_smack_use()) - r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size); - else - r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size); - if (r < 0) { - r = log_oom(); - goto fail; - } + (void) mkdir_label(u->runtime_path, 0700); r = mount("tmpfs", u->runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, t); if (r < 0) { @@ -461,7 +458,7 @@ int user_start(User *u) { u->stopping = false; if (!u->started) { - log_debug("New user %s logged in.", u->name); + log_debug("Starting services for new user %s.", u->name); /* Make XDG_RUNTIME_DIR */ r = user_mkdir_runtime_path(u); @@ -530,9 +527,7 @@ static int user_stop_service(User *u) { return r; } - free(u->service_job); - u->service_job = job; - + free_and_replace(u->service_job, job); return r; } diff --git a/src/machine/machined.c b/src/machine/machined.c index d481020893..b5cb863e5d 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -37,6 +37,7 @@ #include "machined.h" #include "process-util.h" #include "signal-util.h" +#include "special.h" Manager *manager_new(void) { Manager *m; @@ -112,7 +113,7 @@ static int manager_add_host_machine(Manager *m) { if (!rd) return log_oom(); - unit = strdup("-.slice"); + unit = strdup(SPECIAL_ROOT_SLICE); if (!unit) return log_oom(); diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index da3647e7e2..f82e9dac44 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -41,6 +41,7 @@ #include "strv.h" #include "udev-util.h" #include "unit-name.h" +#include "user-util.h" #include "terminal-util.h" enum { @@ -69,6 +70,8 @@ static usec_t arg_timeout_idle = USEC_INFINITY; static bool arg_timeout_idle_set = false; static char **arg_automount_property = NULL; static int arg_bind_device = -1; +static uid_t arg_uid = UID_INVALID; +static gid_t arg_gid = GID_INVALID; static bool arg_fsck = true; static bool arg_aggressive_gc = false; @@ -89,6 +92,7 @@ static void help(void) { " --discover Discover mount device metadata\n" " -t --type=TYPE File system type\n" " -o --options=OPTIONS Mount options\n" + " --owner=USER Add uid= and gid= options for USER\n" " --fsck=no Don't run file system check before mount\n" " --description=TEXT Description for unit\n" " -p --property=NAME=VALUE Set mount unit property\n" @@ -116,6 +120,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_DISCOVER, ARG_MOUNT_TYPE, ARG_MOUNT_OPTIONS, + ARG_OWNER, ARG_FSCK, ARG_DESCRIPTION, ARG_TIMEOUT_IDLE, @@ -139,6 +144,7 @@ static int parse_argv(int argc, char *argv[]) { { "discover", no_argument, NULL, ARG_DISCOVER }, { "type", required_argument, NULL, 't' }, { "options", required_argument, NULL, 'o' }, + { "owner", required_argument, NULL, ARG_OWNER }, { "fsck", required_argument, NULL, ARG_FSCK }, { "description", required_argument, NULL, ARG_DESCRIPTION }, { "property", required_argument, NULL, 'p' }, @@ -220,6 +226,18 @@ static int parse_argv(int argc, char *argv[]) { return log_oom(); break; + case ARG_OWNER: { + const char *user = optarg; + + r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL); + if (r < 0) + return log_error_errno(r, + r == -EBADMSG ? "UID or GID of user %s are invalid." + : "Cannot use \"%s\" as owner: %m", + optarg); + break; + } + case ARG_FSCK: r = parse_boolean(optarg); if (r < 0) @@ -422,6 +440,7 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) { } static int transient_mount_set_properties(sd_bus_message *m) { + _cleanup_free_ char *options = NULL; int r; assert(m); @@ -442,11 +461,24 @@ static int transient_mount_set_properties(sd_bus_message *m) { return r; } - if (arg_mount_options) { - r = sd_bus_message_append(m, "(sv)", "Options", "s", arg_mount_options); + /* Prepend uid=…,gid=… if arg_uid is set */ + if (arg_uid != UID_INVALID) { + r = asprintf(&options, + "uid=" UID_FMT ",gid=" GID_FMT "%s%s", + arg_uid, arg_gid, + arg_mount_options ? "," : "", arg_mount_options); + if (r < 0) + return -ENOMEM; + } + + if (options || arg_mount_options) { + log_debug("Using mount options: %s", options ?: arg_mount_options); + + r = sd_bus_message_append(m, "(sv)", "Options", "s", options ?: arg_mount_options); if (r < 0) return r; - } + } else + log_debug("Not using any mount options"); if (arg_fsck) { _cleanup_free_ char *fsck = NULL; @@ -1604,6 +1636,23 @@ int main(int argc, char* argv[]) { } } + /* The kernel (properly) refuses mounting file systems with unknown uid=,gid= options, + * but not for all filesystem types. Let's try to catch the cases where the option + * would be used if the file system does not support it. It is also possible to + * autodetect the file system, but that's only possible with disk-based file systems + * which incidentally seem to be implemented more carefully and reject unknown options, + * so it's probably OK that we do the check only when the type is specified. + */ + if (arg_mount_type && + !streq(arg_mount_type, "auto") && + arg_uid != UID_INVALID && + !fstype_can_uid_gid(arg_mount_type)) { + log_error("File system type %s is not known to support uid=/gid=, refusing.", + arg_mount_type); + r = -EOPNOTSUPP; + goto finish; + } + switch (arg_action) { case ACTION_MOUNT: diff --git a/src/shared/generator.c b/src/shared/generator.c index 3495a7ef7d..2b0a4ecdc8 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -19,6 +19,7 @@ ***/ #include +#include #include #include "alloc-util.h" @@ -39,6 +40,39 @@ #include "unit-name.h" #include "util.h" +int generator_open_unit_file( + const char *dest, + const char *source, + const char *name, + FILE **file) { + + const char *unit; + FILE *f; + + unit = strjoina(dest, "/", name); + + f = fopen(unit, "wxe"); + if (!f) { + if (source && errno == EEXIST) + return log_error_errno(errno, + "Failed to create unit file %s, as it already exists. Duplicate entry in %s?", + unit, source); + else + return log_error_errno(errno, + "Failed to create unit file %s: %m", + unit); + } + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fprintf(f, + "# Automatically generated by %s\n\n", + program_invocation_short_name); + + *file = f; + return 0; +} + int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src) { /* Adds a symlink from ..d/ to ../ */ diff --git a/src/shared/generator.h b/src/shared/generator.h index 32d1ad021c..e1c636a218 100644 --- a/src/shared/generator.h +++ b/src/shared/generator.h @@ -22,6 +22,12 @@ #include +int generator_open_unit_file( + const char *dest, + const char *source, + const char *name, + FILE **file); + int generator_add_symlink(const char *root, const char *dst, const char *dep_type, const char *src); int generator_write_fsck_deps( diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 45eb3ef8b1..2248a30635 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -27,6 +27,7 @@ #include "parse-util.h" #include "proc-cmdline.h" #include "process-util.h" +#include "special.h" #include "stat-util.h" #include "string-util.h" #include "test-helper.h" @@ -141,10 +142,10 @@ static void check_p_g_slice(const char *path, int code, const char *result) { static void test_path_get_slice(void) { check_p_g_slice("/user.slice", 0, "user.slice"); - check_p_g_slice("/foobar", 0, "-.slice"); + check_p_g_slice("/foobar", 0, SPECIAL_ROOT_SLICE); check_p_g_slice("/user.slice/user-waldo.slice", 0, "user-waldo.slice"); - check_p_g_slice("", 0, "-.slice"); - check_p_g_slice("foobar", 0, "-.slice"); + check_p_g_slice("", 0, SPECIAL_ROOT_SLICE); + check_p_g_slice("foobar", 0, SPECIAL_ROOT_SLICE); check_p_g_slice("foobar.slice", 0, "foobar.slice"); check_p_g_slice("foo.slice/foo-bar.slice/waldo.service", 0, "foo-bar.slice"); } @@ -165,10 +166,10 @@ static void test_path_get_user_slice(void) { check_p_g_u_slice("foobar.slice", -ENXIO, NULL); check_p_g_u_slice("foo.slice/foo-bar.slice/waldo.service", -ENXIO, NULL); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, "-.slice"); - check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, "-.slice"); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service///", 0, SPECIAL_ROOT_SLICE); + check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/waldo.service", 0, SPECIAL_ROOT_SLICE); check_p_g_u_slice("foo.slice/foo-bar.slice/user@1000.service/piep.slice/foo.service", 0, "piep.slice"); check_p_g_u_slice("/foo.slice//foo-bar.slice/user@1000.service/piep.slice//piep-pap.slice//foo.service", 0, "piep-pap.slice"); } @@ -274,7 +275,7 @@ static void test_slice_to_path(void) { test_slice_to_path_one("foobar.slice", "foobar.slice", 0); test_slice_to_path_one("foobar-waldo.slice", "foobar.slice/foobar-waldo.slice", 0); test_slice_to_path_one("foobar-waldo.service", NULL, -EINVAL); - test_slice_to_path_one("-.slice", "", 0); + test_slice_to_path_one(SPECIAL_ROOT_SLICE, "", 0); test_slice_to_path_one("--.slice", NULL, -EINVAL); test_slice_to_path_one("-", NULL, -EINVAL); test_slice_to_path_one("-foo-.slice", NULL, -EINVAL); diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index e24892b590..416542c83f 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -32,6 +32,7 @@ #include "manager.h" #include "path-util.h" #include "rm-rf.h" +#include "special.h" #include "specifier.h" #include "string-util.h" #include "test-helper.h" @@ -338,7 +339,7 @@ static void test_unit_name_build(void) { } static void test_slice_name_is_valid(void) { - assert_se(slice_name_is_valid("-.slice")); + assert_se(slice_name_is_valid(SPECIAL_ROOT_SLICE)); assert_se(slice_name_is_valid("foo.slice")); assert_se(slice_name_is_valid("foo-bar.slice")); assert_se(slice_name_is_valid("foo-bar-baz.slice")); @@ -356,7 +357,7 @@ static void test_build_subslice(void) { char *a; char *b; - assert_se(slice_build_subslice("-.slice", "foo", &a) >= 0); + assert_se(slice_build_subslice(SPECIAL_ROOT_SLICE, "foo", &a) >= 0); assert_se(slice_build_subslice(a, "bar", &b) >= 0); free(a); assert_se(slice_build_subslice(b, "barfoo", &a) >= 0); @@ -378,8 +379,8 @@ static void test_build_parent_slice_one(const char *name, const char *expect, in } static void test_build_parent_slice(void) { - test_build_parent_slice_one("-.slice", NULL, 0); - test_build_parent_slice_one("foo.slice", "-.slice", 1); + test_build_parent_slice_one(SPECIAL_ROOT_SLICE, NULL, 0); + test_build_parent_slice_one("foo.slice", SPECIAL_ROOT_SLICE, 1); test_build_parent_slice_one("foo-bar.slice", "foo.slice", 1); test_build_parent_slice_one("foo-bar-baz.slice", "foo-bar.slice", 1); test_build_parent_slice_one("foo-bar--baz.slice", NULL, -EINVAL); diff --git a/src/veritysetup/veritysetup-generator.c b/src/veritysetup/veritysetup-generator.c index 5919b1380e..c29c6f0bb3 100644 --- a/src/veritysetup/veritysetup-generator.c +++ b/src/veritysetup/veritysetup-generator.c @@ -27,6 +27,7 @@ #include "fd-util.h" #include "fileio.h" #include "fstab-util.h" +#include "generator.h" #include "hexdecoct.h" #include "id128-util.h" #include "mkdir.h" @@ -36,6 +37,8 @@ #include "string-util.h" #include "unit-name.h" +#define SYSTEMD_VERITYSETUP_SERVICE "systemd-veritysetup@root.service" + static char *arg_dest = NULL; static bool arg_enabled = true; static char *arg_root_hash = NULL; @@ -45,7 +48,7 @@ static char *arg_hash_what = NULL; static int create_device(void) { _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL; _cleanup_fclose_ FILE *f = NULL; - const char *p, *to; + const char *to; int r; /* If all three pieces of information are missing, then verity is turned off */ @@ -67,8 +70,6 @@ static int create_device(void) { " hash device %s,\n" " and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash); - p = strjoina(arg_dest, "/systemd-veritysetup@root.service"); - u = fstab_node_to_udev_node(arg_data_what); if (!u) return log_oom(); @@ -94,12 +95,11 @@ static int create_device(void) { if (!root_hash_escaped) return log_oom(); - f = fopen(p, "wxe"); - if (!f) - return log_error_errno(errno, "Failed to create unit file %s: %m", p); + r = generator_open_unit_file(arg_dest, NULL, SYSTEMD_VERITYSETUP_SERVICE, &f); + if (r < 0) + return r; fprintf(f, - "# Automatically generated by systemd-veritysetup-generator\n\n" "[Unit]\n" "Description=Integrity Protection Setup for %%I\n" "Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n" @@ -121,12 +121,12 @@ static int create_device(void) { r = fflush_and_check(f); if (r < 0) - return log_error_errno(r, "Failed to write file %s: %m", p); + return log_error_errno(r, "Failed to write file unit "SYSTEMD_VERITYSETUP_SERVICE": %m"); - to = strjoina(arg_dest, "/cryptsetup.target.requires/systemd-veritysetup@root.service"); + to = strjoina(arg_dest, "/cryptsetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE); (void) mkdir_parents(to, 0755); - if (symlink("../systemd-veritysetup@root.service", to) < 0) + if (symlink("../" SYSTEMD_VERITYSETUP_SERVICE, to) < 0) return log_error_errno(errno, "Failed to create symlink %s: %m", to); return 0;