/test-bus-zero-copy
/test-calendarspec
/test-capability
+/test-cap-list
/test-catalog
/test-cgroup
/test-cgroup-mask
src/shared/af-list.h \
src/shared/arphrd-list.c \
src/shared/arphrd-list.h \
+ src/shared/cap-list.c \
+ src/shared/cap-list.h \
src/shared/audit.c \
src/shared/audit.h \
src/shared/xml.c \
src/shared/af-from-name.h \
src/shared/af-to-name.h \
src/shared/arphrd-from-name.h \
- src/shared/arphrd-to-name.h
+ src/shared/arphrd-to-name.h \
+ src/shared/cap-from-name.h \
+ src/shared/cap-to-name.h
libsystemd_shared_la_CFLAGS = \
$(AM_CFLAGS) \
src/shared/af-from-name.gperf \
src/shared/arphrd-list.txt \
src/shared/arphrd-from-name.gperf \
+ src/shared/cap-list.txt \
+ src/shared/cap-from-name.gperf \
src/resolve/dns_type-list.txt \
src/resolve/dns_type-from-name.gperf
src/shared/af-to-name.h \
src/shared/arphrd-from-name.h \
src/shared/arphrd-to-name.h \
+ src/shared/cap-from-name.h \
+ src/shared/cap-to-name.h \
src/resolve/dns_type-from-name.h \
src/resolve/dns_type-to-name.h
src/shared/af-to-name.h: src/shared/af-list.txt
$(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const af_names[] = { "} !/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
+
src/shared/arphrd-list.txt:
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include net/if_arp.h - </dev/null | $(AWK) '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $$2; }' | sed -e 's/ARPHRD_//' >$@
$(AM_V_GEN)$(AWK) 'BEGIN{ print "struct arphrd_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, ARPHRD_%s\n", $$1, $$1 }' <$< >$@
+src/shared/cap-list.txt:
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/capability.h -include missing.h - </dev/null | $(AWK) '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $$2; }' | grep -v CAP_LAST_CAP >$@
+
+src/shared/cap-to-name.h: src/shared/cap-list.txt
+ $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const capability_names[] = { "} { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
+
+src/shared/cap-from-name.gperf: src/shared/cap-list.txt
+ $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct capability_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, %s\n", $$1, $$1 }' <$< >$@
+
+src/shared/cap-from-name.h: src/shared/cap-from-name.gperf
+ $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_capability -H hash_capability_name -p -C <$< >$@
+
+
src/resolve/dns_type-list.txt: src/resolve/dns-type.h
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)$(SED) -n -r 's/.* DNS_TYPE_(\w+).*/\1/p' <$< >$@
test-bus-policy \
test-locale-util \
test-execute \
- test-copy
+ test-copy \
+ test-cap-list
EXTRA_DIST += \
test/a.service \
test_uid_range_LDADD = \
libsystemd-shared.la
+test_cap_list_SOURCES = \
+ src/test/test-cap-list.c
+
+test_cap_list_LDADD = \
+ libsystemd-shared.la
+
test_socket_util_SOURCES = \
src/test/test-socket-util.c
#include "smack-util.h"
#include "bus-kernel.h"
#include "label.h"
+#include "cap-list.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
fprintf(f, "%sCapabilityBoundingSet:", prefix);
for (l = 0; l <= cap_last_cap(); l++)
- if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
- _cleanup_cap_free_charp_ char *t;
-
- t = cap_to_name(l);
- if (t)
- fprintf(f, " %s", t);
- }
+ if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l)))
+ fprintf(f, " %s", strna(capability_to_name(l)));
fputs("\n", f);
}
#include "bus-error.h"
#include "errno-list.h"
#include "af-list.h"
+#include "cap-list.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
FOREACH_WORD_QUOTED(word, l, rvalue, state) {
_cleanup_free_ char *t = NULL;
- int r;
- cap_value_t cap;
+ int cap;
t = strndup(word, l);
if (!t)
return log_oom();
- r = cap_from_name(t, &cap);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, errno,
- "Failed to parse capability in bounding set, ignoring: %s", t);
+ cap = capability_from_name(t);
+ if (cap < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse capability in bounding set, ignoring: %s", t);
continue;
}
#include "strv.h"
#include "audit.h"
#include "macro.h"
+#include "cap-list.h"
#include "bus-message.h"
#include "bus-internal.h"
for (;;) {
if (r > 0) {
- _cleanup_cap_free_charp_ char *t;
if (n > 0)
fputc(' ', f);
if (n % 4 == 3)
fprintf(f, terse ? "\n " : "\n ");
- t = cap_to_name(i);
- fprintf(f, "%s", t);
+ fprintf(f, "%s", strna(capability_to_name(i)));
n++;
}
#include "base-filesystem.h"
#include "barrier.h"
#include "event-util.h"
+#include "cap-list.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) {
_cleanup_free_ char *t;
- cap_value_t cap;
t = strndup(word, length);
if (!t)
else
minus = (uint64_t) -1;
} else {
- if (cap_from_name(t, &cap) < 0) {
+ int cap;
+
+ cap = capability_from_name(t);
+ if (cap < 0) {
log_error("Failed to parse capability %s.", t);
return -EINVAL;
}
+/cap-from-name.gperf
+/cap-from-name.h
+/cap-list.txt
+/cap-to-name.h
/errno-from-name.gperf
/errno-from-name.h
/errno-list.txt
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <linux/capability.h>
+#include <string.h>
+
+#include "util.h"
+#include "cap-list.h"
+#include "missing.h"
+
+static const struct capability_name* lookup_capability(register const char *str, register unsigned int len);
+
+#include "cap-to-name.h"
+#include "cap-from-name.h"
+
+const char *capability_to_name(int id) {
+
+ if (id < 0)
+ return NULL;
+
+ if (id >= (int) ELEMENTSOF(capability_names))
+ return NULL;
+
+ return capability_names[id];
+}
+
+int capability_from_name(const char *name) {
+ const struct capability_name *sc;
+ int r, i;
+
+ assert(name);
+
+ /* Try to parse numeric capability */
+ r = safe_atoi(name, &i);
+ if (r >= 0 && i >= 0)
+ return i;
+
+ /* Try to parse string capability */
+ sc = lookup_capability(name, strlen(name));
+ if (!sc)
+ return -EINVAL;
+
+ return sc->id;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+const char *capability_to_name(int id);
+int capability_from_name(const char *name);
#include "selinux-util.h"
#include "audit.h"
#include "condition.h"
+#include "cap-list.h"
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
Condition *c;
static int condition_test_capability(Condition *c) {
_cleanup_fclose_ FILE *f = NULL;
- cap_value_t value;
+ int value;
char line[LINE_MAX];
unsigned long long capabilities = -1;
assert(c->type == CONDITION_CAPABILITY);
/* If it's an invalid capability, we don't have it */
-
- if (cap_from_name(c->parameter, &value) < 0)
+ value = capability_from_name(c->parameter);
+ if (value < 0)
return -EINVAL;
/* If it's a valid capability we default to assume
#include <linux/if_link.h>
#include <linux/loop.h>
#include <linux/audit.h>
+#include <linux/capability.h>
#ifdef HAVE_AUDIT
#include <libaudit.h>
#ifndef AUDIT_NLGRP_MAX
#define AUDIT_NLGRP_READLOG 1
#endif
+
+#ifndef CAP_MAC_OVERRIDE
+#define CAP_MAC_OVERRIDE 32
+#endif
+
+#ifndef CAP_MAC_ADMIN
+#define CAP_MAC_ADMIN 33
+#endif
+
+#ifndef CAP_SYSLOG
+#define CAP_SYSLOG 34
+#endif
+
+#ifndef CAP_WAKE_ALARM
+#define CAP_WAKE_ALARM 35
+#endif
+
+#ifndef CAP_BLOCK_SUSPEND
+#define CAP_BLOCK_SUSPEND 36
+#endif
+
+#ifndef CAP_AUDIT_READ
+#define CAP_AUDIT_READ 37
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "log.h"
+#include "cap-list.h"
+#include "capability.h"
+
+int main(int argc, char *argv[]) {
+ int i;
+
+ assert_se(!capability_to_name(-1));
+ assert_se(!capability_to_name(cap_last_cap()+1));
+
+ for (i = 0; i <= (int) cap_last_cap(); i++) {
+ const char *n;
+
+ assert_se(n = capability_to_name(i));
+ assert_se(capability_from_name(n) == i);
+ printf("%s = %i\n", n, i);
+ }
+
+ assert_se(capability_from_name("asdfbsd") == -EINVAL);
+ assert_se(capability_from_name("CAP_AUDIT_READ") == CAP_AUDIT_READ);
+ assert_se(capability_from_name("0") == 0);
+ assert_se(capability_from_name("15") == 15);
+ assert_se(capability_from_name("-1") == -EINVAL);
+
+ return 0;
+}