Some help with PolicyKit basics

David Zeuthen david at fubar.dk
Mon Jul 27 07:39:02 PDT 2009


On Mon, 2009-07-27 at 13:07 +1000, Robert Ancell wrote:
> Yes, a lock.  I think this is required for any configuration dialog as
> the UI may not be able to show the configuration until the client is
> authorized and the user doesn't want to authorize for each config
> change.

Not necessarily. I mean, it is definitely nicer that way - the
alternative is to interrupt the user with an authentication dialog the
first time authentication is needed. With 0.93 on onwards there is
visual feedback through the notification area icon

http://people.freedesktop.org/~david/polkit-tmp-authz.png

> I think I understand better, does this make sense (in the case of a
> simple PK+DBUS client/server):
> 
> - PK clients do not need any knowledge of PK, they make D-BUS calls
> and the user will be prompted for any required authorization.  During
> authorisation the D-BUS call will block until authorisation is
> received or denied.

Right. And this doesn't really have to be via D-Bus - the Mechanism that
the UI client is using could be a setuid helper. But, sure.

> - The way a PK client knows a call failed due to authorization is by
> checking the DBusError returned from a failed call.

Yeah. In fact, Mechanisms can return errors in any way they want. For
example, DeviceKit-disks returns the org.fd.DK.Disks.PermissionDenied
D-Bus error. A setuid Mechanism would use a return code - for example,
the pkexec(1) mechanism returns 127 if the given subject is not
authorized.

This is supposed to be specified in the API contract between the UI
client and the Mechanism - polkit really has nothing to do with
specifying interaction between a Mechanism and its clients.

> - The PK server checks authorization in each D-Bus handler using
> polkit_authority_check_authorization_sync() using the D-Bus name for
> the client.

Yep, basically. Two comments

 - if the Mechanism is supposed to serve multiple clients (such as
   PackageKit, DeviceKit-disks and NetworkManager) it should use async
   calls to speak to polkit - e.g. instead of _sync() it should be using
   check_authorization() and check_authorization_finish() - otherwise
   other clients are locked out for the duration of the check (which
   can be many many seconds if authentication is involved)

 - if the Mechanism is not using D-Bus to speak to the client it would
   use a PolkitUnixProcess rather than a PolkitSystemBusName object as
   the PolkitSubject object passed to polkit

> - To avoid the client having to enter their password for each D-Bus
> call the server should maintain a list of authorized D-Bus names.
> This is safe because D-Bus guarantees these names to be unique 

Now, a Mechanism _may_ cache the results authorization checks but it
really shouldn't unless performance is a concern. If it does cache the
results it should evict that cache upon receiving the Changed signal
from the Authority. And a Mechanism can never cache an authorization
unless it is a temporary one (look for polkit.temporary_authorization_id
in the returned details). So, all in all, Mechanisms should never cache
authorization results. 

But it all depends - a mechanism can basically do whatever it wants.

PolicyKit itself has the notion of temporary authorizations precisely to
avoid the user having to authenticate over and over again. There is
enough API available such that UI bits can display visual indication if
something in the user session has one or more temporary authorizations.

> (Is
> this still true if the d-bus daemon is restarted?)

The system bus daemon should _never ever_ be restarted. The guarantee
that unique system bus names are _never_ recycled is a good reason why
this is so. I know some distributions still live in some interesting
reality where they think restarting the system daemon is OK... but
essentially these guys are wrong and doing so is introducing a security
hole.

> - To provide an "unlock" feature the server needs to provide a method
> which tells the client if it is authorized and a method that does that
> performs authorization (but no other actions).

Yeah. That's one way to do it. The other way for which I just added
support via PolkitLockButton requires the client to know, ahead of time,
what action some method may require. Clients may not already know this
for for simple stuff they do.

    David




More information about the polkit-devel mailing list