summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c53
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c25
-rw-r--r--src/libsystemd/sd-bus/bus-util.c24
-rw-r--r--src/libsystemd/sd-bus/bus-util.h4
-rw-r--r--src/libsystemd/sd-network/sd-network.c24
5 files changed, 89 insertions, 41 deletions
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index c5b9cd4caa..f88836b884 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -472,3 +472,56 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
return bus_creds_extend_by_pid(c, mask, creds);
}
+
+_public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
+ _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+ uid_t our_uid;
+ int r;
+
+ assert_return(call, -EINVAL);
+ assert_return(call->sealed, -EPERM);
+ assert_return(call->bus, -EINVAL);
+ assert_return(!bus_pid_changed(call->bus), -ECHILD);
+
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
+ /* We only trust the effective capability set if this is
+ * kdbus. On classic dbus1 we cannot retrieve the value
+ * without races. Since this function is supposed to be useful
+ * for authentication decision we hence avoid requesting and
+ * using that information. */
+ if (call->bus->is_kernel && capability >= 0) {
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_creds_has_effective_cap(creds, capability);
+ if (r > 0)
+ return 1;
+ } else {
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds);
+ if (r < 0)
+ return r;
+ }
+
+ /* Now, check the UID, but only if the capability check wasn't
+ * sufficient */
+ our_uid = getuid();
+ if (our_uid != 0 || !call->bus->is_kernel || capability < 0) {
+ uid_t sender_uid;
+
+ r = sd_bus_creds_get_uid(creds, &sender_uid);
+ if (r >= 0) {
+ /* Sender has same UID as us, then let's grant access */
+ if (sender_uid == our_uid)
+ return 1;
+
+ /* Sender is root, we are not root. */
+ if (our_uid != 0 && sender_uid == 0)
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index dbb04e5ec6..78dab8048d 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -289,7 +289,6 @@ static int node_callbacks_run(
static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c, sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
uint64_t cap;
- uid_t uid;
int r;
assert(bus);
@@ -304,17 +303,6 @@ static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c,
if (c->vtable->flags & SD_BUS_VTABLE_UNPRIVILEGED)
return 0;
- /* If we are not connected to kdbus we cannot retrieve the
- * effective capability set without race. Since we need this
- * for a security decision we cannot use racy data, hence
- * don't request it. */
- if (bus->is_kernel)
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
- else
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
- if (r < 0)
- return r;
-
/* Check have the caller has the requested capability
* set. Note that the flags value contains the capability
* number plus one, which we need to subtract here. We do this
@@ -328,16 +316,11 @@ static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c,
else
cap --;
- r = sd_bus_creds_has_effective_cap(creds, cap);
+ r = sd_bus_query_sender_privilege(m, cap);
+ if (r < 0)
+ return r;
if (r > 0)
- return 1;
-
- /* Caller has same UID as us, then let's grant access */
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r >= 0) {
- if (uid == getuid())
- return 1;
- }
+ return 0;
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access to %s.%s() not permitted.", c->interface, c->member);
}
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
index 37f5c4620c..65f1d17c9f 100644
--- a/src/libsystemd/sd-bus/bus-util.c
+++ b/src/libsystemd/sd-bus/bus-util.c
@@ -186,28 +186,22 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
int bus_verify_polkit(
sd_bus *bus,
sd_bus_message *m,
+ int capability,
const char *action,
bool interactive,
bool *_challenge,
sd_bus_error *e) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- uid_t uid;
int r;
assert(bus);
assert(m);
assert(action);
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+ r = sd_bus_query_sender_privilege(m, capability);
if (r < 0)
return r;
-
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r < 0)
- return r;
-
- if (uid == 0)
+ if (r > 0)
return 1;
#ifdef ENABLE_POLKIT
@@ -325,6 +319,7 @@ int bus_verify_polkit_async(
sd_bus *bus,
Hashmap **registry,
sd_bus_message *m,
+ int capability,
const char *action,
bool interactive,
sd_bus_error *error,
@@ -336,8 +331,6 @@ int bus_verify_polkit_async(
AsyncPolkitQuery *q;
const char *sender;
#endif
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- uid_t uid;
int r;
assert(bus);
@@ -383,15 +376,10 @@ int bus_verify_polkit_async(
}
#endif
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+ r = sd_bus_query_sender_privilege(m, capability);
if (r < 0)
return r;
-
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r < 0)
- return r;
-
- if (uid == 0)
+ if (r > 0)
return 1;
#ifdef ENABLE_POLKIT
diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h
index b3b52af24c..1ac46875b2 100644
--- a/src/libsystemd/sd-bus/bus-util.h
+++ b/src/libsystemd/sd-bus/bus-util.h
@@ -62,9 +62,9 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error);
int bus_check_peercred(sd_bus *c);
-int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
+int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
-int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
+int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, int capability, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
void bus_verify_polkit_async_registry_free(Hashmap *registry);
int bus_open_system_systemd(sd_bus **_bus);
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
index 4d8b7e7b2c..3a3f53576f 100644
--- a/src/libsystemd/sd-network/sd-network.c
+++ b/src/libsystemd/sd-network/sd-network.c
@@ -92,6 +92,10 @@ _public_ int sd_network_get_ntp(char ***ret) {
return network_get_strv("NTP", ret);
}
+_public_ int sd_network_get_domains(char ***ret) {
+ return network_get_strv("DOMAINS", ret);
+}
+
_public_ int sd_network_link_get_setup_state(int ifindex, char **state) {
_cleanup_free_ char *s = NULL, *p = NULL;
int r;
@@ -210,6 +214,26 @@ _public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
return network_get_link_strv("DOMAINS", ifindex, ret);
}
+_public_ int sd_network_link_get_wildcard_domain(int ifindex) {
+ int r;
+ _cleanup_free_ char *p = NULL, *s = NULL;
+
+ assert_return(ifindex > 0, -EINVAL);
+
+ if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+ return -ENOMEM;
+
+ r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
+ if (r == -ENOENT)
+ return -ENODATA;
+ if (r < 0)
+ return r;
+ if (isempty(s))
+ return -ENODATA;
+
+ return parse_boolean(s);
+}
+
static inline int MONITOR_TO_FD(sd_network_monitor *m) {
return (int) (unsigned long) m - 1;
}