PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sun Apr 22 18:13:17 PDT 2007
configure.in | 14 +
policy/polkit-example-action.policy | 34 +-
polkit-grant/polkit-grant.c | 13 -
polkit-grant/polkit-grant.h | 2
polkit/Makefile.am | 2
polkit/polkit-context.c | 27 ++
polkit/polkit-context.h | 31 +-
polkit/polkit-error.c | 6
polkit/polkit-policy-cache.c | 40 ++-
polkit/polkit-policy-cache.h | 25 +-
polkit/polkit-policy-default.c | 155 ++++++-------
polkit/polkit-policy-default.h | 17 -
polkit/polkit-policy-file-entry.c | 189 +++++++++++++++-
polkit/polkit-policy-file-entry.h | 11
polkit/polkit-policy-file.c | 420 +++++++++++++++++++++++++++++++-----
polkit/polkit-policy-file.h | 4
tools/Makefile.am | 5
tools/polkit-list-actions.c | 143 ++++++++++++
tools/polkit-policy-file-validate.c | 2
19 files changed, 934 insertions(+), 206 deletions(-)
New commits:
diff-tree b9cf5bca49a2a1fc68002c2a315d94a3adaed51e (from 5cfae846d1c2b0cbef3dcebc909e2846bcc3cc4b)
Author: David Zeuthen <davidz at redhat.com>
Date: Sun Apr 22 21:13:17 2007 -0400
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.
diff --git a/configure.in b/configure.in
index ae55f16..2eb6b95 100644
--- a/configure.in
+++ b/configure.in
@@ -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])
diff --git a/policy/polkit-example-action.policy b/policy/polkit-example-action.policy
index 5204398..761ccf3 100644
--- a/policy/polkit-example-action.policy
+++ b/policy/polkit-example-action.policy
@@ -1,15 +1,23 @@
-# -*- 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>
diff --git a/polkit-grant/polkit-grant.c b/polkit-grant/polkit-grant.c
index 0197aa9..d73a0aa 100644
--- a/polkit-grant/polkit-grant.c
+++ b/polkit-grant/polkit-grant.c
@@ -221,11 +221,17 @@ polkit_grant_set_functions (PolKitGrant
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 *p
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);
}
/**
diff --git a/polkit-grant/polkit-grant.h b/polkit-grant/polkit-grant.h
index 0339f3d..cc04d42 100644
--- a/polkit-grant/polkit-grant.h
+++ b/polkit-grant/polkit-grant.h
@@ -196,6 +196,7 @@ typedef PolKitResult (*PolKitGrantOverri
* 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 (*PolKitGrantOverri
**/
typedef void (*PolKitGrantDone) (PolKitGrant *polkit_grant,
polkit_bool_t gained_privilege,
+ polkit_bool_t invalid_data,
void *user_data);
/**
diff --git a/polkit/Makefile.am b/polkit/Makefile.am
index 0b3bbb1..5313952 100644
--- a/polkit/Makefile.am
+++ b/polkit/Makefile.am
@@ -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)
diff --git a/polkit/polkit-context.c b/polkit/polkit-context.c
index a1248fd..0e17aa2 100644
--- a/polkit/polkit-context.c
+++ b/polkit/polkit-context.c
@@ -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_
* 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 (PolKi
* @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 (PolKitC
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 (PolKitC
_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));
diff --git a/polkit/polkit-context.h b/polkit/polkit-context.h
index 5963abe..13d53bf 100644
--- a/polkit/polkit-context.h
+++ b/polkit/polkit-context.h
@@ -135,13 +135,14 @@ typedef void (*PolKitContextFileMonitorR
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) (Pol
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 */
diff --git a/polkit/polkit-error.c b/polkit/polkit-error.c
index cec8cc4..0d20c69 100644
--- a/polkit/polkit-error.c
+++ b/polkit/polkit-error.c
@@ -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 **er
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 **er
*error = e;
}
-
-
-
diff --git a/polkit/polkit-policy-cache.c b/polkit/polkit-policy-cache.c
index dc9a93a..461583d 100644
--- a/polkit/polkit-policy-cache.c
+++ b/polkit/polkit-policy-cache.c
@@ -74,17 +74,10 @@ _append_entry (PolKitPolicyFile *p
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 *dir
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 (PolKitPol
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);
+ }
+}
diff --git a/polkit/polkit-policy-cache.h b/polkit/polkit-policy-cache.h
index 7ed7e4d..c7d89c5 100644
--- a/polkit/polkit-policy-cache.h
+++ b/polkit/polkit-policy-cache.h
@@ -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);
+/**
+ * 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);
-PolKitPolicyFileEntry* polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache,
- PolKitAction *action);
+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 */
diff --git a/polkit/polkit-policy-default.c b/polkit/polkit-policy-default.c
index 8ab2110..074fb93 100644
--- a/polkit/polkit-policy-default.c
+++ b/polkit/polkit-policy-default.c
@@ -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_
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;
+}
+
diff --git a/polkit/polkit-policy-default.h b/polkit/polkit-policy-default.h
index 2dda732..9dad92c 100644
--- a/polkit/polkit-policy-default.h
+++ b/polkit/polkit-policy-default.h
@@ -45,13 +45,18 @@ void polkit_policy_de
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" */
diff --git a/polkit/polkit-policy-file-entry.c b/polkit/polkit-policy-file-entry.c
index 8e5c172..f72c87c 100644
--- a/polkit/polkit-policy-file-entry.c
+++ b/polkit/polkit-policy-file-entry.c
@@ -59,24 +59,55 @@ struct PolKitPolicyFileEntry
{
int refcount;
char *action;
+ char *group;
PolKitPolicyDefault *defaults;
-};
-PolKitPolicyFileEntry *
-_polkit_policy_file_entry_new (GKeyFile *key_file, const char *action, PolKitError **error);
+ char *group_description;
+ char *group_description_short;
+ char *policy_description;
+ char *policy_missing;
+ char *policy_apply_all_mnemonic;
+};
-extern PolKitPolicyDefault *_polkit_policy_default_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 (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,
+ const char *policy_description,
+ const char *policy_missing,
+ const char *policy_apply_all_mnemonic)
+{
+ g_return_if_fail (policy_file_entry != NULL);
+ policy_file_entry->group_description = g_strdup (group_description);
+ policy_file_entry->group_description_short = g_strdup (group_description_short);
+ policy_file_entry->policy_description = g_strdup (policy_description);
+ policy_file_entry->policy_missing = g_strdup (policy_missing);
+ policy_file_entry->policy_apply_all_mnemonic = g_strdup (policy_apply_all_mnemonic);
+}
+
+/**
+ * polkit_policy_file_get_group_description:
+ * @policy_file_entry: the object
+ *
+ * Get the description of the group that this policy entry describes.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ *
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_group_description (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->group_description;
+}
+
+/**
+ * polkit_policy_file_get_group_description_short:
+ * @policy_file_entry: the object
+ *
+ * Get the short description of the group that this policy entry describes.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ *
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_group_description_short (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->group_description_short;
+}
+
+/**
+ * polkit_policy_file_get_action_description:
+ * @policy_file_entry: the object
+ *
+ * Get the description of the action that this policy entry describes.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ *
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_action_description (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->policy_description;
+}
+
+/**
+ * polkit_policy_file_get_action_missing:
+ * @policy_file_entry: the object
+ *
+ * Get a phrase, for the policy entry in question, that can be shown
+ * in the user interface explaining that the caller doesn't possess
+ * the privilege to perform the given action on the given resource.
+ *
+ * The returned string may contain a single %s entry - the caller
+ * should use a printf-style function to replace this with a human
+ * readable description of the resource in question.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ *
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_action_missing (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->policy_missing;
+}
+
+/**
+ * polkit_policy_file_get_action_apply_to_all_mnemonic:
+ * @policy_file_entry: the object
+ *
+ * Get a phrase, for the policy entry in question, that can be shown
+ * in the user interface for a checkbox whether the grant of a
+ * privilege should apply to all resources. The string may contain a
+ * single underscore to indicate a mnemonic shortcut.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ *
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_action_apply_to_all_mnemonic (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->policy_apply_all_mnemonic;
+}
+
+
/**
* polkit_policy_file_entry_ref:
* @policy_file_entry: the policy file object
@@ -121,6 +273,13 @@ polkit_policy_file_entry_unref (PolKitPo
g_free (policy_file_entry->action);
if (policy_file_entry->defaults != NULL)
polkit_policy_default_unref (policy_file_entry->defaults);
+
+ g_free (policy_file_entry->group_description);
+ g_free (policy_file_entry->group_description_short);
+ g_free (policy_file_entry->policy_description);
+ g_free (policy_file_entry->policy_missing);
+ g_free (policy_file_entry->policy_apply_all_mnemonic);
+
g_free (policy_file_entry);
}
@@ -156,6 +315,22 @@ polkit_policy_file_entry_get_id (PolKitP
}
/**
+ * polkit_policy_file_entry_get_group_id:
+ * @policy_file_entry: the file entry
+ *
+ * Get the action group identifier.
+ *
+ * Returns: A string - caller shall not free this string.
+ **/
+const char *
+polkit_policy_file_entry_get_group_id (PolKitPolicyFileEntry *policy_file_entry)
+{
+ g_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->group;
+}
+
+
+/**
* polkit_policy_file_entry_get_default:
* @policy_file_entry: the file entry
*
diff --git a/polkit/polkit-policy-file-entry.h b/polkit/polkit-policy-file-entry.h
index 1fd11b5..5e0b310 100644
--- a/polkit/polkit-policy-file-entry.h
+++ b/polkit/polkit-policy-file-entry.h
@@ -40,8 +40,15 @@ PolKitPolicyFileEntry *polkit_policy_fil
void polkit_policy_file_entry_unref (PolKitPolicyFileEntry *policy_file_entry);
void polkit_policy_file_entry_debug (PolKitPolicyFileEntry *policy_file_entry);
-const char *polkit_policy_file_entry_get_id (PolKitPolicyFileEntry *policy_file_entry);
-PolKitPolicyDefault *polkit_policy_file_entry_get_default (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_entry_get_id (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_entry_get_group_id (PolKitPolicyFileEntry *policy_file_entry);
+PolKitPolicyDefault *polkit_policy_file_entry_get_default (PolKitPolicyFileEntry *policy_file_entry);
+
+const char *polkit_policy_file_get_group_description (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_get_group_description_short (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_get_action_description (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_get_action_missing (PolKitPolicyFileEntry *policy_file_entry);
+const char *polkit_policy_file_get_action_apply_to_all_mnemonic (PolKitPolicyFileEntry *policy_file_entry);
#endif /* POLKIT_POLICY_FILE_ENTRY_H */
diff --git a/polkit/polkit-policy-file.c b/polkit/polkit-policy-file.c
index 04b23dc..043fe90 100644
--- a/polkit/polkit-policy-file.c
+++ b/polkit/polkit-policy-file.c
@@ -36,11 +36,14 @@
#include <unistd.h>
#include <errno.h>
+#include <expat.h>
+
#include <glib.h>
#include "polkit-error.h"
#include "polkit-result.h"
#include "polkit-policy-file.h"
#include "polkit-policy-file-entry.h"
+#include "polkit-debug.h"
/**
* SECTION:polkit-policy-file
@@ -61,34 +64,331 @@ struct PolKitPolicyFile
GSList *entries;
};
-extern PolKitPolicyFileEntry *_polkit_policy_file_entry_new (GKeyFile *keyfile,
- const char *action,
- PolKitError **error);
+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);
+
+enum {
+ STATE_NONE,
+ STATE_IN_POLICY_CONFIG,
+ STATE_IN_GROUP,
+ STATE_IN_GROUP_DESCRIPTION,
+ STATE_IN_GROUP_DESCRIPTION_SHORT,
+ STATE_IN_POLICY,
+ STATE_IN_POLICY_DESCRIPTION,
+ STATE_IN_POLICY_MISSING,
+ STATE_IN_POLICY_APPLY_TO_ALL_MNEMONIC,
+ STATE_IN_DEFAULTS,
+ STATE_IN_DEFAULTS_ALLOW_REMOTE_INACTIVE,
+ STATE_IN_DEFAULTS_ALLOW_REMOTE_ACTIVE,
+ STATE_IN_DEFAULTS_ALLOW_LOCAL_INACTIVE,
+ STATE_IN_DEFAULTS_ALLOW_LOCAL_ACTIVE
+};
+
+typedef struct {
+ XML_Parser parser;
+ int state;
+ char *group_id;
+ char *action_id;
+
+ PolKitResult defaults_allow_remote_inactive;
+ PolKitResult defaults_allow_remote_active;
+ PolKitResult defaults_allow_local_inactive;
+ PolKitResult defaults_allow_local_active;
+
+ PolKitPolicyFile *pf;
+
+ polkit_bool_t load_descriptions;
+
+ char *group_description;
+ char *group_description_short;
+ char *policy_description;
+ char *policy_missing;
+ char *policy_apply_all_mnemonic;
+} ParserData;
+
+static void
+_start (void *data, const char *el, const char **attr)
+{
+ int state;
+ int num_attr;
+ ParserData *pd = data;
+
+ for (num_attr = 0; attr[num_attr] != NULL; num_attr++)
+ ;
+
+ state = STATE_NONE;
+
+ switch (pd->state) {
+ case STATE_NONE:
+ if (strcmp (el, "policyconfig") == 0) {
+ state = STATE_IN_POLICY_CONFIG;
+ }
+ break;
+ case STATE_IN_POLICY_CONFIG:
+ if (strcmp (el, "group") == 0) {
+ if (num_attr != 2 || strcmp (attr[0], "id") != 0)
+ goto error;
+ g_free (pd->group_id);
+ pd->group_id = g_strdup (attr[1]);
+ state = STATE_IN_GROUP;
+
+ g_free (pd->group_description);
+ g_free (pd->group_description_short);
+ pd->group_description = NULL;
+ pd->group_description_short = NULL;
+ }
+ break;
+ case STATE_IN_GROUP:
+ if (strcmp (el, "policy") == 0) {
+ if (num_attr != 2 || strcmp (attr[0], "id") != 0)
+ goto error;
+ g_free (pd->action_id);
+ pd->action_id = g_strdup (attr[1]);
+ state = STATE_IN_POLICY;
+
+ pd->policy_description = NULL;
+ pd->policy_missing = NULL;
+ pd->policy_apply_all_mnemonic = NULL;
+
+ /* initialize defaults */
+ pd->defaults_allow_remote_inactive = POLKIT_RESULT_NO;
+ pd->defaults_allow_remote_active = POLKIT_RESULT_NO;
+ pd->defaults_allow_local_inactive = POLKIT_RESULT_NO;
+ pd->defaults_allow_local_active = POLKIT_RESULT_NO;
+ }
+ else if (strcmp (el, "description") == 0)
+ state = STATE_IN_GROUP_DESCRIPTION;
+ else if (strcmp (el, "description_short") == 0)
+ state = STATE_IN_GROUP_DESCRIPTION_SHORT;
+ break;
+ case STATE_IN_GROUP_DESCRIPTION:
+ break;
+ case STATE_IN_GROUP_DESCRIPTION_SHORT:
+ break;
+ case STATE_IN_POLICY:
+ if (strcmp (el, "defaults") == 0)
+ state = STATE_IN_DEFAULTS;
+ else if (strcmp (el, "description") == 0)
+ state = STATE_IN_POLICY_DESCRIPTION;
+ else if (strcmp (el, "missing") == 0)
+ state = STATE_IN_POLICY_MISSING;
+ else if (strcmp (el, "apply_to_all_mnemonic") == 0)
+ state = STATE_IN_POLICY_APPLY_TO_ALL_MNEMONIC;
+ break;
+ case STATE_IN_POLICY_DESCRIPTION:
+ break;
+ case STATE_IN_POLICY_MISSING:
+ break;
+ case STATE_IN_POLICY_APPLY_TO_ALL_MNEMONIC:
+ break;
+ case STATE_IN_DEFAULTS:
+ if (strcmp (el, "allow_remote_inactive") == 0)
+ state = STATE_IN_DEFAULTS_ALLOW_REMOTE_INACTIVE;
+ else if (strcmp (el, "allow_remote_active") == 0)
+ state = STATE_IN_DEFAULTS_ALLOW_REMOTE_ACTIVE;
+ else if (strcmp (el, "allow_local_inactive") == 0)
+ state = STATE_IN_DEFAULTS_ALLOW_LOCAL_INACTIVE;
+ else if (strcmp (el, "allow_local_active") == 0)
+ state = STATE_IN_DEFAULTS_ALLOW_LOCAL_ACTIVE;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_INACTIVE:
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_ACTIVE:
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_INACTIVE:
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_ACTIVE:
+ break;
+ default:
+ break;
+ }
+
+ if (state == STATE_NONE)
+ goto error;
+
+ pd->state = state;
+
+ return;
+error:
+ XML_StopParser (pd->parser, FALSE);
+}
+
+static void
+_cdata (void *data, const char *s, int len)
+{
+ char *str;
+ ParserData *pd = data;
+
+ str = g_strndup (s, len);
+ switch (pd->state) {
+
+ case STATE_IN_GROUP_DESCRIPTION:
+ if (pd->load_descriptions)
+ pd->group_description = g_strdup (str);
+ break;
+
+ case STATE_IN_GROUP_DESCRIPTION_SHORT:
+ if (pd->load_descriptions)
+ pd->group_description_short = g_strdup (str);
+ break;
+
+ case STATE_IN_POLICY_DESCRIPTION:
+ if (pd->load_descriptions)
+ pd->policy_description = g_strdup (str);
+ break;
+
+ case STATE_IN_POLICY_MISSING:
+ if (pd->load_descriptions)
+ pd->policy_missing = g_strdup (str);
+ break;
+
+ case STATE_IN_POLICY_APPLY_TO_ALL_MNEMONIC:
+ if (pd->load_descriptions)
+ pd->policy_apply_all_mnemonic = g_strdup (str);
+ break;
+
+
+
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_INACTIVE:
+ if (!polkit_result_from_string_representation (str, &pd->defaults_allow_remote_inactive))
+ goto error;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_ACTIVE:
+ if (!polkit_result_from_string_representation (str, &pd->defaults_allow_remote_active))
+ goto error;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_INACTIVE:
+ if (!polkit_result_from_string_representation (str, &pd->defaults_allow_local_inactive))
+ goto error;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_ACTIVE:
+ if (!polkit_result_from_string_representation (str, &pd->defaults_allow_local_active))
+ goto error;
+ break;
+ default:
+ break;
+ }
+ g_free (str);
+ return;
+error:
+ g_free (str);
+ XML_StopParser (pd->parser, FALSE);
+}
+
+
+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);
+
+static void
+_end (void *data, const char *el)
+{
+ int state;
+ ParserData *pd = data;
+
+ state = STATE_NONE;
+
+ switch (pd->state) {
+ case STATE_NONE:
+ break;
+ case STATE_IN_POLICY_CONFIG:
+ state = STATE_NONE;
+ break;
+ case STATE_IN_GROUP:
+ state = STATE_IN_POLICY_CONFIG;
+ break;
+ case STATE_IN_GROUP_DESCRIPTION:
+ state = STATE_IN_GROUP;
+ break;
+ case STATE_IN_GROUP_DESCRIPTION_SHORT:
+ state = STATE_IN_GROUP;
+ break;
+ case STATE_IN_POLICY:
+ {
+ PolKitPolicyFileEntry *pfe;
+
+ pfe = _polkit_policy_file_entry_new (pd->group_id, pd->action_id,
+ pd->defaults_allow_remote_inactive,
+ pd->defaults_allow_remote_active,
+ pd->defaults_allow_local_inactive,
+ pd->defaults_allow_local_active);
+ if (pfe == NULL)
+ goto error;
+
+ if (pd->load_descriptions)
+ _polkit_policy_file_entry_set_descriptions (pfe,
+ pd->group_description,
+ pd->group_description_short,
+ pd->policy_description,
+ pd->policy_missing,
+ pd->policy_apply_all_mnemonic);
+
+ pd->pf->entries = g_slist_prepend (pd->pf->entries, pfe);
+
+ state = STATE_IN_GROUP;
+ break;
+ }
+ case STATE_IN_POLICY_DESCRIPTION:
+ state = STATE_IN_POLICY;
+ break;
+ case STATE_IN_POLICY_MISSING:
+ state = STATE_IN_POLICY;
+ break;
+ case STATE_IN_POLICY_APPLY_TO_ALL_MNEMONIC:
+ state = STATE_IN_POLICY;
+ break;
+ case STATE_IN_DEFAULTS:
+ state = STATE_IN_POLICY;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_INACTIVE:
+ state = STATE_IN_DEFAULTS;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_REMOTE_ACTIVE:
+ state = STATE_IN_DEFAULTS;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_INACTIVE:
+ state = STATE_IN_DEFAULTS;
+ break;
+ case STATE_IN_DEFAULTS_ALLOW_LOCAL_ACTIVE:
+ state = STATE_IN_DEFAULTS;
+ break;
+ default:
+ break;
+ }
+
+ pd->state = state;
+
+ return;
+error:
+ XML_StopParser (pd->parser, FALSE);
+}
+
/**
* polkit_policy_file_new:
- * @path: path to policy file
- * @error: return location for error
+ * @path: path to file
+ * @load_descriptions: whether descriptions should be loaded
+ * @error: Return location for error
*
- * Create a new #PolKitPolicyFile object. If the file does not
- * validate, a human readable explanation of why will be set in
- * @error.
+ * Load a policy file.
*
- * Returns: the new object or #NULL if error is set
+ * Returns: The new object or #NULL if error is set
**/
PolKitPolicyFile *
-polkit_policy_file_new (const char *path, PolKitError **error)
+polkit_policy_file_new (const char *path, polkit_bool_t load_descriptions, PolKitError **error)
{
- GKeyFile *key_file;
PolKitPolicyFile *pf;
- char **groups;
- gsize groups_len;
- int n;
- GError *g_error;
+ ParserData pd;
+ int xml_res;
pf = NULL;
- key_file = NULL;
- groups = NULL;
if (!g_str_has_suffix (path, ".policy")) {
polkit_error_set_error (error,
@@ -97,59 +397,75 @@ polkit_policy_file_new (const char *path
goto error;
}
+ char *buf;
+ gsize buflen;
+ GError *g_error;
+
g_error = NULL;
- key_file = g_key_file_new ();
- if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &g_error)) {
+ if (!g_file_get_contents (path, &buf, &buflen, &g_error)) {
polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID,
"Cannot load PolicyKit policy file at '%s': %s",
path,
g_error->message);
g_error_free (g_error);
+ goto error;
+ }
+
+ pd.parser = XML_ParserCreate (NULL);
+ if (pd.parser == NULL) {
+ polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY,
+ "Cannot load PolicyKit policy file at '%s': %s",
+ path,
+ "No memory for parser");
goto error;
}
+ XML_SetUserData (pd.parser, &pd);
+ XML_SetElementHandler (pd.parser, _start, _end);
+ XML_SetCharacterDataHandler (pd.parser, _cdata);
pf = g_new0 (PolKitPolicyFile, 1);
pf->refcount = 1;
- groups = g_key_file_get_groups(key_file, &groups_len);
- if (groups == NULL)
- goto error;
-
- for (n = 0; groups[n] != NULL; n++) {
- const char *action;
- PolKitPolicyFileEntry *pfe;
-
- if (!g_str_has_prefix (groups[n], "Action ")) {
- polkit_error_set_error (error,
- POLKIT_ERROR_POLICY_FILE_INVALID,
- "Unknown group of name '%s'", groups[n]);
- goto error;
- }
-
- action = groups[n] + 7; /* "Action " */
- if (strlen (action) == 0) {
- polkit_error_set_error (error,
- POLKIT_ERROR_POLICY_FILE_INVALID,
- "Zero-length action name");
- goto error;
- }
+ pd.state = STATE_NONE;
+ pd.group_id = NULL;
+ pd.action_id = NULL;
+ pd.group_description = NULL;
+ pd.group_description_short = NULL;
+ pd.policy_description = NULL;
+ pd.policy_missing = NULL;
+ pd.policy_apply_all_mnemonic = NULL;
+ pd.pf = pf;
+ pd.load_descriptions = load_descriptions;
+
+ xml_res = XML_Parse (pd.parser, buf, buflen, 1);
+
+ g_free (pd.group_id);
+ g_free (pd.action_id);
+ g_free (pd.group_description);
+ g_free (pd.group_description_short);
+ g_free (pd.policy_description);
+ g_free (pd.policy_missing);
+ g_free (pd.policy_apply_all_mnemonic);
- pfe = _polkit_policy_file_entry_new (key_file, action, error);
- if (pfe == NULL)
- goto error;
- pf->entries = g_slist_prepend (pf->entries, pfe);
- }
+ if (xml_res == 0) {
+ polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID,
+ "%s:%d: parse error: %s",
+ path,
+ (int) XML_GetCurrentLineNumber (pd.parser),
+ XML_ErrorString (XML_GetErrorCode (pd.parser)));
+
+ XML_ParserFree (pd.parser);
+ g_free (buf);
+ goto error;
+ }
+ XML_ParserFree (pd.parser);
+ g_free (buf);
- g_strfreev (groups);
- g_key_file_free (key_file);
return pf;
error:
- if (groups != NULL)
- g_strfreev (groups);
- if (key_file != NULL)
- g_key_file_free (key_file);
if (pf != NULL)
polkit_policy_file_unref (pf);
+
return NULL;
}
diff --git a/polkit/polkit-policy-file.h b/polkit/polkit-policy-file.h
index 3e1baf0..bcb28f9 100644
--- a/polkit/polkit-policy-file.h
+++ b/polkit/polkit-policy-file.h
@@ -48,7 +48,9 @@ typedef void (*PolKitPolicyFileEntryFore
PolKitPolicyFileEntry *policy_file_entry,
void *user_data);
-PolKitPolicyFile *polkit_policy_file_new (const char *path, PolKitError **error);
+PolKitPolicyFile *polkit_policy_file_new (const char *path,
+ polkit_bool_t load_descriptions,
+ PolKitError **error);
PolKitPolicyFile *polkit_policy_file_ref (PolKitPolicyFile *policy_file);
void polkit_policy_file_unref (PolKitPolicyFile *policy_file);
void polkit_policy_file_entry_foreach (PolKitPolicyFile *policy_file,
diff --git a/tools/Makefile.am b/tools/Makefile.am
index eddca37..d40298d 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -11,7 +11,7 @@ INCLUDES = \
@GLIB_CFLAGS@ \
@DBUS_CFLAGS@
-bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-policy-file-validate polkit-grant
+bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-policy-file-validate polkit-grant polkit-list-actions
polkit_check_caller_SOURCES = polkit-check-caller.c
polkit_check_caller_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
@@ -25,6 +25,9 @@ polkit_policy_file_validate_LDADD = $(to
polkit_grant_SOURCES = polkit-grant.c
polkit_grant_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-grant/libpolkit-grant.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+polkit_list_actions_SOURCES = polkit-list-actions.c
+polkit_list_actions_LDADD = $(GLIB) $(top_builddir)/polkit/libpolkit.la
+
clean-local :
rm -f *~
diff --git a/tools/polkit-list-actions.c b/tools/polkit-list-actions.c
new file mode 100644
index 0000000..756c1d8
--- /dev/null
+++ b/tools/polkit-list-actions.c
@@ -0,0 +1,143 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-list-actions.c : list all registered PolicyKit actions
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <polkit/polkit.h>
+
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : polkit-list-actions [--version] [--help]\n"
+ "\n");
+ fprintf (stderr,
+ "\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "List the actions registered with PolicyKit.\n");
+}
+
+static void
+_print_entry (PolKitPolicyCache *policy_cache,
+ PolKitPolicyFileEntry *pfe,
+ void *user_data)
+{
+ const char *action_id;
+ const char *group_id;
+ PolKitPolicyDefault *def;
+ PolKitResult default_remote_inactive;
+ PolKitResult default_remote_active;
+ PolKitResult default_local_inactive;
+ PolKitResult default_local_active;
+
+ action_id = polkit_policy_file_entry_get_id (pfe);
+ group_id = polkit_policy_file_entry_get_group_id (pfe);
+ def = polkit_policy_file_entry_get_default (pfe);
+ default_remote_inactive = polkit_policy_default_get_allow_remote_inactive (def);
+ default_remote_active = polkit_policy_default_get_allow_remote_active (def);
+ default_local_inactive = polkit_policy_default_get_allow_local_inactive (def);
+ default_local_active = polkit_policy_default_get_allow_local_active (def);
+
+ printf ("Policy\n"
+ "------\n"
+ "group = %s ('%s') ('%s')\n"
+ "action = %s ('%s') ('%s') ('%s')\n"
+ "default_remote_inactive = %s\n"
+ "default_remote_active = %s\n"
+ "default_local_inactive = %s\n"
+ "default_local_active = %s\n"
+ "\n",
+ group_id,
+ polkit_policy_file_get_group_description (pfe),
+ polkit_policy_file_get_group_description_short (pfe),
+ action_id,
+ polkit_policy_file_get_action_description (pfe),
+ polkit_policy_file_get_action_missing (pfe),
+ polkit_policy_file_get_action_apply_to_all_mnemonic (pfe),
+ polkit_result_to_string_representation (default_remote_inactive),
+ polkit_result_to_string_representation (default_remote_active),
+ polkit_result_to_string_representation (default_local_inactive),
+ polkit_result_to_string_representation (default_local_active));
+}
+
+int
+main (int argc, char *argv[])
+{
+ int n;
+
+ for (n = 1; n < argc; n++) {
+ if (strcmp (argv[n], "--help") == 0) {
+ usage (argc, argv);
+ return 0;
+ }
+ if (strcmp (argv[n], "--version") == 0) {
+ printf ("polkit-list-actions " PACKAGE_VERSION "\n");
+ return 0;
+ }
+ }
+
+ int ret;
+ ret = 1;
+
+ PolKitContext *ctx;
+ PolKitPolicyCache *cache;
+ PolKitError *error;
+ ctx = polkit_context_new ();
+ if (ctx == NULL)
+ goto out;
+ error = NULL;
+ polkit_context_set_load_descriptions (ctx);
+ if (!polkit_context_init (ctx, &error)) {
+ printf ("Init failed: %s\n", polkit_error_get_error_message (error));
+ polkit_context_unref (ctx);
+ goto out;
+ }
+
+ cache = polkit_context_get_policy_cache (ctx);
+ if (cache == NULL) {
+ polkit_context_unref (ctx);
+ goto out;
+ }
+
+ polkit_policy_cache_foreach (cache, _print_entry, NULL);
+
+ polkit_context_unref (ctx);
+out:
+ return ret;
+}
diff --git a/tools/polkit-policy-file-validate.c b/tools/polkit-policy-file-validate.c
index 4bd1d76..1ad5035 100644
--- a/tools/polkit-policy-file-validate.c
+++ b/tools/polkit-policy-file-validate.c
@@ -61,7 +61,7 @@ validate_file (const char *file)
PolKitError *error;
error = NULL;
- priv_file = polkit_policy_file_new (file, &error);
+ priv_file = polkit_policy_file_new (file, TRUE, &error);
if (priv_file == NULL) {
printf ("%s did not validate: %s\n", file, polkit_error_get_error_message (error));
polkit_error_free (error);
More information about the hal-commit
mailing list