int r;
assert_return(bus, -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
- r = sd_bus_message_new_signal(bus, path, interface, member, &m);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
+ r = sd_bus_message_new_signal(bus, &m, path, interface, member);
if (r < 0)
return r;
int r;
assert_return(bus, -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
- r = sd_bus_message_new_method_call(bus, destination, path, interface, member, &m);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
+ r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member);
if (r < 0)
return r;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
return 0;
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
assert_return(sd_bus_error_is_set(e), -EINVAL);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
return 0;
- r = sd_bus_message_new_method_error(call, e, &m);
+ r = sd_bus_message_new_method_error(call, &m, e);
if (r < 0)
return r;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
return 0;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
return 0;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
return 0;
va_start(ap, format);
- bus_error_set_errnofv(&berror, error, format, ap);
+ sd_bus_error_set_errnofv(&berror, error, format, ap);
va_end(ap);
return sd_bus_reply_method_error(call, &berror);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(reply, -EINVAL);
assert_return(signature_is_single(type, false), -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
if (r < 0)
return r;
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(bus_type_is_trivial(type), -EINVAL);
assert_return(ptr, -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
if (r < 0)
return r;
assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(ret, -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
if (r < 0)
return r;
assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(ret, -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
if (r < 0)
return r;
assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(signature_is_single(type, false), -EINVAL);
- assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
assert_return(!bus_pid_changed(bus), -ECHILD);
- r = sd_bus_message_new_method_call(bus, destination, path, "org.freedesktop.DBus.Properties", "Set", &m);
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
+ r = sd_bus_message_new_method_call(bus, &m, destination, path, "org.freedesktop.DBus.Properties", "Set");
if (r < 0)
return r;
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
- assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+ assert_return(call->bus, -EINVAL);
assert_return(!bus_pid_changed(call->bus), -ECHILD);
+ if (!BUS_IS_OPEN(call->bus->state))
+ return -ENOTCONN;
+
c = sd_bus_message_get_creds(call);
/* All data we need? */
* to get it from the sender or peer */
if (call->sender)
- return sd_bus_get_owner(call->bus, call->sender, mask, creds);
+ return sd_bus_get_name_creds(call->bus, call->sender, mask, creds);
else
- return sd_bus_get_peer_creds(call->bus, mask, creds);
+ return sd_bus_get_owner_creds(call->bus, mask, creds);
}
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;
+ bool know_caps = false;
+ 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;
+
+ if (capability >= 0) {
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+ if (r < 0)
+ return r;
+
+ /* Note that not even on kdbus we might have the caps
+ * field, due to faked identities, or namespace
+ * translation issues. */
+ r = sd_bus_creds_has_effective_cap(creds, capability);
+ if (r > 0)
+ return 1;
+ if (r == 0)
+ know_caps = true;
+ } else {
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID, &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 || !know_caps || capability < 0) {
+ uid_t sender_uid;
+
+ /* Try to use the EUID, if we have it. */
+ r = sd_bus_creds_get_euid(creds, &sender_uid);
+ if (r < 0)
+ 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;
+}