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_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 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 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>
<varlistentry> <varlistentry>
@ -962,7 +965,10 @@
<listitem><para>Specify one or more additional capabilities to <listitem><para>Specify one or more additional capabilities to
drop for the container. This allows running the container with drop for the container. This allows running the container with
fewer capabilities than the default (see 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>
<varlistentry> <varlistentry>

View file

@ -492,6 +492,46 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) {
return 0; 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) { static int parse_share_ns_env(const char *name, unsigned long ns_flag) {
int r; int r;
@ -695,7 +735,6 @@ static int parse_argv(int argc, char *argv[]) {
}; };
int c, r; int c, r;
const char *p;
uint64_t plus = 0, minus = 0; uint64_t plus = 0, minus = 0;
bool mask_all_settings = false, mask_no_settings = false; 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_CAPABILITY:
case ARG_DROP_CAPABILITY: { case ARG_DROP_CAPABILITY: {
p = optarg; uint64_t m;
for (;;) { r = parse_capability_spec(optarg, &m);
_cleanup_free_ char *t = NULL; if (r <= 0)
return r;
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;
}
}
if (c == ARG_CAPABILITY)
plus |= m;
else
minus |= m;
arg_settings_mask |= SETTING_CAPABILITY; arg_settings_mask |= SETTING_CAPABILITY;
break; break;
} }
case ARG_NO_NEW_PRIVILEGES: case ARG_NO_NEW_PRIVILEGES:
r = parse_boolean(optarg); r = parse_boolean(optarg);
if (r < 0) if (r < 0)