If the special value <literal>all</literal> is passed, all capabilities are retained.</para>
<para>If the special value of <literal>help</literal> is passed, the program will print known
- capability names and exit.</para></listitem>
+ capability names and exit.</para>
+
+ <para>This option sets the bounding set of capabilities which
+ also limits the ambient capabilities as given with the
+ <option>--ambient-capability=</option>.</para></listitem>
</varlistentry>
<varlistentry>
above).</para>
<para>If the special value of <literal>help</literal> is passed, the program will print known
- capability names and exit.</para></listitem>
+ capability names and exit.</para>
+
+ <para>This option sets the bounding set of capabilities which
+ also limits the ambient capabilities as given with the
+ <option>--ambient-capability=</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--ambient-capability=</option></term>
+
+ <listitem><para>Specify one or more additional capabilities to
+ pass in the inheritable and ambient set to the program started
+ within the container. The value <literal>all</literal> is not
+ supported for this setting.</para>
+
+ <para>All capabilities specified here must be in the set
+ allowed with the <option>--capability=</option> and
+ <option>--drop-capability=</option> options. Otherwise, an
+ error message will be shown.</para>
+
+ <para>This option cannot be combined with the boot mode of the
+ container (as requested via <option>--boot</option>).</para>
+
+ <para>If the special value of <literal>help</literal> is
+ passed, the program will print known capability names and
+ exit.</para></listitem>
</varlistentry>
<varlistentry>
<filename>/run/system/nspawn/</filename> (see above). On the
other hand, <varname>DropCapability=</varname> takes effect in
all cases. If the special value <literal>all</literal> is passed, all
- capabilities are retained (or dropped).</para></listitem>
+ capabilities are retained (or dropped).</para>
+ <para>These settings change the bounding set of capabilities which
+ also limits the ambient capabilities as given with the
+ <varname>AmbientCapability=</varname>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AmbientCapability=</varname></term>
+ <listitem><para>Takes a space-separated list of Linux process
+ capabilities (see
+ <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ for details). The <varname>AmbientCapability=</varname> setting
+ specifies capability which will be passed to to started program
+ in the inheritable and ambient capability sets. This will grant
+ these capabilities to this process. This setting correspond to
+ the <option>--ambient-capability=</option> command line switch.
+ </para>
+
+ <para>The value <literal>all</literal> is not supported for this
+ setting.</para>
+
+ <para>The setting of <varname>AmbientCapability=</varname> must
+ be covered by the bounding set settings which were established by
+ <varname>Capability=</varname> and <varname>DropCapability=</varname>.
+ </para>
+
+ <para>Note that <varname>AmbientCapability=</varname> is a privileged
+ setting (see above).</para></listitem>
</varlistentry>
<varlistentry>
Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment)
Exec.User, config_parse_string, 0, offsetof(Settings, user)
Exec.Capability, config_parse_capability, 0, offsetof(Settings, capability)
+Exec.AmbientCapability, config_parse_capability, 0, offsetof(Settings, ambient_capability)
Exec.DropCapability, config_parse_capability, 0, offsetof(Settings, drop_capability)
Exec.KillSignal, config_parse_signal, 0, offsetof(Settings, kill_signal)
Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality)
(1ULL << CAP_SYS_PTRACE) |
(1ULL << CAP_SYS_RESOURCE) |
(1ULL << CAP_SYS_TTY_CONFIG);
+static uint64_t arg_caps_ambient = 0;
static CapabilityQuintet arg_full_capabilities = CAPABILITY_QUINTET_NULL;
static CustomMount *arg_custom_mounts = NULL;
static size_t arg_n_custom_mounts = 0;
" --capability=CAP In addition to the default, retain specified\n"
" capability\n"
" --drop-capability=CAP Drop the specified capability from the default set\n"
+ " --ambient-capability=CAP\n"
+ " Sets the specified capability for the started\n"
+ " process. Not useful if booting a machine.\n"
" --no-new-privileges Set PR_SET_NO_NEW_PRIVS flag for container payload\n"
" --system-call-filter=LIST|~LIST\n"
" Permit/prohibit specific system calls\n"
ARG_UUID,
ARG_READ_ONLY,
ARG_CAPABILITY,
+ ARG_AMBIENT_CAPABILITY,
ARG_DROP_CAPABILITY,
ARG_LINK_JOURNAL,
ARG_BIND,
{ "uuid", required_argument, NULL, ARG_UUID },
{ "read-only", no_argument, NULL, ARG_READ_ONLY },
{ "capability", required_argument, NULL, ARG_CAPABILITY },
+ { "ambient-capability", required_argument, NULL, ARG_AMBIENT_CAPABILITY },
{ "drop-capability", required_argument, NULL, ARG_DROP_CAPABILITY },
{ "no-new-privileges", required_argument, NULL, ARG_NO_NEW_PRIVILEGES },
{ "link-journal", required_argument, NULL, ARG_LINK_JOURNAL },
arg_settings_mask |= SETTING_READ_ONLY;
break;
+ case ARG_AMBIENT_CAPABILITY: {
+ uint64_t m;
+ r = parse_capability_spec(optarg, &m);
+ if (r <= 0)
+ return r;
+ arg_caps_ambient |= m;
+ arg_settings_mask |= SETTING_CAPABILITY;
+ break;
+ }
case ARG_CAPABILITY:
case ARG_DROP_CAPABILITY: {
uint64_t m;
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--port= is not supported, compiled without libiptc support.");
#endif
+ if (arg_caps_ambient) {
+ if (arg_caps_ambient == (uint64_t)-1)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "AmbientCapability= does not support the value all.");
+
+ if ((arg_caps_ambient & arg_caps_retain) != arg_caps_ambient)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "AmbientCapability= setting is not fully covered by Capability= setting.");
+
+ if (arg_start_mode == START_BOOT)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "AmbientCapability= setting is not useful for boot mode.");
+ }
+
r = custom_mount_check_all();
if (r < 0)
return r;
q.effective = uid == 0 ? q.bounding : 0;
if (q.inheritable == (uint64_t) -1)
- q.inheritable = uid == 0 ? q.bounding : 0;
+ q.inheritable = uid == 0 ? q.bounding : arg_caps_ambient;
if (q.permitted == (uint64_t) -1)
- q.permitted = uid == 0 ? q.bounding : 0;
+ q.permitted = uid == 0 ? q.bounding : arg_caps_ambient;
if (q.ambient == (uint64_t) -1 && ambient_capabilities_supported())
- q.ambient = 0;
+ q.ambient = arg_caps_ambient;
if (capability_quintet_mangle(&q))
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Cannot set capabilities that are not in the current bounding set.");
q = (CapabilityQuintet) {
.bounding = arg_caps_retain,
.effective = uid == 0 ? arg_caps_retain : 0,
- .inheritable = uid == 0 ? arg_caps_retain : 0,
- .permitted = uid == 0 ? arg_caps_retain : 0,
- .ambient = ambient_capabilities_supported() ? 0 : (uint64_t) -1,
+ .inheritable = uid == 0 ? arg_caps_retain : arg_caps_ambient,
+ .permitted = uid == 0 ? arg_caps_retain : arg_caps_ambient,
+ .ambient = ambient_capabilities_supported() ? arg_caps_ambient : (uint64_t) -1,
};
/* If we're not using OCI, proceed with mangled capabilities (so we don't error out)
if ((arg_settings_mask & SETTING_CAPABILITY) == 0) {
uint64_t plus, minus;
uint64_t network_minus = 0;
+ uint64_t ambient;
/* Note that we copy both the simple plus/minus caps here, and the full quintet from the
* Settings structure */
else
arg_full_capabilities = settings->full_capabilities;
}
+
+ ambient = settings->ambient_capability;
+ if (!arg_settings_trusted && ambient != 0)
+ log_warning("Ignoring AmbientCapability= setting, file %s is not trusted.", path);
+ else
+ arg_caps_ambient |= ambient;
}
if ((arg_settings_mask & SETTING_KILL_SIGNAL) == 0 &&