Core API Reference - Context
Desktop Apps Training - Policy Kit

Context

Context — The main interface used to query PolicyKit.

 

Synopsis



PolKitContext;
void (*PolKitContextConfigChangedCB) (PolKitContext *pk_context,
void *user_data);
int (*PolKitContextAddIOWatch) (PolKitContext *pk_context,
int fd);
void (*PolKitContextRemoveIOWatch) (PolKitContext *pk_context,
int watch_id);
PolKitContext* polkit_context_new (void);
void polkit_context_set_config_changed (PolKitContext *pk_context,
PolKitContextConfigChangedCB cb,
void *user_data);
void polkit_context_set_io_watch_functions
(PolKitContext *pk_context,
PolKitContextAddIOWatch io_add_watch_func,
PolKitContextRemoveIOWatch io_remove_watch_func);
void polkit_context_set_load_descriptions
(PolKitContext *pk_context);
polkit_bool_t polkit_context_init (PolKitContext *pk_context,
PolKitError **error);
PolKitContext* polkit_context_ref (PolKitContext *pk_context);
void polkit_context_unref (PolKitContext *pk_context);
void polkit_context_force_reload (PolKitContext *pk_context);
void polkit_context_io_func (PolKitContext *pk_context,
int fd);
PolKitPolicyCache* polkit_context_get_policy_cache (PolKitContext *pk_context);
PolKitResult polkit_context_can_session_do_action
(PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session);
PolKitResult polkit_context_can_caller_do_action (PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller);
PolKitConfig* polkit_context_get_config (PolKitContext *pk_context,
PolKitError **error);
PolKitResult polkit_context_is_caller_authorized (PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller,
polkit_bool_t revoke_if_one_shot,
PolKitError **error);
PolKitResult polkit_context_is_session_authorized
(PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session,
PolKitError **error);
PolKitAuthorizationDB* polkit_context_get_authorization_db
(PolKitContext *pk_context);

Description

This class is used to represent the interface to PolicyKit - it is used by Mechanisms that use PolicyKit for making decisions. Typically, it's used as a singleton:

 

  • First, the Mechanism need to declare one or more PolicyKit Actions by dropping a .policy file into /usr/share/PolicyKit/policy. This is described in the PolicyKit specification.
  • The mechanism starts up and uses polkit_context_new() to create a new context
  • If the mechanism is a long running daemon, it should use polkit_context_set_config_changed() to register a callback when configuration changes. This is useful if, for example, the mechanism needs to revise decisions based on earlier answers from libpolkit. For example, a daemon that manages permissions on /dev may want to add/remove ACL's when configuration changes; for example, the system administrator could have changed the PolicyKit configuration file /etc/PolicyKit/PolicyKit.conf such that some user is now privileged to access a specific device.
  • If polkit_context_set_config_changed() is used, the mechanism must also use polkit_context_set_io_watch_functions() to integrate libpolkit into the mainloop.
  • The mechanism needs to call polkit_context_init() such that libpolkit can load configuration files and properly initialize.
  • Whenever the mechanism needs to make a decision whether a caller is allowed to make a perform some action, the mechanism prepares a PolKitAction and PolKitCaller object (or PolKitSession if applicable) and calls polkit_context_can_caller_do_action() (or polkit_context_can_session_do_action() if applicable). The mechanism may use the libpolkit-dbus library (specifically the polkit_caller_new_from_dbus_name() or polkit_caller_new_from_pid() functions) but may opt, for performance reasons, to construct PolKitCaller (or PolKitSession if applicable) from it's own cache of information.
  • The mechanism will get a PolKitResult object back that describes whether it should carry out the action. This result stems from a number of sources, see the PolicyKit specification document for details.
  • If the result is POLKIT_RESULT_YES, the mechanism should carry out the action. If the result is not POLKIT_RESULT_YES nor POLKIT_RESULT_UNKNOWN (this would never be returned but is mentioned here for completeness), the mechanism should throw an expcetion to the caller detailing the PolKitResult as a textual string using polkit_result_to_string_representation(). For example, if the mechanism is using D-Bus it could throw an com.some-mechanism.DeniedByPolicy exception with the PolKitResult textual representation in the detail field. Then the caller can interpret this exception and then act on it (for example it can attempt to gain that privilege).

 

For more information about using PolicyKit in mechanisms and callers, refer to the PolicyKit-gnome project which includes a sample application on how to use this in the GNOME desktop.

 

Details

PolKitContext

typedef struct _PolKitContext PolKitContext;

Context object for users of PolicyKit.

 


PolKitContextConfigChangedCB ()

void                (*PolKitContextConfigChangedCB)     (PolKitContext *pk_context,
void *user_data);

The type of the callback function for when configuration changes. Mechanisms should use this callback to e.g. reconfigure all permissions / acl's they have set in response to policy decisions made from information provided by PolicyKit.

The user must have set up watches using polkit_context_set_io_watch_functions for this to work.

Note that this function may be called many times within a short interval due to how file monitoring works if e.g. the user is editing a configuration file (editors typically create back-up files). Mechanisms should use a "cool-off" timer (of, say, one second) to avoid doing many expensive operations (such as reconfiguring all ACL's for all devices) within a very short timeframe.

 

pk_context :

PolicyKit context

user_data :

user data

PolKitContextAddIOWatch ()

int                 (*PolKitContextAddIOWatch)          (PolKitContext *pk_context,
int fd);

Type for function supplied by the application to integrate a watch on a file descriptor into the applications main loop. The application must call polkit_context_io_func() when there is data to read from the file descriptor.

For glib mainloop, the function will typically look like this:

 

static gboolean
io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
{
int fd;
PolKitContext *pk_context = user_data;
fd = g_io_channel_unix_get_fd (channel);
polkit_context_io_func (pk_context, fd);
return TRUE;
}

static int
io_add_watch (PolKitContext *pk_context, int fd)
{
guint id = 0;
GIOChannel *channel;
channel = g_io_channel_unix_new (fd);
if (channel == NULL)
goto out;
id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, pk_context);
if (id == 0) {
g_io_channel_unref (channel);
goto out;
}
g_io_channel_unref (channel);
out:
return id;
}

 

pk_context :

the polkit context

fd :

the file descriptor to watch

Returns :

0 if the watch couldn't be set up; otherwise an unique identifier for the watch.

PolKitContextRemoveIOWatch ()

void                (*PolKitContextRemoveIOWatch)       (PolKitContext *pk_context,
int watch_id);

Type for function supplied by the application to remove a watch set up via the supplied function of type PolKitContextAddIOWatch

For the glib mainloop, the function will typically look like this:

 

static void 
io_remove_watch (PolKitContext *pk_context, int watch_id)
{
g_source_remove (watch_id);
}

 

pk_context :

the context object

watch_id :

the id obtained from using the supplied function of type PolKitContextAddIOWatch

polkit_context_new ()

PolKitContext*      polkit_context_new                  (void);

Create a new context

 

Returns :

the object

polkit_context_set_config_changed ()

void                polkit_context_set_config_changed   (PolKitContext *pk_context,
PolKitContextConfigChangedCB cb,
void *user_data);

Register the callback function for when configuration changes. Mechanisms should use this callback to e.g. reconfigure all permissions / acl's they have set in response to policy decisions made from information provided by PolicyKit.

Note that this function may be called many times within a short interval due to how file monitoring works if e.g. the user is editing a configuration file (editors typically create back-up files). Mechanisms should use a "cool-off" timer (of, say, one second) to avoid doing many expensive operations (such as reconfiguring all ACL's for all devices) within a very short timeframe.

This method must be called before polkit_context_init().

 

pk_context :

the context object

cb :

the callback to invoke

user_data :

user data to pass to the callback

polkit_context_set_io_watch_functions ()

void                polkit_context_set_io_watch_functions
(PolKitContext *pk_context,
PolKitContextAddIOWatch io_add_watch_func,
PolKitContextRemoveIOWatch io_remove_watch_func);

Register a functions that PolicyKit can use for watching IO descriptors.

This method must be called before polkit_context_init().

 

pk_context :

the context object

io_add_watch_func :

the function that the PolicyKit library can invoke to start watching a file descriptor

io_remove_watch_func :

the function that the PolicyKit library can invoke to stop watching a file descriptor

polkit_context_set_load_descriptions ()

void                polkit_context_set_load_descriptions
(PolKitContext *pk_context);

Set whether policy descriptions should be loaded. By default these are not loaded to keep memory use down. TODO: specify whether they are localized and how.

This method must be called before polkit_context_init().

 

pk_context :

the context

polkit_context_init ()

polkit_bool_t       polkit_context_init                 (PolKitContext *pk_context,
PolKitError **error);

Initializes a new context; loads PolicyKit files from /usr/share/PolicyKit/policy.

 

pk_context :

the context object

error :

return location for error

Returns :

FALSE if error was set, otherwise TRUE

polkit_context_ref ()

PolKitContext*      polkit_context_ref                  (PolKitContext *pk_context);

Increase reference count.

 

pk_context :

the context object

Returns :

the object

polkit_context_unref ()

void                polkit_context_unref                (PolKitContext *pk_context);

Decreases the reference count of the object. If it becomes zero, the object is freed. Before freeing, reference counts on embedded objects are decresed by one.

 

pk_context :

the context object

polkit_context_force_reload ()

void                polkit_context_force_reload         (PolKitContext *pk_context);

Force a reload.

Note that there is no reason to call this method in response to a config changed callback.

 

pk_context :

context

Since 0.7


polkit_context_io_func ()

void                polkit_context_io_func              (PolKitContext *pk_context,
int fd);

Method that the application must call when there is data to read from a file descriptor registered with the supplied function of type PolKitContextAddIOWatch.

 

pk_context :

the object

fd :

the file descriptor passed to the supplied function of type PolKitContextAddIOWatch.

polkit_context_get_policy_cache ()

PolKitPolicyCache*  polkit_context_get_policy_cache     (PolKitContext *pk_context);

Get the PolKitPolicyCache object that holds all the defined policies as well as their defaults.

 

pk_context :

the context

Returns :

the PolKitPolicyCache object. Caller shall not unref it.

polkit_context_can_session_do_action ()

PolKitResult        polkit_context_can_session_do_action
(PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session);

Warning

polkit_context_can_session_do_action has been deprecated since version 0.7 and should not be used in newly-written code. use polkit_context_is_session_authorized() instead.

Determine if a given session can do a given action.

This can fail with the following errors: POLKIT_ERROR_NOT_AUTHORIZED_TO_READ_AUTHORIZATIONS_FOR_OTHER_USERS

 

pk_context :

the PolicyKit context

action :

the type of access to check for

session :

the session in question

Returns :

A PolKitResult - can only be one of POLKIT_RESULT_YES, POLKIT_RESULT_NO.

polkit_context_can_caller_do_action ()

PolKitResult        polkit_context_can_caller_do_action (PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller);

Warning

polkit_context_can_caller_do_action has been deprecated since version 0.7 and should not be used in newly-written code. use polkit_context_is_caller_authorized() instead.

Determine if a given caller can do a given action.

 

pk_context :

the PolicyKit context

action :

the type of access to check for

caller :

the caller in question

Returns :

A PolKitResult specifying if, and how, the caller can do a specific action

polkit_context_get_config ()

PolKitConfig*       polkit_context_get_config           (PolKitContext *pk_context,
PolKitError **error);

Returns an object that provides access to the /etc/PolicyKit/PolicyKit.conf configuration files. Applications using PolicyKit should never use this method; it's only here for integration with other PolicyKit components.

 

pk_context :

the PolicyKit context

error :

Return location for error

Returns :

A PolKitConfig object or NULL if the configuration file is malformed. Caller should not unref this object.

polkit_context_is_caller_authorized ()

PolKitResult        polkit_context_is_caller_authorized (PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller,
polkit_bool_t revoke_if_one_shot,
PolKitError **error);

Determine if a given caller is authorized to do a given action.

It is important to understand how one-shot authorizations work. The revoke_if_one_shot parameter, if TRUE, specifies whether one-shot authorizations should be revoked if they are used to make the decision to return POLKIT_RESULT_YES.

UI applications wanting to hint whether a caller is authorized must pass FALSE here. Mechanisms that wants to check authorizations before carrying out work on behalf of a caller must pass TRUE here.

As a side-effect, any process with the authorization org.freedesktop.policykit.read can revoke one-shot authorizations from other users. Even though the window for doing so is small (one-shot auths are typically used right away), be careful who you grant that authorization to.

This can fail with the following errors: POLKIT_ERROR_NOT_AUTHORIZED_TO_READ_AUTHORIZATIONS_FOR_OTHER_USERS

 

pk_context :

the PolicyKit context

action :

the type of access to check for

caller :

the caller in question

revoke_if_one_shot :

Whether to revoke one-shot authorizations. See below for discussion.

error :

return location for error

Returns :

A PolKitResult specifying if, and how, the caller can do a specific action.

Since 0.7


polkit_context_is_session_authorized ()

PolKitResult        polkit_context_is_session_authorized
(PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session,
PolKitError **error);

Determine if any caller from a giver session is authorized to do a given action.

 

pk_context :

the PolicyKit context

action :

the type of access to check for

session :

the session in question

error :

return location for error

Returns :

A PolKitResult specifying if, and how, the caller can do a specific action.

Since 0.7


polkit_context_get_authorization_db ()

PolKitAuthorizationDB* polkit_context_get_authorization_db
(PolKitContext *pk_context);

Returns an object that provides access to the authorization database. Applications using PolicyKit should never use this method; it's only here for integration with other PolicyKit components.

 

pk_context :

the PolicyKit context

Returns :

A PolKitAuthorizationDB object. Caller should not unref this object.