## 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.