mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
nspawn/vmspawn: Add --bind-user-group= option
Useful to add the bound users to the wheel group.
This commit is contained in:
@@ -1667,6 +1667,19 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--bind-user-group=<replaceable>NAME</replaceable></option></term>
|
||||
|
||||
<listitem><para>When used with <option>--bind-user=</option>, includes the specified group as an
|
||||
auxiliary group in the user records of users bound into the container. Takes a group name.</para>
|
||||
|
||||
<para>Note: This will not check whether the specified groups exist in the container.</para>
|
||||
|
||||
<para>This operation is only supported in combination with <option>--bind-user=</option>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--inaccessible=</option></term>
|
||||
|
||||
|
||||
@@ -526,6 +526,20 @@
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--bind-user-group=<replaceable>NAME</replaceable></option></term>
|
||||
|
||||
<listitem><para>When used with <option>--bind-user=</option>, includes the specified group as an
|
||||
auxiliary group in the user records of users bound into the virtual machine. Takes a group name.</para>
|
||||
|
||||
<para>Note: This will not check whether the specified groups exist in the virtual machine.</para>
|
||||
|
||||
<para>This operation is only supported in combination with <option>--bind-user=</option>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@ static MachineCredentialContext arg_credentials = {};
|
||||
static char **arg_bind_user = NULL;
|
||||
static char *arg_bind_user_shell = NULL;
|
||||
static bool arg_bind_user_shell_copy = false;
|
||||
static char **arg_bind_user_groups = NULL;
|
||||
static bool arg_suppress_sync = false;
|
||||
static char *arg_settings_filename = NULL;
|
||||
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
|
||||
@@ -283,6 +284,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_cpu_set, cpu_set_done);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_sysctl, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user_shell, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user_groups, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_settings_filename, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_background, freep);
|
||||
@@ -429,6 +431,8 @@ static int help(void) {
|
||||
" --bind-user=NAME Bind user from host to container\n"
|
||||
" --bind-user-shell=BOOL|PATH\n"
|
||||
" Configure the shell to use for --bind-user= users\n"
|
||||
" --bind-user-group=GROUP\n"
|
||||
" Add an auxiliary group to --bind-user= users\n"
|
||||
"\n%3$sInput/Output:%4$s\n"
|
||||
" --console=MODE Select how stdin/stdout/stderr and /dev/console are\n"
|
||||
" set up for the container.\n"
|
||||
@@ -660,6 +664,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_LOAD_CREDENTIAL,
|
||||
ARG_BIND_USER,
|
||||
ARG_BIND_USER_SHELL,
|
||||
ARG_BIND_USER_GROUP,
|
||||
ARG_SUPPRESS_SYNC,
|
||||
ARG_IMAGE_POLICY,
|
||||
ARG_BACKGROUND,
|
||||
@@ -738,6 +743,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "load-credential", required_argument, NULL, ARG_LOAD_CREDENTIAL },
|
||||
{ "bind-user", required_argument, NULL, ARG_BIND_USER },
|
||||
{ "bind-user-shell", required_argument, NULL, ARG_BIND_USER_SHELL },
|
||||
{ "bind-user-group", required_argument, NULL, ARG_BIND_USER_GROUP },
|
||||
{ "suppress-sync", required_argument, NULL, ARG_SUPPRESS_SYNC },
|
||||
{ "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
|
||||
{ "background", required_argument, NULL, ARG_BACKGROUND },
|
||||
@@ -1514,6 +1520,15 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_BIND_USER_GROUP:
|
||||
if (!valid_user_group_name(optarg, /* flags= */ 0))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid bind user auxiliary group name: %s", optarg);
|
||||
|
||||
if (strv_extend(&arg_bind_user_groups, optarg) < 0)
|
||||
return log_oom();
|
||||
|
||||
break;
|
||||
|
||||
case ARG_SUPPRESS_SYNC:
|
||||
r = parse_boolean_argument("--suppress-sync=", optarg, &arg_suppress_sync);
|
||||
if (r < 0)
|
||||
@@ -1689,12 +1704,16 @@ static int verify_arguments(void) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "AmbientCapability= setting is not useful for boot mode.");
|
||||
}
|
||||
|
||||
/* Drop duplicate --bind-user= entries */
|
||||
/* Drop duplicate --bind-user= and --bind-user-group= entries */
|
||||
strv_uniq(arg_bind_user);
|
||||
strv_uniq(arg_bind_user_groups);
|
||||
|
||||
if (arg_bind_user_shell && strv_isempty(arg_bind_user))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --bind-user-shell= without --bind-user=");
|
||||
|
||||
if (!strv_isempty(arg_bind_user_groups) && strv_isempty(arg_bind_user))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --bind-user-group= without --bind-user=");
|
||||
|
||||
r = custom_mount_check_all();
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -4023,6 +4042,7 @@ static int outer_child(
|
||||
arg_bind_user_shell,
|
||||
arg_bind_user_shell_copy,
|
||||
"/run/host/home",
|
||||
arg_bind_user_groups,
|
||||
&bind_user_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -94,6 +94,7 @@ static int convert_user(
|
||||
const char *shell,
|
||||
bool shell_copy,
|
||||
const char *home_mount_directory,
|
||||
char **groups,
|
||||
UserRecord **ret_converted_user,
|
||||
GroupRecord **ret_converted_group) {
|
||||
|
||||
@@ -145,6 +146,7 @@ static int convert_user(
|
||||
SD_JSON_BUILD_PAIR("homeDirectory", SD_JSON_BUILD_STRING(h)),
|
||||
SD_JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.NSpawn")),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("shell", shell),
|
||||
SD_JSON_BUILD_PAIR_STRV("memberOf", groups),
|
||||
SD_JSON_BUILD_PAIR("privileged", SD_JSON_BUILD_OBJECT(
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!strv_isempty(u->hashed_password), "hashedPassword", SD_JSON_BUILD_VARIANT(hp)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!!ssh, "sshAuthorizedKeys", SD_JSON_BUILD_VARIANT(ssh))))));
|
||||
@@ -212,6 +214,7 @@ int machine_bind_user_prepare(
|
||||
const char *bind_user_shell,
|
||||
bool bind_user_shell_copy,
|
||||
const char *bind_user_home_mount_directory,
|
||||
char **bind_user_groups,
|
||||
MachineBindUserContext **ret) {
|
||||
|
||||
_cleanup_(machine_bind_user_context_freep) MachineBindUserContext *c = NULL;
|
||||
@@ -288,6 +291,7 @@ int machine_bind_user_prepare(
|
||||
bind_user_shell,
|
||||
bind_user_shell_copy,
|
||||
bind_user_home_mount_directory,
|
||||
bind_user_groups,
|
||||
&cu, &cg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -28,4 +28,5 @@ int machine_bind_user_prepare(
|
||||
const char *bind_user_shell,
|
||||
bool bind_user_shell_copy,
|
||||
const char *bind_user_home_mount_directory,
|
||||
char **bind_user_groups,
|
||||
MachineBindUserContext **ret);
|
||||
|
||||
@@ -143,6 +143,7 @@ static bool arg_notify_ready = true;
|
||||
static char **arg_bind_user = NULL;
|
||||
static char *arg_bind_user_shell = NULL;
|
||||
static bool arg_bind_user_shell_copy = false;
|
||||
static char **arg_bind_user_groups = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||
@@ -164,6 +165,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_tpm_state_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user_shell, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_bind_user_groups, strv_freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
@@ -227,6 +229,8 @@ static int help(void) {
|
||||
" --bind-user=NAME Bind user from host to virtual machine\n"
|
||||
" --bind-user-shell=BOOL|PATH\n"
|
||||
" Configure the shell to use for --bind-user= users\n"
|
||||
" --bind-user-group=GROUP\n"
|
||||
" Add an auxiliary group to --bind-user= users\n"
|
||||
"\n%3$sIntegration:%4$s\n"
|
||||
" --forward-journal=FILE|DIR\n"
|
||||
" Forward the VM's journal to the host\n"
|
||||
@@ -303,6 +307,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_NOTIFY_READY,
|
||||
ARG_BIND_USER,
|
||||
ARG_BIND_USER_SHELL,
|
||||
ARG_BIND_USER_GROUP,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -354,6 +359,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "notify-ready", required_argument, NULL, ARG_NOTIFY_READY },
|
||||
{ "bind-user", required_argument, NULL, ARG_BIND_USER },
|
||||
{ "bind-user-shell", required_argument, NULL, ARG_BIND_USER_SHELL },
|
||||
{ "bind-user-group", required_argument, NULL, ARG_BIND_USER_GROUP },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -715,6 +721,15 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_BIND_USER_GROUP:
|
||||
if (!valid_user_group_name(optarg, /* flags= */ 0))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid bind user auxiliary group name: %s", optarg);
|
||||
|
||||
if (strv_extend(&arg_bind_user_groups, optarg) < 0)
|
||||
return log_oom();
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@@ -722,12 +737,16 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
/* Drop duplicate --bind-user= entries */
|
||||
/* Drop duplicate --bind-user= and --bind-user-group= entries */
|
||||
strv_uniq(arg_bind_user);
|
||||
strv_uniq(arg_bind_user_groups);
|
||||
|
||||
if (arg_bind_user_shell && strv_isempty(arg_bind_user))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --bind-user-shell= without --bind-user=");
|
||||
|
||||
if (!strv_isempty(arg_bind_user_groups) && strv_isempty(arg_bind_user))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot use --bind-user-group= without --bind-user=");
|
||||
|
||||
if (argc > optind) {
|
||||
arg_kernel_cmdline_extra = strv_copy(argv + optind);
|
||||
if (!arg_kernel_cmdline_extra)
|
||||
@@ -1840,6 +1859,7 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
|
||||
arg_bind_user_shell,
|
||||
arg_bind_user_shell_copy,
|
||||
"/run/vmhost/home",
|
||||
arg_bind_user_groups,
|
||||
&bind_user_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user