permissionsdnsdbuspolicyresolve

Unable to get dbus policy to behave as expected


Here's the policy

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
  <busconfig>
    <policy user="alice">
      <allow send_interface="org.freedesktop.resolve1.Manager" send_member="SetLinkDNS"/>
    </policy>
  </busconfig>

I run

ip link add abc type wireguard

busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager SetLinkDNS 'ia(iay)' 3 1 2 4 8 8 8 8

The error message is Call failed: Access Denied. It runs fine if I prepend sudo. I would like to run this without superuser privileges.


Solution

  • The request was not being denied by D-Bus policy in the first place. Any user is allowed to send method_call messages for this method.

    The request is denied by the service, which is aware of the UID of the caller and rejects unprivileged requests from within the method call handler.

    The service's method call handlers support using PolicyKit (polkit) to verify authorization of calls. If systemd has been compiled with PolicyKit support and if the polkitd service is running, it will be used to check access to the org.freedesktop.resolve1.set-dns-servers PolicyKit action.

    For this specific action, the default treatment is AUTH_ADMIN, which means Polkit will show an interactive credentials prompt – similar to Windows UAC – where members of a group such as wheel or sudoers are considered to be administrators.

    The prompt is shown if the D-Bus method_call has the "allow interactive authorization" flag set (e.g. busctl has --allow-interactive-authorization=BOOL) and if it's made from a desktop session that supports prompting for credentials (busctl has a built-in credential prompter).

    You can change this by writing PolicyKit rules for the specific action you want (the action ID is shown in polkitd logs, systemctl status polkit). For example, to allow the action without asking for credentials:

    polkit.addRule(function(action, subject) {
        if (action.id == "org.freedesktop.resolve1.set-dns-servers" &&
            subject.user == "alice")
        {
            return polkit.Result.YES;
        }
    })
    

    Rule syntax documentation: