Some help with PolicyKit basics

David Zeuthen david at fubar.dk
Sun Jul 26 13:22:25 PDT 2009


On Fri, 2009-07-24 at 17:40 +1000, Robert Ancell wrote:
> Hi,
> 
> I'm trying to learn how to use PolicyKit for configuration of a
> server.  Find attached a demo program (which I plan to post as a a
> tutorial) which does the following:
> - Has a server providing a method "Reflect" which reverses a string
> - Has a client with a text entry that uses that uses the server to
> reflect entered text
> - The client has an "unlock" button that should authorize with the PolKit once
> 
> Note I've tried to make the simplest example not the most efficient.

The code doesn't really compile without mirror.h...

> I've been stumbling along for a while and am in need of some help:
> - I've used POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION in
> polkit_authority_check_authorization_sync to prompt the user for
> authentication but sometimes it just blocks for ages instead of
> popping up the dialog.  When should I use this flag and when let the
> client do the authorization?
> - I haven't been able to get the client to manually authorize or have
> persistent authorization, how do I do this?
> - Any pointers?
> 
> The documentation I have been working from:
> http://dbus.freedesktop.org/doc/dbus-specification.html
> http://hal.freedesktop.org/docs/PolicyKit/
> http://people.freedesktop.org/~david/polkit-0.92-newdocs/
> http://cgit.freedesktop.org/PolicyKit/tree/docs/PORTING-GUIDE

First you appear to be mixing the new PolicyKit version with the old one
(the server links against polkit-gobject-1, the client against
polkit-dbus). In the new PolicyKit, with version > 0.90) the client is
not supposed to know anything about PolicyKit at all - it simply invokes
methods on the server and the server simply does authorization checks
using polkit. If the server passes ALLOW_USER_INTERACTION to polkit it
means that Authentication Dialogs may appear - but the client would
never need to know anything about this. In fact, the client itself
_cannot_ even speak to PolicyKit - it is not allowed.

It is not clear to me what exactly you are trying to achieve - are you
trying to do stuff that works like the OS X lock? For example

http://lh4.ggpht.com/dr.k.anil/SE5J8JltXOI/AAAAAAAACe4/b9a-eq03RV8/accounts.jpg

If so, you need to add support for this in the Server itself, e.g.
something like

 interface com.example.Mirror {
   /// Returns %TRUE if the configuration interface is locked for the
   /// caller - e.g. Conf*() methods will require authentication
   GetIsLocked (OUT boolean is_locked);

   /// Returns %TRUE iff the configuration can be unlocked
   GetCanUnlock (OUT boolean can_be_unlocked);

   /// Returns %TRUE iff the configuration can be locked
   GetCanLock (OUT boolean can_be_locked);

   /// Unlock the interface for the caller so the caller can call
   /// Conf*() methods without authenticating
   Unlock();

   /// Lock the configuration interface - caller can no longer call
   /// Conf*() methods without authenticating.
   Lock();

   /// Emitted when the lock status changes - all callers should
   /// check with GetIsLocked()
   signal LockChanged();

   /// --- Actual methods

   ConfMethod1(...);
   ConfMethod2(...);
   ...
 };

Note that GetIsLocked() depends on the actual caller (the configuration
interface may be locked for one caller and unlocked for another one) -
so it cannot be a property. For the same reasons the LockChanged()
signal doesn't include the state.

So, anyway, with a design like this, then on the server side

 - You would use CheckAuthorization() without ALLOW_USER_INTERACTION for
   when implementing GetIsLocked() and GetCanUnlock()

 - For Unlock() you would use ALLOW_USER_INTERACTION

 - For Lock() you will need some API not yet added (CheckAuthorization()
   needs to return the tmp authz identifier - and we need a way to
   revoke a tmp authz by id).

On the client side

 - Use GetCanUnlock(), GetCanLock() and GetIsLocked() to render the lock
   icon and decide if it is sensitive or not. You'd use Unlock() and
   Lock() when the user clicks the lock.

Hmm, it might be nice to have library API for doing all this since it is
rather complicated. Like, we'd have some code in polkit-gobject-1 to do
the server side bits and maybe a polkit-gtk-1 library for the client
side bits. Unfortunately we don't have a nice D-Bus library for GLib
just yet so it is not yet feasible to do the server side bits just
yet...

Hope this helps.

    David




More information about the polkit-devel mailing list