From 06e78680e3c36589b785f90ecda64d124905a3f7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 12 Apr 2023 22:38:01 +0900 Subject: [PATCH] image-policy: introduce parse_image_policy_argument() helper Addresses https://github.com/systemd/systemd/pull/25608/commits/84be0c710d9d562f6d2cf986cc2a8ff4c98a138b#r1060130312, https://github.com/systemd/systemd/pull/25608/commits/84be0c710d9d562f6d2cf986cc2a8ff4c98a138b#r1067927293, and https://github.com/systemd/systemd/pull/25608/commits/84be0c710d9d562f6d2cf986cc2a8ff4c98a138b#r1067926416. Follow-up for 84be0c710d9d562f6d2cf986cc2a8ff4c98a138b. --- src/analyze/analyze.c | 22 +++---- src/boot/bootctl.c | 22 +++---- src/core/load-fragment-gperf.gperf.in | 1 + src/core/load-fragment.c | 39 ------------ src/core/load-fragment.h | 1 - src/coredump/coredumpctl.c | 22 +++---- src/dissect/dissect.c | 12 +--- src/firstboot/firstboot.c | 21 +++---- src/gpt-auto-generator/gpt-auto-generator.c | 16 +---- src/journal/journalctl.c | 21 +++---- src/machine-id-setup/machine-id-setup-main.c | 21 +++---- src/nspawn/nspawn.c | 12 +--- src/partition/repart.c | 22 +++---- src/shared/image-policy.c | 63 ++++++++++++++++++++ src/shared/image-policy.h | 4 ++ src/sysext/sysext.c | 13 ++-- src/systemctl/systemctl.c | 22 +++---- src/sysupdate/sysupdate.c | 21 +++---- src/sysusers/sysusers.c | 21 +++---- src/tmpfiles/tmpfiles.c | 21 +++---- 20 files changed, 168 insertions(+), 229 deletions(-) diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index ddc71b98b0..09a38e7930 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -292,6 +292,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_REQUIRE, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_SYSTEM, ARG_USER, ARG_GLOBAL, @@ -311,7 +312,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_PROFILE, ARG_TABLE, ARG_NO_LEGEND, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -322,6 +322,7 @@ static int parse_argv(int argc, char *argv[]) { { "require", no_argument, NULL, ARG_REQUIRE }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "recursive-errors", required_argument, NULL, ARG_RECURSIVE_ERRORS }, { "offline", required_argument, NULL, ARG_OFFLINE }, { "threshold", required_argument, NULL, ARG_THRESHOLD }, @@ -344,7 +345,6 @@ static int parse_argv(int argc, char *argv[]) { { "profile", required_argument, NULL, ARG_PROFILE }, { "table", optional_argument, NULL, ARG_TABLE }, { "no-legend", optional_argument, NULL, ARG_NO_LEGEND }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -390,6 +390,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_SYSTEM: arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; break; @@ -528,18 +534,6 @@ static int parse_argv(int argc, char *argv[]) { arg_legend = false; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } - case '?': return -EINVAL; diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index b9d034d550..0480e320c0 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -211,6 +211,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_BOOT_PATH, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_INSTALL_SOURCE, ARG_VERSION, ARG_NO_VARIABLES, @@ -222,7 +223,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_ARCH_ALL, ARG_EFI_BOOT_OPTION_DESCRIPTION, ARG_DRY_RUN, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -233,6 +233,7 @@ static int parse_argv(int argc, char *argv[]) { { "boot-path", required_argument, NULL, ARG_BOOT_PATH }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "install-source", required_argument, NULL, ARG_INSTALL_SOURCE }, { "print-esp-path", no_argument, NULL, 'p' }, { "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */ @@ -249,7 +250,6 @@ static int parse_argv(int argc, char *argv[]) { { "all-architectures", no_argument, NULL, ARG_ARCH_ALL }, { "efi-boot-option-description", required_argument, NULL, ARG_EFI_BOOT_OPTION_DESCRIPTION }, { "dry-run", no_argument, NULL, ARG_DRY_RUN }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -292,6 +292,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_INSTALL_SOURCE: if (streq(optarg, "auto")) arg_install_source = ARG_INSTALL_SOURCE_AUTO; @@ -382,18 +388,6 @@ static int parse_argv(int argc, char *argv[]) { arg_dry_run = true; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } - case '?': return -EINVAL; diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index ce0e2f0c5c..8a2823b075 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -263,6 +263,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include #include "all-units.h" #include "conf-parser.h" +#include "image-policy.h" #include "in-addr-prefix-util.h" #include "load-fragment.h" %} diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index cf0096263a..581a051d46 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1705,45 +1705,6 @@ int config_parse_root_image_options( return 0; } -int config_parse_image_policy( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(image_policy_freep) ImagePolicy *np = NULL; - ImagePolicy **p = ASSERT_PTR(data); - int r; - - assert(rvalue); - - if (isempty(rvalue)) { - *p = image_policy_free(*p); - return 0; - } - - r = image_policy_from_string(rvalue, &np); - if (r == -ENOTUNIQ) - return log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate rule in image policy, refusing: %s", rvalue); - if (r == -EBADSLT) - return log_syntax(unit, LOG_ERR, filename, line, r, "Unknown partition type in image policy, refusing: %s", rvalue); - if (r == -EBADRQC) - return log_syntax(unit, LOG_ERR, filename, line, r, "Unknown partition policy flag in image policy, refusing: %s", rvalue); - if (r < 0) - return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse image policy, refusing: %s", rvalue); - - image_policy_free(*p); - *p = TAKE_PTR(np); - - return 0; -} - int config_parse_exec_root_hash( const char *unit, const char *filename, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 98adf5ae05..a38d697338 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -52,7 +52,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity); CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_apivfs); CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits); CONFIG_PARSER_PROTOTYPE(config_parse_root_image_options); -CONFIG_PARSER_PROTOTYPE(config_parse_image_policy); CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash); CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash_sig); CONFIG_PARSER_PROTOTYPE(config_parse_capability_set); diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 076b35f098..bc52cc0b06 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -222,8 +222,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_FILE, ARG_ROOT, ARG_IMAGE, - ARG_ALL, ARG_IMAGE_POLICY, + ARG_ALL, }; int c, r; @@ -246,8 +246,8 @@ static int parse_argv(int argc, char *argv[]) { { "json", required_argument, NULL, ARG_JSON }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, - { "all", no_argument, NULL, ARG_ALL }, { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, + { "all", no_argument, NULL, ARG_ALL }, {} }; @@ -349,6 +349,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case 'r': arg_reverse = true; break; @@ -368,18 +374,6 @@ static int parse_argv(int argc, char *argv[]) { arg_all = true; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } - case '?': return -EINVAL; diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index b53c2cc357..ab9d796cf4 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -466,17 +466,11 @@ static int parse_argv(int argc, char *argv[]) { return r; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); + return r; break; - } case ARG_VALIDATE: arg_action = ACTION_VALIDATE; diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 7cd13a51e9..71b1e25c9d 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -1208,6 +1208,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_LOCALE, ARG_LOCALE_MESSAGES, ARG_KEYMAP, @@ -1237,7 +1238,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_DELETE_ROOT_PASSWORD, ARG_WELCOME, ARG_RESET, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -1245,6 +1245,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, { "keymap", required_argument, NULL, ARG_KEYMAP }, @@ -1274,7 +1275,6 @@ static int parse_argv(int argc, char *argv[]) { { "delete-root-password", no_argument, NULL, ARG_DELETE_ROOT_PASSWORD }, { "welcome", required_argument, NULL, ARG_WELCOME }, { "reset", no_argument, NULL, ARG_RESET }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -1305,6 +1305,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_LOCALE: r = free_and_strdup(&arg_locale, optarg); if (r < 0) @@ -1481,17 +1487,6 @@ static int parse_argv(int argc, char *argv[]) { arg_reset = true; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL; diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 09c63a31b2..33c215bcb5 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -888,20 +888,8 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat arg_root_rw = true; else if (proc_cmdline_key_streq(key, "ro") && !value) arg_root_rw = false; - else if (proc_cmdline_key_streq(key, "systemd.image_policy")) { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - if (proc_cmdline_value_missing(key, value)) - return 0; - - r = image_policy_from_string(value, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", value); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - return 0; - } + else if (proc_cmdline_key_streq(key, "systemd.image_policy")) + return parse_image_policy_argument(optarg, &arg_image_policy); return 0; } diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index abacbb0306..5c07caa8f3 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -418,6 +418,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_SYSTEM, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_HEADER, ARG_FACILITY, ARG_SETUP_KEYS, @@ -447,7 +448,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_HOSTNAME, ARG_OUTPUT_FIELDS, ARG_NAMESPACE, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -476,6 +476,7 @@ static int parse_argv(int argc, char *argv[]) { { "file", required_argument, NULL, ARG_FILE }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "header", no_argument, NULL, ARG_HEADER }, { "identifier", required_argument, NULL, 't' }, { "priority", required_argument, NULL, 'p' }, @@ -515,7 +516,6 @@ static int parse_argv(int argc, char *argv[]) { { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME }, { "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS }, { "namespace", required_argument, NULL, ARG_NAMESPACE }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -735,6 +735,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case 'c': arg_cursor = optarg; break; @@ -1038,17 +1044,6 @@ static int parse_argv(int argc, char *argv[]) { break; } - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL; diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c index c5b22d5d76..17012e20ac 100644 --- a/src/machine-id-setup/machine-id-setup-main.c +++ b/src/machine-id-setup/machine-id-setup-main.c @@ -60,9 +60,9 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_COMMIT, ARG_PRINT, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -70,9 +70,9 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "commit", no_argument, NULL, ARG_COMMIT }, { "print", no_argument, NULL, ARG_PRINT }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -103,6 +103,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_COMMIT: arg_commit = true; break; @@ -111,17 +117,6 @@ static int parse_argv(int argc, char *argv[]) { arg_print = true; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ff6a437573..bb3a04c9e4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1681,17 +1681,11 @@ static int parse_argv(int argc, char *argv[]) { arg_settings_mask |= SETTING_SUPPRESS_SYNC; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); + return r; break; - } case '?': return -EINVAL; diff --git a/src/partition/repart.c b/src/partition/repart.c index 0da07ee122..3a4808d6a4 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -5725,6 +5725,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_CAN_FACTORY_RESET, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_SEED, ARG_PRETTY, ARG_DEFINITIONS, @@ -5743,7 +5744,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_DEFER_PARTITIONS, ARG_SECTOR_SIZE, ARG_SKIP_PARTITIONS, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -5758,6 +5758,7 @@ static int parse_argv(int argc, char *argv[]) { { "can-factory-reset", no_argument, NULL, ARG_CAN_FACTORY_RESET }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "seed", required_argument, NULL, ARG_SEED }, { "pretty", required_argument, NULL, ARG_PRETTY }, { "definitions", required_argument, NULL, ARG_DEFINITIONS }, @@ -5775,7 +5776,6 @@ static int parse_argv(int argc, char *argv[]) { { "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS }, { "defer-partitions", required_argument, NULL, ARG_DEFER_PARTITIONS }, { "sector-size", required_argument, NULL, ARG_SECTOR_SIZE }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -5858,6 +5858,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_SEED: if (isempty(optarg)) { arg_seed = SD_ID128_NULL; @@ -6070,18 +6076,6 @@ static int parse_argv(int argc, char *argv[]) { break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } - case '?': return -EINVAL; diff --git a/src/shared/image-policy.c b/src/shared/image-policy.c index 8e27021b66..3c1f924a87 100644 --- a/src/shared/image-policy.c +++ b/src/shared/image-policy.c @@ -601,6 +601,69 @@ int image_policy_equivalent(const ImagePolicy *a, const ImagePolicy *b) { return true; } +int config_parse_image_policy( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(image_policy_freep) ImagePolicy *np = NULL; + ImagePolicy **p = ASSERT_PTR(data); + int r; + + assert(rvalue); + + if (isempty(rvalue)) { + *p = image_policy_free(*p); + return 0; + } + + r = image_policy_from_string(rvalue, &np); + if (r == -ENOTUNIQ) + return log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate rule in image policy, refusing: %s", rvalue); + if (r == -EBADSLT) + return log_syntax(unit, LOG_ERR, filename, line, r, "Unknown partition type in image policy, refusing: %s", rvalue); + if (r == -EBADRQC) + return log_syntax(unit, LOG_ERR, filename, line, r, "Unknown partition policy flag in image policy, refusing: %s", rvalue); + if (r < 0) + return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse image policy, refusing: %s", rvalue); + + return free_and_replace_full(*p, np, image_policy_free); +} + +int parse_image_policy_argument(const char *s, ImagePolicy **policy) { + _cleanup_(image_policy_freep) ImagePolicy *np = NULL; + int r; + + assert(s); + assert(policy); + + /* + * This function is intended to be used in command line parsers. + * + * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS! + * Hence, do not pass in uninitialized pointers. + */ + + r = image_policy_from_string(s, &np); + if (r == -ENOTUNIQ) + return log_error_errno(r, "Duplicate rule in image policy: %s", s); + if (r == -EBADSLT) + return log_error_errno(r, "Unknown partition type in image policy: %s", s); + if (r == -EBADRQC) + return log_error_errno(r, "Unknown partition policy flag in image policy: %s", s); + if (r < 0) + return log_error_errno(r, "Failed to parse image policy: %s", s); + + return free_and_replace_full(*policy, np, image_policy_free); +} + const ImagePolicy image_policy_allow = { /* Allow policy */ .n_policies = 0, diff --git a/src/shared/image-policy.h b/src/shared/image-policy.h index 848b24c147..1b3d068c72 100644 --- a/src/shared/image-policy.h +++ b/src/shared/image-policy.h @@ -3,6 +3,7 @@ typedef struct ImagePolicy ImagePolicy; +#include "conf-parser.h" #include "dissect-image.h" #include "errno-list.h" @@ -96,3 +97,6 @@ static inline ImagePolicy* image_policy_free(ImagePolicy *p) { } DEFINE_TRIVIAL_CLEANUP_FUNC(ImagePolicy*, image_policy_free); + +CONFIG_PARSER_PROTOTYPE(config_parse_image_policy); +int parse_image_policy_argument(const char *s, ImagePolicy **policy); diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index df4092fea9..e23785cc56 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -1023,17 +1023,12 @@ static int parse_argv(int argc, char *argv[]) { arg_force = true; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); + return r; break; - } + case '?': return -EINVAL; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 21e09536a6..201d64a1f9 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -428,6 +428,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_NO_WALL, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_NO_RELOAD, ARG_KILL_WHOM, ARG_KILL_VALUE, @@ -454,7 +455,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_NO_WARN, ARG_DROP_IN, ARG_WHEN, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -490,6 +490,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "no-warn", no_argument, NULL, ARG_NO_WARN }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "force", no_argument, NULL, 'f' }, { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, { "kill-whom", required_argument, NULL, ARG_KILL_WHOM }, @@ -520,7 +521,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "marked", no_argument, NULL, ARG_MARKED }, { "drop-in", required_argument, NULL, ARG_DROP_IN }, { "when", required_argument, NULL, ARG_WHEN }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -706,6 +706,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case 'l': arg_full = true; break; @@ -1010,18 +1016,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } - case '.': /* Output an error mimicking getopt, and print a hint afterwards */ log_error("%s: invalid option -- '.'", program_invocation_name); diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index f62e193056..29cd552ea8 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -1241,9 +1241,9 @@ static int parse_argv(int argc, char *argv[]) { ARG_JSON, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_REBOOT, ARG_VERIFY, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -1257,10 +1257,10 @@ static int parse_argv(int argc, char *argv[]) { { "json", required_argument, NULL, ARG_JSON }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "reboot", no_argument, NULL, ARG_REBOOT }, { "component", required_argument, NULL, 'C' }, { "verify", required_argument, NULL, ARG_VERIFY }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -1325,6 +1325,12 @@ static int parse_argv(int argc, char *argv[]) { return r; break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_REBOOT: arg_reboot = true; break; @@ -1358,17 +1364,6 @@ static int parse_argv(int argc, char *argv[]) { break; } - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL; diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index a2d62121e0..58246b5d85 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1985,11 +1985,11 @@ static int parse_argv(int argc, char *argv[]) { ARG_CAT_CONFIG, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_REPLACE, ARG_DRY_RUN, ARG_INLINE, ARG_NO_PAGER, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -1998,11 +1998,11 @@ static int parse_argv(int argc, char *argv[]) { { "cat-config", no_argument, NULL, ARG_CAT_CONFIG }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "replace", required_argument, NULL, ARG_REPLACE }, { "dry-run", no_argument, NULL, ARG_DRY_RUN }, { "inline", no_argument, NULL, ARG_INLINE }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -2042,6 +2042,12 @@ static int parse_argv(int argc, char *argv[]) { break; #endif + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_REPLACE: if (!path_is_absolute(optarg) || !endswith(optarg, ".conf")) @@ -2063,17 +2069,6 @@ static int parse_argv(int argc, char *argv[]) { arg_pager_flags |= PAGER_DISABLE; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index fdabd7d2c5..3adafcae83 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -3727,9 +3727,9 @@ static int parse_argv(int argc, char *argv[]) { ARG_EXCLUDE_PREFIX, ARG_ROOT, ARG_IMAGE, + ARG_IMAGE_POLICY, ARG_REPLACE, ARG_NO_PAGER, - ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -3745,9 +3745,9 @@ static int parse_argv(int argc, char *argv[]) { { "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "replace", required_argument, NULL, ARG_REPLACE }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -3825,6 +3825,12 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_IMAGE_POLICY: + r = parse_image_policy_argument(optarg, &arg_image_policy); + if (r < 0) + return r; + break; + case ARG_REPLACE: if (!path_is_absolute(optarg) || !endswith(optarg, ".conf")) @@ -3838,17 +3844,6 @@ static int parse_argv(int argc, char *argv[]) { arg_pager_flags |= PAGER_DISABLE; break; - case ARG_IMAGE_POLICY: { - _cleanup_(image_policy_freep) ImagePolicy *p = NULL; - - r = image_policy_from_string(optarg, &p); - if (r < 0) - return log_error_errno(r, "Failed to parse image policy: %s", optarg); - - image_policy_free(arg_image_policy); - arg_image_policy = TAKE_PTR(p); - break; - } case '?': return -EINVAL;