mirror of
https://github.com/systemd/systemd.git
synced 2025-01-18 10:04:04 +03:00
dissect: add new --shift command
This commit is contained in:
parent
f979247bb9
commit
7149009417
@ -62,6 +62,9 @@
|
||||
<cmdsynopsis>
|
||||
<command>systemd-dissect</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg>--validate</arg> <arg choice="plain"><replaceable>IMAGE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-dissect</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg>--shift</arg> <arg choice="plain"><replaceable>IMAGE</replaceable></arg> <arg choice="plain"><replaceable>UIDBASE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
@ -350,6 +353,27 @@
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--shift</option></term>
|
||||
|
||||
<listitem><para>Recursively iterates through all inodes of the specified image and shifts the UIDs
|
||||
and GIDs the inodes are owned by into the specified UID range. Takes an image path and a UID base as
|
||||
parameter. The UID base can be specified numerically (in which case it must be a multiple of 65536,
|
||||
and either 0 or within the container or foreign UID range, as per <ulink
|
||||
url="https://systemd.io/UIDS-GIDS/">Users, Groups, UIDs and GIDs on systemd Systems</ulink>), or as
|
||||
the symbolic identifier <literal>foreign</literal> which is shorthand to the foreign UID base. This
|
||||
command is useful for preparing directory container images for unprivileged use. Note that this
|
||||
command is intended for images that use the 16bit UIDs/GIDs range only, and it always ignores the
|
||||
upper 16bit of the current UID/GID ownership, combining the lower 16 bit with the target UID
|
||||
base.</para>
|
||||
|
||||
<para>Use <command>systemd-dissect --shift /some/container/tree foreign</command> to shift a
|
||||
container image into the foreign UID range, or <command>systemd-dissect --shift /some/container/tree
|
||||
0</command> to shift it to host UID range.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "process-util.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "sha256.h"
|
||||
#include "shift-uid.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@ -68,6 +69,7 @@ static enum {
|
||||
ACTION_DISCOVER,
|
||||
ACTION_VALIDATE,
|
||||
ACTION_MAKE_ARCHIVE,
|
||||
ACTION_SHIFT,
|
||||
} arg_action = ACTION_DISSECT;
|
||||
static char *arg_image = NULL;
|
||||
static char *arg_root = NULL;
|
||||
@ -96,6 +98,7 @@ static ImagePolicy *arg_image_policy = NULL;
|
||||
static bool arg_mtree_hash = true;
|
||||
static bool arg_via_service = false;
|
||||
static RuntimeScope arg_runtime_scope = _RUNTIME_SCOPE_INVALID;
|
||||
static uid_t arg_uid_base = UID_INVALID;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
@ -128,6 +131,7 @@ static int help(void) {
|
||||
"%1$s [OPTIONS...] --make-archive IMAGE [TARGET]\n"
|
||||
"%1$s [OPTIONS...] --discover\n"
|
||||
"%1$s [OPTIONS...] --validate IMAGE\n"
|
||||
"%1$s [OPTIONS...] --shift IMAGE UIDBASE\n"
|
||||
"\n%5$sDissect a Discoverable Disk Image (DDI).%6$s\n\n"
|
||||
"%3$sOptions:%4$s\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
@ -172,6 +176,7 @@ static int help(void) {
|
||||
" --make-archive Convert the DDI to an archive file\n"
|
||||
" --discover Discover DDIs in well known directories\n"
|
||||
" --validate Validate image and image policy\n"
|
||||
" --shift Shift UID range to selected base\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
@ -277,6 +282,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_VALIDATE,
|
||||
ARG_MTREE_HASH,
|
||||
ARG_MAKE_ARCHIVE,
|
||||
ARG_SHIFT,
|
||||
ARG_SYSTEM,
|
||||
ARG_USER,
|
||||
};
|
||||
@ -312,6 +318,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "validate", no_argument, NULL, ARG_VALIDATE },
|
||||
{ "mtree-hash", required_argument, NULL, ARG_MTREE_HASH },
|
||||
{ "make-archive", no_argument, NULL, ARG_MAKE_ARCHIVE },
|
||||
{ "shift", no_argument, NULL, ARG_SHIFT },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{}
|
||||
@ -546,6 +553,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_action = ACTION_MAKE_ARCHIVE;
|
||||
break;
|
||||
|
||||
case ARG_SHIFT:
|
||||
arg_action = ACTION_SHIFT;
|
||||
break;
|
||||
|
||||
case ARG_SYSTEM:
|
||||
system_scope_requested = true;
|
||||
break;
|
||||
@ -723,6 +734,33 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_flags &= ~(DISSECT_IMAGE_PIN_PARTITION_DEVICES|DISSECT_IMAGE_ADD_PARTITION_DEVICES);
|
||||
break;
|
||||
|
||||
case ACTION_SHIFT:
|
||||
if (optind + 2 != argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Expected an image path and a UID base as only argument.");
|
||||
|
||||
r = parse_image_path_argument(argv[optind], &arg_root, &arg_image);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(argv[optind + 1], "foreign"))
|
||||
arg_uid_base = FOREIGN_UID_BASE;
|
||||
else {
|
||||
r = parse_uid(argv[optind + 1], &arg_uid_base);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse UID base: %s", argv[optind + 1]);
|
||||
|
||||
if ((arg_uid_base & 0xFFFF) != 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Selected UID base not a multiple of 64K: " UID_FMT, arg_uid_base);
|
||||
if (arg_uid_base != 0 &&
|
||||
!uid_is_container(arg_uid_base) &&
|
||||
!uid_is_foreign(arg_uid_base))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Selected UID range is not in the container range, nor the foreign one, refusing.");
|
||||
}
|
||||
|
||||
arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
@ -1436,7 +1474,7 @@ static int action_list_or_mtree_or_copy_or_make_archive(DissectedImage *m, LoopD
|
||||
const char *root;
|
||||
int r;
|
||||
|
||||
assert(IN_SET(arg_action, ACTION_LIST, ACTION_MTREE, ACTION_COPY_FROM, ACTION_COPY_TO, ACTION_MAKE_ARCHIVE));
|
||||
assert(IN_SET(arg_action, ACTION_LIST, ACTION_MTREE, ACTION_COPY_FROM, ACTION_COPY_TO, ACTION_MAKE_ARCHIVE, ACTION_SHIFT));
|
||||
|
||||
if (arg_image) {
|
||||
assert(m);
|
||||
@ -1691,6 +1729,13 @@ static int action_list_or_mtree_or_copy_or_make_archive(DissectedImage *m, LoopD
|
||||
#endif
|
||||
}
|
||||
|
||||
case ACTION_SHIFT:
|
||||
r = path_patch_uid(root, arg_uid_base, 0x10000);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to shift UID base: %m");
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
@ -2100,7 +2145,7 @@ static int run(int argc, char *argv[]) {
|
||||
else
|
||||
r = loop_device_make_by_path(arg_image, open_flags, /* sector_size= */ UINT32_MAX, loop_flags, LOCK_SH, &d);
|
||||
if (r < 0) {
|
||||
if (!ERRNO_IS_PRIVILEGE(r) || !IN_SET(arg_action, ACTION_DISSECT, ACTION_LIST, ACTION_MTREE, ACTION_COPY_FROM, ACTION_COPY_TO))
|
||||
if (!ERRNO_IS_PRIVILEGE(r) || !IN_SET(arg_action, ACTION_DISSECT, ACTION_LIST, ACTION_MTREE, ACTION_COPY_FROM, ACTION_COPY_TO, ACTION_SHIFT))
|
||||
return log_error_errno(r, "Failed to set up loopback device for %s: %m", arg_image);
|
||||
|
||||
log_debug_errno(r, "Lacking permissions to set up loopback block device for %s, using service: %m", arg_image);
|
||||
@ -2185,6 +2230,7 @@ static int run(int argc, char *argv[]) {
|
||||
case ACTION_COPY_FROM:
|
||||
case ACTION_COPY_TO:
|
||||
case ACTION_MAKE_ARCHIVE:
|
||||
case ACTION_SHIFT:
|
||||
return action_list_or_mtree_or_copy_or_make_archive(m, d, userns_fd);
|
||||
|
||||
case ACTION_WITH:
|
||||
|
Loading…
x
Reference in New Issue
Block a user