assert(m);
assert(e);
+ sd_bus_close(bus);
sd_event_exit(e, 0);
+
return 1;
}
if (r < 0)
return -ENOMEM;
- r = sd_bus_add_match(bus, match, name_owner_change_callback, e);
+ r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
if (r < 0)
return r;
return r;
if (r == 0 && !exiting) {
- r = bus_async_unregister_and_exit(e, bus, name);
+
+ r = sd_bus_try_close(bus);
+ if (r == -EBUSY)
+ continue;
+
+ if (r == -ENOTSUP) {
+ /* Fallback for dbus1 connections: we
+ * unregister the name and wait for
+ * the response to come through for
+ * it */
+
+ r = bus_async_unregister_and_exit(e, bus, name);
+ if (r < 0)
+ return r;
+
+ exiting = true;
+ continue;
+ }
+
if (r < 0)
return r;
- exiting = true;
+ sd_event_exit(e, 0);
+ break;
}
}
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
sd_bus_message *request, *reply;
sd_bus_message_handler_t callback;
void *userdata;
- uint64_t serial;
+ sd_bus_slot *slot;
Hashmap *registry;
} AsyncPolkitQuery;
-static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
+static void async_polkit_query_free(AsyncPolkitQuery *q) {
if (!q)
return;
- if (q->serial > 0 && b)
- sd_bus_call_async_cancel(b, q->serial);
+ sd_bus_slot_unref(q->slot);
if (q->registry && q->request)
hashmap_remove(q->registry, q->request);
assert(reply);
assert(q);
+ q->slot = sd_bus_slot_unref(q->slot);
q->reply = sd_bus_message_ref(reply);
- q->serial = 0;
r = sd_bus_message_rewind(q->request, true);
if (r < 0) {
r = bus_maybe_reply_error(q->request, r, &error_buffer);
finish:
- async_polkit_query_free(bus, q);
+ async_polkit_query_free(q);
+
return r;
}
sd_bus *bus,
Hashmap **registry,
sd_bus_message *m,
+ int capability,
const char *action,
bool interactive,
sd_bus_error *error,
AsyncPolkitQuery *q;
const char *sender;
#endif
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- uid_t uid;
int r;
assert(bus);
}
#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
r = hashmap_put(*registry, m, q);
if (r < 0) {
- async_polkit_query_free(bus, q);
+ async_polkit_query_free(q);
return r;
}
q->registry = *registry;
- r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
+ r = sd_bus_call_async(bus, &q->slot, pk, async_polkit_callback, q, 0);
if (r < 0) {
- async_polkit_query_free(bus, q);
+ async_polkit_query_free(q);
return r;
}
return -EACCES;
}
-void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) {
+void bus_verify_polkit_async_registry_free(Hashmap *registry) {
#ifdef ENABLE_POLKIT
AsyncPolkitQuery *q;
while ((q = hashmap_steal_first(registry)))
- async_polkit_query_free(bus, q);
+ async_polkit_query_free(q);
hashmap_free(registry);
#endif
if (r < 0)
return r;
- if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid()) < 0)
+ if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, getuid()) < 0)
return -ENOMEM;
bus->bus_client = true;
return r;
}
-int bus_property_get_tristate(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- int *tristate = userdata;
-
- return sd_bus_message_append(reply, "b", *tristate > 0);
-}
-
int bus_property_get_bool(
sd_bus *bus,
const char *path,
#endif
int bus_log_parse_error(int r) {
- log_error("Failed to parse message: %s", strerror(-r));
+ log_error("Failed to parse bus message: %s", strerror(-r));
return r;
}
int bus_log_create_error(int r) {
- log_error("Failed to create message: %s", strerror(-r));
+ log_error("Failed to create bus message: %s", strerror(-r));
return r;
}
assert(message);
assert(u);
+ u->machine = NULL;
+
return sd_bus_message_read(
message,
"(ssssssouso)",
field = strndupa(assignment, eq - assignment);
eq ++;
+ if (streq(field, "CPUQuota")) {
+
+ if (isempty(eq)) {
+
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
+
+ } else if (endswith(eq, "%")) {
+ double percent;
+
+ if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
+ log_error("CPU quota '%s' invalid.", eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
+ } else {
+ log_error("CPU quota needs to be in percent.");
+ return -EINVAL;
+ }
+
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return 0;
+ }
+
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
if (r < 0)
return bus_log_create_error(r);
- if (STR_IN_SET(field, "CPUAccounting", "MemoryAccounting", "BlockIOAccounting")) {
+ if (STR_IN_SET(field,
+ "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+ "SendSIGHUP", "SendSIGKILL")) {
r = parse_boolean(eq);
if (r < 0) {
r = sd_bus_message_append(m, "v", "t", u);
- } else if (streq(field, "DevicePolicy"))
+ } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "DeviceAllow")) {
r = sd_bus_message_append(m, "v", "a(st)", path, u);
}
+ } else if (rlimit_from_string(field) >= 0) {
+ uint64_t rl;
+
+ if (streq(eq, "infinity"))
+ rl = (uint64_t) -1;
+ else {
+ r = safe_atou64(eq, &rl);
+ if (r < 0) {
+ log_error("Invalid resource limit: %s", eq);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", rl);
+
+ } else if (streq(field, "Nice")) {
+ int32_t i;
+
+ r = safe_atoi32(eq, &i);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", i);
+
+ } else if (streq(field, "Environment")) {
+
+ r = sd_bus_message_append(m, "v", "as", 1, eq);
+
+ } else if (streq(field, "KillSignal")) {
+ int sig;
+
+ sig = signal_from_string_try_harder(eq);
+ if (sig < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", sig);
+
} else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;