summaryrefslogtreecommitdiff
path: root/src/bus-proxyd
diff options
context:
space:
mode:
Diffstat (limited to 'src/bus-proxyd')
-rw-r--r--src/bus-proxyd/bus-xml-policy.c6
-rw-r--r--src/bus-proxyd/driver.c102
-rw-r--r--src/bus-proxyd/proxy.c13
-rw-r--r--src/bus-proxyd/proxy.h13
-rw-r--r--src/bus-proxyd/synthesize.c19
5 files changed, 109 insertions, 44 deletions
diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c
index dab5acbcb4..9a3b451c56 100644
--- a/src/bus-proxyd/bus-xml-policy.c
+++ b/src/bus-proxyd/bus-xml-policy.c
@@ -586,10 +586,8 @@ static int file_load(Policy *p, const char *path) {
case POLICY_ITEM_SEND:
case POLICY_ITEM_RECV:
- if (streq(name, "*")) {
- free(name);
- name = NULL;
- }
+ if (streq(name, "*"))
+ name = mfree(name);
break;
diff --git a/src/bus-proxyd/driver.c b/src/bus-proxyd/driver.c
index 1cb5ea5008..951f515808 100644
--- a/src/bus-proxyd/driver.c
+++ b/src/bus-proxyd/driver.c
@@ -71,6 +71,27 @@ static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, s
return get_creds_by_name(bus, name, mask, _creds, error);
}
+static int driver_activation(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ ProxyActivation *activation = userdata;
+
+ /*
+ * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
+ * whether this succeeded, failed, was not implemented or timed out. We
+ * cannot assume that the target reacts to this properly. Hence, just
+ * send the reply to the activation request and be done.
+ */
+
+ m = activation->request; /* claim reference */
+
+ --activation->proxy->n_activations;
+ LIST_REMOVE(activations_by_proxy, activation->proxy->activations, activation);
+ sd_bus_slot_unref(activation->slot);
+ free(activation);
+
+ return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
+}
+
int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names) {
int r;
@@ -441,27 +462,29 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
name_list = (struct kdbus_info *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
KDBUS_FOREACH(name, name_list, cmd.list_size) {
- const char *entry_name = NULL;
struct kdbus_item *item;
char *n;
- KDBUS_ITEM_FOREACH(item, name, items)
- if (item->type == KDBUS_ITEM_OWNED_NAME)
- entry_name = item->name.name;
-
- if (!streq_ptr(entry_name, arg0))
- continue;
-
- if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
- err = -ENOMEM;
- break;
+ KDBUS_ITEM_FOREACH(item, name, items) {
+ if (item->type == KDBUS_ITEM_OWNED_NAME) {
+ if (!streq_ptr(item->name.name, arg0))
+ continue;
+
+ if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) {
+ err = -ENOMEM;
+ break;
+ }
+
+ r = strv_consume(&owners, n);
+ if (r < 0) {
+ err = r;
+ break;
+ }
+ }
}
- r = strv_consume(&owners, n);
- if (r < 0) {
- err = r;
+ if (err < 0)
break;
- }
}
r = bus_kernel_cmd_free(a, cmd.offset);
@@ -585,7 +608,9 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) {
_cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
+ ProxyActivation *activation;
const char *name;
+ uint64_t cookie;
uint32_t flags;
if (!sd_bus_message_has_signature(m, "su"))
@@ -604,21 +629,46 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
if (r != -ESRCH)
return synthetic_reply_method_errno(m, r, NULL);
- r = sd_bus_message_new_method_call(
- a,
- &msg,
- name,
- "/",
- "org.freedesktop.DBus.Peer",
- "Ping");
+ if (p->n_activations >= PROXY_ACTIVATIONS_MAX)
+ return synthetic_reply_method_errno(m, -EMFILE, NULL);
+
+ r = sd_bus_message_get_cookie(m, &cookie);
+ if (r < 0)
+ return synthetic_reply_method_errno(m, r, NULL);
+
+ r = sd_bus_message_new_method_call(a,
+ &msg,
+ name,
+ "/",
+ "org.freedesktop.DBus.Peer",
+ "Ping");
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- r = sd_bus_send(a, msg, NULL);
+ r = bus_message_seal(msg, cookie, BUS_DEFAULT_TIMEOUT);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
+ activation = new0(ProxyActivation, 1);
+ if (!activation)
+ return synthetic_reply_method_errno(m, -ENOMEM, NULL);
+
+ r = sd_bus_call_async(a,
+ &activation->slot,
+ msg,
+ driver_activation,
+ activation,
+ 0);
+ if (r < 0) {
+ free(activation);
+ return synthetic_reply_method_errno(m, r, NULL);
+ }
+
+ activation->proxy = p;
+ activation->request = sd_bus_message_ref(m);
+ LIST_PREPEND(activations_by_proxy, p->activations, activation);
+ ++p->n_activations;
+ return 1;
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
_cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
@@ -657,8 +707,8 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (!args)
- return synthetic_reply_method_errno(m, -EINVAL, NULL);
+ if (strv_isempty(args)) /* nothing to do? */
+ return synthetic_reply_method_return(m, NULL);
r = sd_bus_message_new_method_call(
a,
diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c
index c37b09b9c0..df361ac400 100644
--- a/src/bus-proxyd/proxy.c
+++ b/src/bus-proxyd/proxy.c
@@ -261,9 +261,18 @@ int proxy_new(Proxy **out, int in_fd, int out_fd, const char *destination) {
}
Proxy *proxy_free(Proxy *p) {
+ ProxyActivation *activation;
+
if (!p)
return NULL;
+ while ((activation = p->activations)) {
+ LIST_REMOVE(activations_by_proxy, p->activations, activation);
+ sd_bus_message_unref(activation->request);
+ sd_bus_slot_unref(activation->slot);
+ free(activation);
+ }
+
sd_bus_flush_close_unref(p->local_bus);
sd_bus_flush_close_unref(p->destination_bus);
set_free_free(p->owned_names);
@@ -644,6 +653,10 @@ static int process_hello(Proxy *p, sd_bus_message *m) {
if (r < 0)
return log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
+ r = sd_bus_message_set_destination(n, p->destination_bus->unique_name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set destination for NameAcquired message: %m");
+
r = bus_seal_synthetic_message(p->local_bus, n);
if (r < 0)
return log_error_errno(r, "Failed to seal NameAcquired message: %m");
diff --git a/src/bus-proxyd/proxy.h b/src/bus-proxyd/proxy.h
index ccb951c109..6aac650ac9 100644
--- a/src/bus-proxyd/proxy.h
+++ b/src/bus-proxyd/proxy.h
@@ -25,6 +25,9 @@
#include "bus-xml-policy.h"
typedef struct Proxy Proxy;
+typedef struct ProxyActivation ProxyActivation;
+
+#define PROXY_ACTIVATIONS_MAX (16) /* max parallel activation requests */
struct Proxy {
sd_bus *local_bus;
@@ -37,12 +40,22 @@ struct Proxy {
Set *owned_names;
SharedPolicy *policy;
+ LIST_HEAD(ProxyActivation, activations);
+ size_t n_activations;
+
bool got_hello : 1;
bool queue_overflow : 1;
bool message_matched : 1;
bool synthetic_matched : 1;
};
+struct ProxyActivation {
+ LIST_FIELDS(ProxyActivation, activations_by_proxy);
+ Proxy *proxy;
+ sd_bus_message *request;
+ sd_bus_slot *slot;
+};
+
int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest);
Proxy *proxy_free(Proxy *p);
diff --git a/src/bus-proxyd/synthesize.c b/src/bus-proxyd/synthesize.c
index 3ecedfd575..15d99103f6 100644
--- a/src/bus-proxyd/synthesize.c
+++ b/src/bus-proxyd/synthesize.c
@@ -214,22 +214,13 @@ int synthesize_name_acquired(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m)
if (r < 0)
return r;
- r = bus_seal_synthetic_message(b, n);
+ r = sd_bus_message_set_destination(n, a->unique_name);
if (r < 0)
return r;
- /*
- * Make sure to only forward NameLost/NameAcquired messages if they
- * match an installed MATCH rule of the local client. We really must
- * not send messages the client doesn't expect.
- */
-
- r = bus_match_run(b, &b->match_callbacks, n);
- if (r >= 0 && p->message_matched)
- r = sd_bus_send(b, n, NULL);
-
- p->message_matched = false;
- p->synthetic_matched = false;
+ r = bus_seal_synthetic_message(b, n);
+ if (r < 0)
+ return r;
- return r;
+ return sd_bus_send(b, n, NULL);
}