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,
+ sd_bus_message *call,
+ 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(call);
assert(action);
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+ r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
-
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r < 0)
- return r;
-
- if (uid == 0)
+ else if (r > 0)
return 1;
-
#ifdef ENABLE_POLKIT
else {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
int authorized = false, challenge = false;
const char *sender;
- sender = sd_bus_message_get_sender(m);
+ sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
r = sd_bus_call_method(
- bus,
+ call->bus,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
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;
}
#endif
int bus_verify_polkit_async(
- sd_bus *bus,
- Hashmap **registry,
- sd_bus_message *m,
+ sd_bus_message *call,
+ int capability,
const char *action,
bool interactive,
- sd_bus_error *error,
- sd_bus_message_handler_t callback,
- void *userdata) {
+ Hashmap **registry,
+ sd_bus_error *error) {
#ifdef ENABLE_POLKIT
_cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
AsyncPolkitQuery *q;
const char *sender;
+ sd_bus_message_handler_t callback;
+ void *userdata;
#endif
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- uid_t uid;
int r;
- assert(bus);
- assert(registry);
- assert(m);
+ assert(call);
assert(action);
+ assert(registry);
#ifdef ENABLE_POLKIT
- q = hashmap_get(*registry, m);
+ q = hashmap_get(*registry, call);
if (q) {
int authorized, challenge;
}
#endif
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+ r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
-
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r < 0)
- return r;
-
- if (uid == 0)
+ else if (r > 0)
return 1;
#ifdef ENABLE_POLKIT
- sender = sd_bus_message_get_sender(m);
+ if (sd_bus_get_current_message(call->bus) != call)
+ return -EINVAL;
+
+ callback = sd_bus_get_current_handler(call->bus);
+ if (!callback)
+ return -EINVAL;
+
+ userdata = sd_bus_get_current_userdata(call->bus);
+
+ sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
return r;
r = sd_bus_message_new_method_call(
- bus,
+ call->bus,
&pk,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
if (!q)
return -ENOMEM;
- q->request = sd_bus_message_ref(m);
+ q->request = sd_bus_message_ref(call);
q->callback = callback;
q->userdata = userdata;
- r = hashmap_put(*registry, m, q);
+ r = hashmap_put(*registry, call, 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(call->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;
}
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);