diff --git a/man/portablectl.xml b/man/portablectl.xml index d7366376d9..190fefa97b 100644 --- a/man/portablectl.xml +++ b/man/portablectl.xml @@ -320,7 +320,8 @@ When attaching an image, select the profile to use. By default, the default - profile is used. For details about profiles, see below. + profile is used. Attaching fails if the selected profile does not exist. For details about profiles, see + below. diff --git a/src/portable/portable.c b/src/portable/portable.c index 8f1e7f22cf..98f15a7be4 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -41,6 +41,7 @@ #include "nsresource.h" #include "os-util.h" #include "path-lookup.h" +#include "path-util.h" #include "pidref.h" #include "portable.h" #include "portable-util.h" @@ -2055,6 +2056,10 @@ int portable_attach( assert(scope < _RUNTIME_SCOPE_MAX); + r = portable_profile_validate(scope, profile, error); + if (r < 0) + return r; + r = extract_image_and_extensions( scope, name_or_path, @@ -2660,6 +2665,36 @@ int portable_get_profiles(RuntimeScope scope, char ***ret) { return conf_files_list_strv(ret, NULL, NULL, CONF_FILES_DIRECTORY|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED, (const char* const*) dirs); } +int portable_profile_validate(RuntimeScope scope, const char *profile, sd_bus_error *reterr_error) { + _cleanup_strv_free_ char **profiles = NULL; + int r; + + assert(scope < _RUNTIME_SCOPE_MAX); + + if (!filename_is_valid(profile)) + return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_INVALID_ARGS, "Profile name '%s' is not valid.", profile); + + r = portable_get_profiles(scope, &profiles); + if (r < 0) + return sd_bus_error_set_errnof(reterr_error, r, "Failed to enumerate portable profiles: %m"); + + if (strv_contains(profiles, profile)) + return 0; + + _cleanup_free_ char *joined = strv_join(profiles, ", "); + if (!joined) + return -ENOMEM; + + return sd_bus_error_setf( + reterr_error, + SD_BUS_ERROR_INVALID_ARGS, + "Profile '%s' does not exist, refusing.%s%s%s", + profile, + isempty(joined) ? "" : " (Available profiles are: ", + strempty(joined), + isempty(joined) ? "" : ")"); +} + static const char* const portable_change_type_table[_PORTABLE_CHANGE_TYPE_MAX] = { [PORTABLE_COPY] = "copy", [PORTABLE_MKDIR] = "mkdir", diff --git a/src/portable/portable.h b/src/portable/portable.h index 597f0f1468..1711618f42 100644 --- a/src/portable/portable.h +++ b/src/portable/portable.h @@ -111,6 +111,7 @@ int portable_get_state( sd_bus_error *error); int portable_get_profiles(RuntimeScope scope, char ***ret); +int portable_profile_validate(RuntimeScope scope, const char *profile, sd_bus_error *reterr_error); void portable_changes_free(PortableChange *array, size_t n); diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c index 5517ea10a1..5a5393e986 100644 --- a/src/portable/portabled-image-bus.c +++ b/src/portable/portabled-image-bus.c @@ -714,6 +714,11 @@ int bus_image_common_reattach( if (r == 0) /* Will call us back */ return 1; + /* portable_attach() checks this too, but by then the image is detached already. */ + r = portable_profile_validate(m->runtime_scope, profile, error); + if (r < 0) + return r; + r = portable_detach( m->runtime_scope, sd_bus_message_get_bus(message),