Commit b9cf5bca authored by David Zeuthen's avatar David Zeuthen
Browse files

switch to XML for policy definition files and introduce descriptions

Descriptions will be subject to i18n/l10n efforts at some point.

Also add a new tool polkit-list-actions.
parent 5cfae846
......@@ -127,6 +127,20 @@ AC_SUBST(DBUS_LIBS)
AC_CHECK_FUNCS(getgrouplist)
EXPAT_LIB=""
AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
[
expat=$withval
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
]
)
AC_CHECK_HEADERS(expat.h, [AC_DEFINE(HAVE_EXPAT_H)],
[AC_MSG_ERROR([Can't find expat.h. Please install expat.])])
AC_CHECK_LIB(expat,XML_ParserCreate,[EXPAT_LIBS="-lexpat"],
[AC_MSG_ERROR([Can't find expat library. Please install expat.])])
AC_SUBST(EXPAT_LIBS)
# DocBook Documentation
AC_MSG_CHECKING([whether to build DocBook documentation])
......
# -*- Conf -*-
#
# Example privilege definitions...
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
[Action polkit-example-privilege]
AllowRemoteInactive=no
AllowRemoteActive=auth_root_keep_session
AllowLocalInactive=auth_self_keep_always
AllowLocalActive=yes
<group id="polkit-example">
<description>PolicyKit examples</description>
<description_short>PolicyKit</description_short>
[Action polkit-example-privilege2]
AllowRemoteInactive=no
AllowRemoteActive=auth_root_keep_session
AllowLocalInactive=auth_self_keep_always
AllowLocalActive=yes
<policy id="polkit-example-frobnicate">
<description>Frobnicate devices</description>
<missing>System policy prevents frobnicating the device '%s'.</missing>
<apply_to_all_mnemonic>Apply to all _frobnicatable devices</apply_to_all_mnemonic>
<defaults>
<allow_remote_inactive>no</allow_remote_inactive>
<allow_remote_active>no</allow_remote_active>
<allow_local_inactive>no</allow_local_inactive>
<allow_local_active>auth_self_keep_always</allow_local_active>
</defaults>
</policy>
</group>
</policyconfig>
......@@ -221,11 +221,17 @@ polkit_grant_set_functions (PolKitGrant *polkit_grant,
void
polkit_grant_child_func (PolKitGrant *polkit_grant, pid_t pid, int exit_code)
{
polkit_bool_t input_was_bogus;
g_return_if_fail (polkit_grant != NULL);
g_return_if_fail (polkit_grant->auth_in_progress);
if (exit_code >= 2)
input_was_bogus = TRUE;
else
input_was_bogus = FALSE;
polkit_grant->success = (exit_code == 0);
polkit_grant->func_done (polkit_grant, polkit_grant->success, polkit_grant->user_data);
polkit_grant->func_done (polkit_grant, polkit_grant->success, input_was_bogus, polkit_grant->user_data);
}
......@@ -355,8 +361,9 @@ polkit_grant_cancel_auth (PolKitGrant *polkit_grant)
pid = polkit_grant->child_pid;
polkit_grant->child_pid = 0;
kill (pid, SIGTERM);
polkit_grant->func_done (polkit_grant, FALSE, polkit_grant->user_data);
if (pid > 0)
kill (pid, SIGTERM);
polkit_grant->func_done (polkit_grant, FALSE, FALSE, polkit_grant->user_data);
}
/**
......
......@@ -196,6 +196,7 @@ typedef PolKitResult (*PolKitGrantOverrideGrantType) (PolKitGrant *polkit_grant,
* PolKitGrantDone:
* @polkit_grant: the grant object
* @gained_privilege: whether the privilege was obtained
* @invalid_data: whether the input data was bogus (not including bad passwords)
* @user_data: user data pointed as passed into polkit_grant_set_functions()
*
* This function is called when the granting process ends; either if
......@@ -204,6 +205,7 @@ typedef PolKitResult (*PolKitGrantOverrideGrantType) (PolKitGrant *polkit_grant,
**/
typedef void (*PolKitGrantDone) (PolKitGrant *polkit_grant,
polkit_bool_t gained_privilege,
polkit_bool_t invalid_data,
void *user_data);
/**
......
......@@ -53,7 +53,7 @@ libpolkit_la_SOURCES = \
polkit-utils.h polkit-utils.c \
polkit-module.h polkit-module.c
libpolkit_la_LIBADD = @GLIB_LIBS@ -ldl
libpolkit_la_LIBADD = @GLIB_LIBS@ @EXPAT_LIBS@ -ldl
libpolkit_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
......
......@@ -76,6 +76,8 @@ struct PolKitContext
PolKitPolicyCache *priv_cache;
GSList *modules;
polkit_bool_t load_descriptions;
};
/**
......@@ -377,6 +379,8 @@ polkit_context_unref (PolKitContext *pk_context)
* 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().
**/
void
polkit_context_set_config_changed (PolKitContext *pk_context,
......@@ -395,6 +399,8 @@ polkit_context_set_config_changed (PolKitContext *pk_context,
* @remove_watch_func: the function that the PolicyKit library can invoke to stop watching a file
*
* Register a functions that PolicyKit can use for watching files.
*
* This method must be called before polkit_context_init().
**/
void
polkit_context_set_file_monitor (PolKitContext *pk_context,
......@@ -406,6 +412,23 @@ polkit_context_set_file_monitor (PolKitContext *pk_contex
pk_context->file_monitor_remove_watch_func = remove_watch_func;
}
/**
* polkit_context_set_load_descriptions:
* @pk_context: the context
*
* Set whether policy descriptions should be loaded. By default these
* are not loaded to keep memory use down.
*
* This method must be called before polkit_context_init().
**/
void
polkit_context_set_load_descriptions (PolKitContext *pk_context)
{
g_return_if_fail (pk_context != NULL);
pk_context->load_descriptions = TRUE;
}
extern PolKitPolicyCache *_polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions, PolKitError **error);
/**
* polkit_context_get_policy_cache:
......@@ -426,7 +449,9 @@ polkit_context_get_policy_cache (PolKitContext *pk_context)
_pk_debug ("Populating cache from directory %s", pk_context->policy_dir);
error = NULL;
pk_context->priv_cache = polkit_policy_cache_new (pk_context->policy_dir, &error);
pk_context->priv_cache = _polkit_policy_cache_new (pk_context->policy_dir,
pk_context->load_descriptions,
&error);
if (pk_context->priv_cache == NULL) {
g_warning ("Error loading policy files from %s: %s",
pk_context->policy_dir, polkit_error_get_error_message (error));
......
......@@ -135,13 +135,14 @@ typedef void (*PolKitContextFileMonitorRemoveWatch) (PolKitContext
PolKitContext *polkit_context_new (void);
void polkit_context_set_config_changed (PolKitContext *pk_context,
PolKitContextConfigChangedCB cb,
void *user_data);
PolKitContextConfigChangedCB cb,
void *user_data);
void polkit_context_set_file_monitor (PolKitContext *pk_context,
PolKitContextFileMonitorAddWatch add_watch_func,
PolKitContextFileMonitorRemoveWatch remove_watch_func);
PolKitContextFileMonitorAddWatch add_watch_func,
PolKitContextFileMonitorRemoveWatch remove_watch_func);
void polkit_context_set_load_descriptions (PolKitContext *pk_context);
polkit_bool_t polkit_context_init (PolKitContext *pk_context,
PolKitError **error);
PolKitError **error);
PolKitContext *polkit_context_ref (PolKitContext *pk_context);
void polkit_context_unref (PolKitContext *pk_context);
......@@ -161,25 +162,25 @@ typedef void (*PolKitSeatVisitorCB) (PolKitSeat *seat,
PolKitResult
polkit_context_get_seat_resource_association (PolKitContext *pk_context,
PolKitSeatVisitorCB visitor,
void *user_data);
PolKitSeatVisitorCB visitor,
void *user_data);
PolKitResult
polkit_context_is_resource_associated_with_seat (PolKitContext *pk_context,
PolKitResource *resource,
PolKitSeat *seat);
PolKitResource *resource,
PolKitSeat *seat);
PolKitResult
polkit_context_can_session_access_resource (PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session);
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session);
PolKitResult
polkit_context_can_caller_access_resource (PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller);
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller);
#endif /* POLKIT_CONTEXT_H */
......
......@@ -47,6 +47,7 @@
#include "polkit-types.h"
#include "polkit-error.h"
#include "polkit-debug.h"
/**
* PolKitError:
......@@ -123,7 +124,7 @@ polkit_error_set_error (PolKitError **error, PolKitErrorCode error_code, const c
va_list args;
PolKitError *e;
if (*error == NULL)
if (error == NULL)
return;
e = g_new0 (PolKitError, 1);
......@@ -135,6 +136,3 @@ polkit_error_set_error (PolKitError **error, PolKitErrorCode error_code, const c
*error = e;
}
......@@ -74,17 +74,10 @@ _append_entry (PolKitPolicyFile *policy_file,
policy_cache->priv_entries = g_slist_append (policy_cache->priv_entries, policy_file_entry);
}
/**
* polkit_policy_cache_new:
* @dirname: directory containing policy files
* @error: location to return error
*
* Create a new #PolKitPolicyCache object and load information from policy files.
*
* Returns: #NULL if @error was set, otherwise the #PolKitPolicyCache object
**/
extern PolKitPolicyCache *_polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions, PolKitError **error);
PolKitPolicyCache *
polkit_policy_cache_new (const char *dirname, PolKitError **error)
_polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions, PolKitError **error)
{
const char *file;
GDir *dir;
......@@ -117,7 +110,7 @@ polkit_policy_cache_new (const char *dirname, PolKitError **error)
path = g_strdup_printf ("%s/%s", dirname, file);
_pk_debug ("Loading %s", path);
pf = polkit_policy_file_new (path, error);
pf = polkit_policy_file_new (path, load_descriptions, error);
g_free (path);
if (pf == NULL) {
......@@ -246,3 +239,28 @@ polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache,
out:
return pfe;
}
/**
* polkit_policy_cache_foreach:
* @policy_cache: the policy cache
* @callback: callback function
* @user_data: user data to pass to callback function
*
* Visit all entries in the policy cache.
**/
void
polkit_policy_cache_foreach (PolKitPolicyCache *policy_cache,
PolKitPolicyCacheForeachFunc callback,
void *user_data)
{
GSList *i;
PolKitPolicyFileEntry *pfe;
g_return_if_fail (policy_cache != NULL);
g_return_if_fail (callback != NULL);
for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
pfe = i->data;
callback (policy_cache, pfe, user_data);
}
}
......@@ -37,13 +37,26 @@
struct PolKitPolicyCache;
typedef struct PolKitPolicyCache PolKitPolicyCache;
PolKitPolicyCache *polkit_policy_cache_new (const char *dirname, PolKitError **error);
PolKitPolicyCache *polkit_policy_cache_ref (PolKitPolicyCache *policy_cache);
void polkit_policy_cache_unref (PolKitPolicyCache *policy_cache);
void polkit_policy_cache_debug (PolKitPolicyCache *policy_cache);
PolKitPolicyFileEntry* polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache,
PolKitAction *action);
/**
* PolKitPolicyCacheForeachFunc:
* @policy_cache: the policy cache
* @entry: an entry in the cache - do not unref
* @user_data: user data passed to polkit_policy_cache_foreach()
*
* Callback function for polkit_policy_cache_foreach().
**/
typedef void (*PolKitPolicyCacheForeachFunc) (PolKitPolicyCache *policy_cache,
PolKitPolicyFileEntry *entry,
void *user_data);
PolKitPolicyCache *polkit_policy_cache_ref (PolKitPolicyCache *policy_cache);
void polkit_policy_cache_unref (PolKitPolicyCache *policy_cache);
void polkit_policy_cache_debug (PolKitPolicyCache *policy_cache);
PolKitPolicyFileEntry* polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache,
PolKitAction *action);
void polkit_policy_cache_foreach (PolKitPolicyCache *policy_cache,
PolKitPolicyCacheForeachFunc callback,
void *user_data);
#endif /* POLKIT_POLICY_CACHE_H */
......
......@@ -63,96 +63,26 @@ struct PolKitPolicyDefault
PolKitResult default_local_active;
};
static gboolean
parse_default (const char *key, char *s, const char *group, PolKitResult* target, PolKitError **error)
{
gboolean ret;
ret = polkit_result_from_string_representation (s, target);
if (!ret) {
int n;
char *s2;
GString *str;
str = g_string_new (NULL);
for (n = 0; n < POLKIT_RESULT_N_RESULTS; n++) {
if (n == POLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW)
continue;
if (str->len > 0) {
g_string_append (str, ", ");
}
g_string_append (str, polkit_result_to_string_representation (n));
}
s2 = g_string_free (str, FALSE);
polkit_error_set_error (error,
POLKIT_ERROR_POLICY_FILE_INVALID,
"Value '%s' is not allowed for key '%s' in group '%s'; "
"supported values are: %s",
s,
key,
group,
s2);
g_free (s2);
}
g_free (s);
return ret;
}
extern PolKitPolicyDefault *_polkit_policy_default_new (GKeyFile *key_file, const char *action, PolKitError **error);
extern PolKitPolicyDefault *_polkit_policy_default_new (PolKitResult defaults_allow_remote_inactive,
PolKitResult defaults_allow_remote_active,
PolKitResult defaults_allow_local_inactive,
PolKitResult defaults_allow_local_active);
PolKitPolicyDefault *
_polkit_policy_default_new (GKeyFile *key_file, const char *action, PolKitError **error)
_polkit_policy_default_new (PolKitResult defaults_allow_remote_inactive,
PolKitResult defaults_allow_remote_active,
PolKitResult defaults_allow_local_inactive,
PolKitResult defaults_allow_local_active)
{
const char *key;
const char *group;
char *s;
char buf[256];
PolKitPolicyDefault *pd;
GError *g_error;
pd = g_new0 (PolKitPolicyDefault, 1);
pd->refcount = 1;
g_snprintf (buf, sizeof (buf), "Action %s", action);
group = buf;
g_error = NULL;
key = "AllowRemoteInactive";
if ((s = g_key_file_get_string (key_file, group, key, &g_error)) == NULL)
goto error;
if (!parse_default (key, s, group, &pd->default_remote_inactive, error))
goto error;
key = "AllowRemoteActive";
if ((s = g_key_file_get_string (key_file, group, key, &g_error)) == NULL)
goto error;
if (!parse_default (key, s, group, &pd->default_remote_active, error))
goto error;
key = "AllowLocalInactive";
if ((s = g_key_file_get_string (key_file, group, key, &g_error)) == NULL)
goto error;
if (!parse_default (key, s, group, &pd->default_local_inactive, error))
goto error;
key = "AllowLocalActive";
if ((s = g_key_file_get_string (key_file, group, key, &g_error)) == NULL)
goto error;
if (!parse_default (key, s, group, &pd->default_local_active, error))
goto error;
pd->default_remote_inactive = defaults_allow_remote_inactive;
pd->default_remote_active = defaults_allow_remote_active;
pd->default_local_inactive = defaults_allow_local_inactive;
pd->default_local_active = defaults_allow_local_active;
return pd;
error:
if (g_error != NULL) {
polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID,
"Missing key in policy file: %s",
g_error->message);
g_error_free (g_error);
}
if (pd != NULL)
polkit_policy_default_ref (pd);
return NULL;
}
/**
......@@ -320,3 +250,64 @@ polkit_policy_default_can_caller_access_resource (PolKitPolicyDefault *policy_de
out:
return ret;
}
/**
* polkit_policy_default_get_allow_remote_inactive:
* @policy_default: the object
*
* Get default policy.
*
* Returns: default policy
**/
PolKitResult
polkit_policy_default_get_allow_remote_inactive (PolKitPolicyDefault *policy_default)
{
g_return_val_if_fail (policy_default != NULL, POLKIT_RESULT_NO);
return policy_default->default_remote_inactive;
}
/**
* polkit_policy_default_get_allow_remote_active:
* @policy_default: the object
*
* Get default policy.
*
* Returns: default policy
**/
PolKitResult
polkit_policy_default_get_allow_remote_active (PolKitPolicyDefault *policy_default)
{
g_return_val_if_fail (policy_default != NULL, POLKIT_RESULT_NO);
return policy_default->default_remote_active;
}
/**
* polkit_policy_default_get_allow_local_inactive:
* @policy_default: the object
*
* Get default policy.
*
* Returns: default policy
**/
PolKitResult
polkit_policy_default_get_allow_local_inactive (PolKitPolicyDefault *policy_default)
{
g_return_val_if_fail (policy_default != NULL, POLKIT_RESULT_NO);
return policy_default->default_local_inactive;
}
/**
* polkit_policy_default_get_allow_local_active:
* @policy_default: the object
*
* Get default policy.
*
* Returns: default policy
**/
PolKitResult
polkit_policy_default_get_allow_local_active (PolKitPolicyDefault *policy_default)
{
g_return_val_if_fail (policy_default != NULL, POLKIT_RESULT_NO);
return policy_default->default_local_active;
}
......@@ -45,13 +45,18 @@ void polkit_policy_default_unref (PolKitPolicyDefault *policy
void polkit_policy_default_debug (PolKitPolicyDefault *policy_default);
PolKitResult polkit_policy_default_can_session_access_resource (PolKitPolicyDefault *policy_default,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session);
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session);
PolKitResult polkit_policy_default_can_caller_access_resource (PolKitPolicyDefault *policy_default,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller);
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller);
PolKitResult polkit_policy_default_get_allow_remote_inactive (PolKitPolicyDefault *policy_default);
PolKitResult polkit_policy_default_get_allow_remote_active (PolKitPolicyDefault *policy_default);
PolKitResult polkit_policy_default_get_allow_local_inactive (PolKitPolicyDefault *policy_default);
PolKitResult polkit_policy_default_get_allow_local_active (PolKitPolicyDefault *policy_default);
/* TODO: export knobs for "default policy" */
......
......@@ -59,24 +59,55 @@ struct PolKitPolicyFileEntry
{
int refcount;
char *action;
char *group;
PolKitPolicyDefault *defaults;
char *group_description;
char *group_description_short;
char *policy_description;
char *policy_missing;
char *policy_apply_all_mnemonic;
};
PolKitPolicyFileEntry *
_polkit_policy_file_entry_new (GKeyFile *key_file, const char *action, PolKitError **error);
extern void _polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *pfe,
const char *group_description,
const char *group_description_short,
const char *policy_description,
const char *policy_missing,
const char *policy_apply_all_mnemonic);
extern PolKitPolicyDefault *_polkit_policy_default_new (GKeyFile *key_file, const char *action, PolKitError **error);
extern PolKitPolicyDefault *_polkit_policy_default_new (PolKitResult defaults_allow_remote_inactive,
PolKitResult defaults_allow_remote_active,
PolKitResult defaults_allow_local_inactive,
PolKitResult defaults_allow_local_active);
extern PolKitPolicyFileEntry *_polkit_policy_file_entry_new (const char *action_group_id,
const char *action_id,
PolKitResult defaults_allow_remote_inactive,
PolKitResult defaults_allow_remote_active,
PolKitResult defaults_allow_local_inactive,
PolKitResult defaults_allow_local_active);
extern PolKitPolicyFileEntry *
_polkit_policy_file_entry_new (GKeyFile *key_file, const char *action, PolKitError **error)
_polkit_policy_file_entry_new (const char *action_group_id,
const char *action_id,
PolKitResult defaults_allow_remote_inactive,
PolKitResult defaults_allow_remote_active,
PolKitResult defaults_allow_local_inactive,
PolKitResult defaults_allow_local_active)
{
PolKitPolicyFileEntry *pfe;
pfe = g_new0 (PolKitPolicyFileEntry, 1);
pfe->refcount = 1;
pfe->action = g_strdup (action);
pfe->action = g_strdup (action_id);
pfe->group = g_strdup (action_group_id);
pfe->defaults = _polkit_policy_default_new (key_file, action, error);
pfe->defaults = _polkit_policy_default_new (defaults_allow_remote_inactive,
defaults_allow_remote_active,
defaults_allow_local_inactive,
defaults_allow_local_active);
if (pfe->defaults == NULL)
goto error;
......@@ -87,6 +118,127 @@ error:
return NULL;
}
void
_polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *policy_file_entry,
const char *group_description,
const char *group_description_short,