1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

nspawn: dump capability list with --capabilities=help

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-11-20 18:33:32 +01:00
parent 7f95bb22d3
commit 8a99bd0c46
2 changed files with 56 additions and 30 deletions

View File

@ -953,7 +953,10 @@
CAP_SETGID, CAP_SETPCAP, CAP_SETUID, CAP_SYS_ADMIN, CAP_SYS_BOOT, CAP_SYS_CHROOT,
CAP_SYS_NICE, CAP_SYS_PTRACE, CAP_SYS_RESOURCE, CAP_SYS_TTY_CONFIG. Also CAP_NET_ADMIN
is retained if <option>--private-network</option> is specified. If the special value
<literal>all</literal> is passed, all capabilities are retained.</para></listitem>
<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>
</varlistentry>
<varlistentry>
@ -962,7 +965,10 @@
<listitem><para>Specify one or more additional capabilities to
drop for the container. This allows running the container with
fewer capabilities than the default (see
above).</para></listitem>
above).</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>

View File

@ -492,6 +492,46 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) {
return 0;
}
static int parse_capability_spec(const char *spec, uint64_t *ret_mask) {
uint64_t mask = 0;
int r;
for (;;) {
_cleanup_free_ char *t = NULL;
r = extract_first_word(&spec, &t, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse capability %s.", t);
if (r == 0)
break;
if (streq(t, "help")) {
for (int i = 0; i < capability_list_length(); i++) {
const char *name;
name = capability_to_name(i);
if (name)
puts(name);
}
return 0; /* quit */
}
if (streq(t, "all"))
mask = (uint64_t) -1;
else {
r = capability_from_name(t);
if (r < 0)
return log_error_errno(r, "Failed to parse capability %s.", t);
mask |= 1ULL << r;
}
}
*ret_mask = mask;
return 1; /* continue */
}
static int parse_share_ns_env(const char *name, unsigned long ns_flag) {
int r;
@ -695,7 +735,6 @@ static int parse_argv(int argc, char *argv[]) {
};
int c, r;
const char *p;
uint64_t plus = 0, minus = 0;
bool mask_all_settings = false, mask_no_settings = false;
@ -937,37 +976,18 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_CAPABILITY:
case ARG_DROP_CAPABILITY: {
p = optarg;
for (;;) {
_cleanup_free_ char *t = NULL;
r = extract_first_word(&p, &t, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse capability %s.", t);
if (r == 0)
break;
if (streq(t, "all")) {
if (c == ARG_CAPABILITY)
plus = (uint64_t) -1;
else
minus = (uint64_t) -1;
} else {
r = capability_from_name(t);
if (r < 0)
return log_error_errno(r, "Failed to parse capability %s.", t);
if (c == ARG_CAPABILITY)
plus |= 1ULL << r;
else
minus |= 1ULL << r;
}
}
uint64_t m;
r = parse_capability_spec(optarg, &m);
if (r <= 0)
return r;
if (c == ARG_CAPABILITY)
plus |= m;
else
minus |= m;
arg_settings_mask |= SETTING_CAPABILITY;
break;
}
case ARG_NO_NEW_PRIVILEGES:
r = parse_boolean(optarg);
if (r < 0)