2

I wrote a dbus service and have it listening on the system bus, under the bus name "org.jfhbrook.plusdeck" and the path "/". That seems to be working fine. I have a corresponding dbus client that I'd like to use to interact with that system bus service, either if I'm the root user (called with sudo) or if I'm in a particular group (in this case, the "plusdeck" group).

I currently have this policy file, based on the dbus-daemon docs and cribbing from whatever examples I could find:

<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- --> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <!-- Root user can own the plusdeck service --> <policy user="root"> <allow own="org.jfhbrook.plusdeck"/> <allow send_destination="org.jfhbrook.plusdeck"/> </policy> <!-- Allow access for the "plusdeck" group --> <policy group="plusdeck"> <allow send_destination="org.jfhbrook.plusdeck"/> </policy> </busconfig> 

This works when I use sudo. However, when I use the same client with my user, which is a member of the plusdeck group, I get an error:

ERROR:plusdeck.dbus.client:org.freedesktop.DBus.Error.AccessDenied: Access to org.jfhbrook.plusdeck.Eject() not permitted. 

Note that this is a different error than I'd get if I didn't have access to the bus - that would be ERROR:plusdeck.dbus.client:org.freedesktop.DBus.Error.AccessDenied: Sender is not authorized to send message. It seems I'm authorized to send messages, but not to call that method.

I've tried combinations of everything I can think of, including setting send_member="*" in the allow tag, as well as <allow send_type="method_call"/>. I'm at my wit's end. Any help or guidance would be appreciated.

For what it's worth, I'm using Fedora 41. I mention this because I'm aware that my issue could be outside this configuration, for instance with SELinux. Though, I believe seeing nothing in /var/log/audit/audit.log rules that out.

1 Answer 1

2

After a lot of digging and a hint from the Fedora forums, I was able to figure out what was going on. I haven't completely tested it - unrelated issues with my release pipeline - but the API I'm using bears this out.

The dbus policy I have in this question is to my knowledge well-formed - in fact, it could be narrowed a bit by adding send_interface to the allow tag.

But there are at least two other ways of managing access policies for dbus. One of them is using polkit, and in fact I thought that was the issue for a while. But, as far as I can tell, polkit is an optional, added layer - it's not implemented by default.

The other way - and the culprit in this case - is the service itself marking a method as privileged within the sd-bus library. This is what was happening in my case. Some evidence of this is that, on introspecting my service's API, I could see an annotation called "org.freedesktop.systemd1.Privileged":

 <method name="Eject"> <annotation name="org.freedesktop.systemd1.Privileged" value="true"/> </method> 

By default, sd-bus marks all methods as privileged, unless an "unprivileged" flag is explicitly applied when defining the method. In the C API, this flag is called SD_BUS_VTABLE_UNPRIVILEGED. Note that signals and properties are not treated as such by default - in fact, those were all working fine.

My service is written in Python with python-sdbus, and indeed, it does support this API.

So in my code, I had something like:

 @dbus_method_async("") async def eject(self: Self) -> None: """ Eject the tape. """ self.client.eject() 

and I needed to change it to:

 @dbus_method_async("", flags=sdbus.DbusUnprivilegedFlag) async def eject(self: Self) -> None: """ Eject the tape. """ self.client.eject() 

Like I said, I haven't been able to fully test this end-to-end. But I'm really confident that this is the answer, and so am posting this as the solution.

1
  • Polkit falls under "the service itself managing access": the service would receive the call and then, as part of the handler function or possibly part of library like sd-bus, it would make a call to polkitd to verify caller's access. Commented Feb 11 at 7:30

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.