PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Thu Nov 8 12:29:57 PST 2007


 src/polkit/polkit-authorization-db-dummy.c        |    3 
 src/polkit/polkit-authorization-db.c              |    3 
 src/polkit/polkit-policy-cache.c                  |  245 ++++++++++++++++++----
 src/polkit/polkit-policy-cache.h                  |   10 
 src/polkit/polkit-policy-file-entry.c             |   25 +-
 src/polkit/polkit-policy-file-entry.h             |   12 -
 src/polkit/polkit-policy-file.c                   |   39 ++-
 src/polkit/polkit-policy-file.h                   |   14 -
 src/polkit/polkit-private.h                       |    2 
 src/polkit/polkit-test.c                          |    1 
 src/polkit/polkit-test.h                          |    1 
 test/Makefile.am                                  |   23 +-
 test/invalid/test-invalid-1-action-id.policy      |   14 +
 test/invalid/test-invalid-2-bogus-any.policy      |   14 +
 test/invalid/test-invalid-3-bogus-inactive.policy |   14 +
 test/invalid/test-invalid-4-bogus-active.policy   |   14 +
 test/invalid/test-invalid-5-max-depth.policy      |   87 +++++++
 test/test-invalid-1-action-id.policy              |   14 -
 test/test-invalid-2-bogus-any.policy              |   14 -
 test/test-invalid-3-bogus-inactive.policy         |   14 -
 test/test-invalid-4-bogus-active.policy           |   14 -
 test/test-invalid-5-max-depth.policy              |   87 -------
 test/test-valid-1.policy                          |   14 -
 test/test-valid-2-annotations.policy              |   16 -
 test/test-valid-3-lang.policy                     |   28 --
 test/test-valid-4-unknown-tags.policy             |   20 -
 test/valid/test-valid-1.policy                    |   14 +
 test/valid/test-valid-2-annotations.policy        |   27 ++
 test/valid/test-valid-3-lang.policy               |   28 ++
 test/valid/test-valid-4-unknown-tags.policy       |   20 +
 test/valid/test-valid-5-wrong-extension.policy~   |   14 +
 tools/polkit-action.c                             |    7 
 tools/polkit-auth.c                               |    8 
 33 files changed, 538 insertions(+), 322 deletions(-)

New commits:
commit 720b47b2c0ba6517755ef78d8037f96572d71e55
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Nov 8 15:26:43 2007 -0500

    add unit tests of PolKitPolicyCache

diff --git a/src/polkit/polkit-authorization-db-dummy.c b/src/polkit/polkit-authorization-db-dummy.c
index 64eecb0..30a086b 100644
--- a/src/polkit/polkit-authorization-db-dummy.c
+++ b/src/polkit/polkit-authorization-db-dummy.c
@@ -65,11 +65,12 @@ _polkit_authorization_db_new (void)
         return authdb;
 }
 
-void
+polkit_bool_t
 _polkit_authorization_db_pfe_foreach   (PolKitPolicyCache *policy_cache, 
                                         PolKitPolicyCacheForeachFunc callback,
                                         void *user_data)
 {
+        return FALSE;
 }
 
 PolKitPolicyFileEntry* 
diff --git a/src/polkit/polkit-authorization-db.c b/src/polkit/polkit-authorization-db.c
index edccfc6..3f2edee 100644
--- a/src/polkit/polkit-authorization-db.c
+++ b/src/polkit/polkit-authorization-db.c
@@ -119,11 +119,12 @@ _polkit_authorization_db_new (void)
         return authdb;
 }
 
-void
+polkit_bool_t
 _polkit_authorization_db_pfe_foreach   (PolKitPolicyCache *policy_cache, 
                                         PolKitPolicyCacheForeachFunc callback,
                                         void *user_data)
 {
+        return FALSE;
 }
 
 PolKitPolicyFileEntry* 
diff --git a/src/polkit/polkit-policy-cache.c b/src/polkit/polkit-policy-cache.c
index e9be5ea..6775238 100644
--- a/src/polkit/polkit-policy-cache.c
+++ b/src/polkit/polkit-policy-cache.c
@@ -27,6 +27,8 @@
 #  include <config.h>
 #endif
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -36,12 +38,17 @@
 #include <unistd.h>
 #include <errno.h>
 #include <syslog.h>
+#include <fcntl.h>
+#include <dirent.h>
 
 #include <glib.h>
 #include "polkit-debug.h"
 #include "polkit-policy-file.h"
 #include "polkit-policy-cache.h"
 #include "polkit-private.h"
+#include "polkit-memory.h"
+#include "polkit-list.h"
+#include "polkit-test.h"
 
 /**
  * SECTION:polkit-policy-cache
@@ -62,54 +69,74 @@ struct _PolKitPolicyCache
 {
         int refcount;
 
-        GSList *priv_entries;
+        PolKitList *priv_entries;
 };
 
 
-static void
-_append_entry (PolKitPolicyFile       *policy_file,
+static polkit_bool_t
+_prepend_entry (PolKitPolicyFile       *policy_file,
                PolKitPolicyFileEntry  *policy_file_entry,
                void                   *user_data)
 {
+        PolKitList *l;
         PolKitPolicyCache *policy_cache = user_data;
 
         polkit_policy_file_entry_ref (policy_file_entry);
-        policy_cache->priv_entries = g_slist_append (policy_cache->priv_entries, policy_file_entry);
+        l = polkit_list_prepend (policy_cache->priv_entries, policy_file_entry);
+        if (l == NULL) {
+                polkit_policy_file_entry_unref (policy_file_entry);
+                goto oom;
+        }
+        policy_cache->priv_entries = l;
+        return FALSE;
+oom:
+        return TRUE;
 }
 
 PolKitPolicyCache *
 _polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions, PolKitError **error)
 {
-        const char *file;
-        GDir *dir;
+        DIR *dir;
+        int dfd;
+        struct dirent64 *d;
         PolKitPolicyCache *pc;
-        GError *g_error;
 
-        pc = g_new0 (PolKitPolicyCache, 1);
+        dir = NULL;
+
+        pc = p_new0 (PolKitPolicyCache, 1);
+        if (pc == NULL) {
+                polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, "Out of memory");
+                goto out;
+        }
+
         pc->refcount = 1;
 
-        g_error = NULL;
-        dir = g_dir_open (dirname, 0, &g_error);
-        if (dir == NULL) {
+        dir = opendir (dirname);
+        if (dir == NULL || (dfd = dirfd (dir)) == -1) {
                 polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID,
-                                        "Cannot load policy files from directory %s: %s",
-                                        dirname,
-                                        g_error->message);
-                g_error_free (g_error);
+                                        "Cannot load policy files from directory %s: %m",
+                                        dirname);
                 goto out;
         }
-        while ((file = g_dir_read_name (dir)) != NULL) {
+
+
+        while ((d = readdir64(dir)) != NULL) {
                 char *path;
                 PolKitPolicyFile *pf;
                 PolKitError *pk_error;
+                size_t name_len;
+                char *filename;
+                static const char suffix[] = ".policy";
 
-                if (!g_str_has_suffix (file, ".policy"))
+                if (d->d_type != DT_REG)
                         continue;
 
-                if (g_str_has_prefix (file, "."))
+                filename = d->d_name;
+                name_len = strlen (filename);
+                if (name_len < sizeof (suffix) || strcmp ((filename + name_len - sizeof (suffix) + 1), suffix) != 0)
                         continue;
 
-                path = g_strdup_printf ("%s/%s", dirname, file);
+                path = g_strdup_printf ("%s/%s", dirname, filename);
 
                 _pk_debug ("Loading %s", path);
                 pk_error = NULL;
@@ -117,6 +144,11 @@ _polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions,
                 g_free (path);
 
                 if (pf == NULL) {
+                        if (polkit_error_get_error_code (pk_error) == POLKIT_ERROR_OUT_OF_MEMORY) {
+                                polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, "Out of memory");
+                                goto out;
+                        }
+
                         _pk_debug ("libpolkit: ignoring malformed policy file: %s", 
                                    polkit_error_get_error_message (pk_error));
                         syslog (LOG_ALERT, "libpolkit: ignoring malformed policy file: %s", 
@@ -126,15 +158,23 @@ _polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions,
                 }
 
                 /* steal entries */
-                polkit_policy_file_entry_foreach (pf, _append_entry, pc);
+                if (polkit_policy_file_entry_foreach (pf, _prepend_entry, pc)) {
+                        /* OOM failure */
+                        polkit_policy_file_unref (pf);
+                        polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, "Out of memory");
+                        goto out;
+                }
                 polkit_policy_file_unref (pf);
         }
-        g_dir_close (dir);
+        closedir(dir);
 
         return pc;
 out:
+        if (dir != NULL)
+                closedir(dir);
+
         if (pc != NULL)
-                polkit_policy_cache_ref (pc);
+                polkit_policy_cache_unref (pc);
         return NULL;
 }
 
@@ -165,21 +205,21 @@ polkit_policy_cache_ref (PolKitPolicyCache *policy_cache)
 void
 polkit_policy_cache_unref (PolKitPolicyCache *policy_cache)
 {
-        GSList *i;
+        PolKitList *i;
 
         g_return_if_fail (policy_cache != NULL);
         policy_cache->refcount--;
         if (policy_cache->refcount > 0) 
                 return;
 
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+        for (i = policy_cache->priv_entries; i != NULL; i = i->next) {
                 PolKitPolicyFileEntry *pfe = i->data;
                 polkit_policy_file_entry_unref (pfe);
         }
         if (policy_cache->priv_entries != NULL)
-                g_slist_free (policy_cache->priv_entries);
+                polkit_list_free (policy_cache->priv_entries);
 
-        g_free (policy_cache);
+        p_free (policy_cache);
 }
 
 /**
@@ -191,14 +231,14 @@ polkit_policy_cache_unref (PolKitPolicyCache *policy_cache)
 void
 polkit_policy_cache_debug (PolKitPolicyCache *policy_cache)
 {
-        GSList *i;
+        PolKitList *i;
         g_return_if_fail (policy_cache != NULL);
 
         _pk_debug ("PolKitPolicyCache: refcount=%d num_entries=%d ...", 
                    policy_cache->refcount,
-                   policy_cache->priv_entries == NULL ? 0 : g_slist_length (policy_cache->priv_entries));
+                   policy_cache->priv_entries == NULL ? 0 : polkit_list_length (policy_cache->priv_entries));
 
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+        for (i = policy_cache->priv_entries; i != NULL; i = i->next) {
                 PolKitPolicyFileEntry *pfe = i->data;
                 polkit_policy_file_entry_debug (pfe);
         }
@@ -220,7 +260,7 @@ polkit_policy_cache_debug (PolKitPolicyCache *policy_cache)
 PolKitPolicyFileEntry* 
 polkit_policy_cache_get_entry_by_id (PolKitPolicyCache *policy_cache, const char *action_id)
 {
-        GSList *i;
+        PolKitList *i;
         PolKitPolicyFileEntry *pfe;
 
         g_return_val_if_fail (policy_cache != NULL, NULL);
@@ -228,12 +268,13 @@ polkit_policy_cache_get_entry_by_id (PolKitPolicyCache *policy_cache, const char
 
         pfe = NULL;
 
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+        for (i = policy_cache->priv_entries; i != NULL; i = i->next) {
                 pfe = i->data;
                 if (strcmp (polkit_policy_file_entry_get_id (pfe), action_id) == 0) {
                         goto out;
                 }
         }
+        pfe = NULL;
 
         if (pfe == NULL) {
                 /* the authdb backend may want to synthesize pfe's */
@@ -287,27 +328,30 @@ out:
  * @user_data: user data to pass to callback function
  * 
  * Visit all entries in the policy cache.
+ *
+ * Returns: #TRUE only if iteration was short-circuited
  **/
-void
+polkit_bool_t
 polkit_policy_cache_foreach (PolKitPolicyCache *policy_cache, 
                              PolKitPolicyCacheForeachFunc callback,
                              void *user_data)
 {
-        GSList *i;
+        PolKitList *i;
         PolKitPolicyFileEntry *pfe;
 
-        g_return_if_fail (policy_cache != NULL);
-        g_return_if_fail (callback != NULL);
+        g_return_val_if_fail (policy_cache != NULL, FALSE);
+        g_return_val_if_fail (callback != NULL, FALSE);
 
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+        for (i = policy_cache->priv_entries; i != NULL; i = i->next) {
                 pfe = i->data;
-                callback (policy_cache, pfe, user_data);
+                if (callback (policy_cache, pfe, user_data))
+                        return TRUE;
         }
 
         /* the authdb backend may also want to return synthesized pfe's */
-        _polkit_authorization_db_pfe_foreach (policy_cache,
-                                              callback,
-                                              user_data);
+        return _polkit_authorization_db_pfe_foreach (policy_cache,
+                                                     callback,
+                                                     user_data);
 }
 
 /**
@@ -332,13 +376,13 @@ polkit_policy_cache_get_entry_by_annotation (PolKitPolicyCache *policy_cache,
                                              const char *annotation_key,
                                              const char *annotation_value)
 {
-        GSList *i;
+        PolKitList *i;
 
         g_return_val_if_fail (policy_cache != NULL, NULL);
         g_return_val_if_fail (annotation_key != NULL, NULL);
         g_return_val_if_fail (annotation_value != NULL, NULL);
 
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+        for (i = policy_cache->priv_entries; i != NULL; i = i->next) {
                 const char *value;
                 PolKitPolicyFileEntry *pfe = i->data;
 
@@ -353,3 +397,120 @@ polkit_policy_cache_get_entry_by_annotation (PolKitPolicyCache *policy_cache,
 
         return NULL;
 }
+
+#ifdef POLKIT_BUILD_TESTS
+
+static polkit_bool_t
+_test_count (PolKitPolicyCache *pc, PolKitPolicyFileEntry *pfe, void *user_data)
+{
+        int *counter = (int *) user_data;
+        const char *action_id;
+
+        action_id = polkit_policy_file_entry_get_id (pfe);
+        if (action_id != NULL && (strcmp (action_id, "org.example.valid1") == 0 ||
+                                  strcmp (action_id, "org.example.valid2") == 0 ||
+                                  strcmp (action_id, "org.example.valid2b") == 0 ||
+                                  strcmp (action_id, "org.example.valid3") == 0 ||
+                                  strcmp (action_id, "org.example.valid3b") == 0 ||
+                                  strcmp (action_id, "org.example.valid4") == 0)) {
+                *counter += 1;
+        }
+                    
+        return FALSE;
+}
+
+static polkit_bool_t
+_test_short_circuit (PolKitPolicyCache *pc, PolKitPolicyFileEntry *pfe, void *user_data)
+{
+        int *counter = (int *) user_data;
+        *counter += 1;
+        return TRUE;
+}
+
+static polkit_bool_t
+_run_test (void)
+{
+        PolKitError *error;
+        PolKitPolicyCache *pc;
+        PolKitPolicyFileEntry *pfe;
+        PolKitAction *a;
+        int counter;
+
+        error = NULL;
+        g_assert (_polkit_policy_cache_new (TEST_DATA_DIR "/non-existant", TRUE, &error) == NULL);
+        g_assert (polkit_error_is_set (error) && 
+                  (polkit_error_get_error_code (error) == POLKIT_ERROR_POLICY_FILE_INVALID ||
+                   polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY));
+        polkit_error_free (error);
+
+        error = NULL;
+        if ((pc = _polkit_policy_cache_new (TEST_DATA_DIR "/invalid", TRUE, &error)) == NULL) {
+                g_assert (polkit_error_is_set (error) && 
+                          polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
+                polkit_error_free (error);
+        } else {
+                polkit_policy_cache_unref (pc);
+        }
+
+        error = NULL;
+        if ((pc = _polkit_policy_cache_new (TEST_DATA_DIR "/valid", TRUE, &error)) == NULL) {
+                g_assert (polkit_error_is_set (error) && 
+                          polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
+                polkit_error_free (error);
+                goto out;
+        }
+
+        g_assert (polkit_policy_cache_get_entry_by_id (pc, "org.example.valid1") != NULL);
+        g_assert (polkit_policy_cache_get_entry_by_id (pc, "org.example.non-existant") == NULL);
+
+        pfe = polkit_policy_cache_get_entry_by_annotation (pc, "the.key1", "Some Value 1");
+        g_assert (pfe != NULL && strcmp (polkit_policy_file_entry_get_id (pfe), "org.example.valid2") == 0);
+        pfe = polkit_policy_cache_get_entry_by_annotation (pc, "the.key2", "Some Value 2");
+        g_assert (pfe != NULL && strcmp (polkit_policy_file_entry_get_id (pfe), "org.example.valid2") == 0);
+        pfe = polkit_policy_cache_get_entry_by_annotation (pc, "the.key1", "Some Value 1b");
+        g_assert (pfe != NULL && strcmp (polkit_policy_file_entry_get_id (pfe), "org.example.valid2b") == 0);
+        pfe = polkit_policy_cache_get_entry_by_annotation (pc, "the.key1", "NON-EXISTANT VALUE");
+        g_assert (pfe == NULL);
+        pfe = polkit_policy_cache_get_entry_by_annotation (pc, "NON_EXISTANT KEY", "NON-EXISTANT VALUE");
+        g_assert (pfe == NULL);
+
+        if ((a = polkit_action_new ()) != NULL) {
+                pfe = polkit_policy_cache_get_entry (pc, a);
+                g_assert (pfe == NULL);
+                if (polkit_action_set_action_id (a, "org.example.valid1")) {
+                        pfe = polkit_policy_cache_get_entry (pc, a);
+                        g_assert (pfe != NULL && strcmp (polkit_policy_file_entry_get_id (pfe), "org.example.valid1") == 0);
+                }
+                if (polkit_action_set_action_id (a, "org.example.non-existant")) {
+                        pfe = polkit_policy_cache_get_entry (pc, a);
+                        g_assert (pfe == NULL);
+                }
+
+                polkit_action_unref (a);
+        }
+
+        counter = 0;
+        polkit_policy_cache_foreach (pc, _test_count, &counter);
+        g_assert (counter == 6);
+
+        counter = 0;
+        polkit_policy_cache_foreach (pc, _test_short_circuit, &counter);
+        g_assert (counter == 1);
+
+        polkit_policy_cache_debug (pc);
+        polkit_policy_cache_ref (pc);
+        polkit_policy_cache_unref (pc);
+        polkit_policy_cache_unref (pc);
+
+out:
+        return TRUE;
+}
+
+PolKitTest _test_policy_cache = {
+        "polkit_policy_cache",
+        NULL,
+        NULL,
+        _run_test
+};
+
+#endif /* POLKIT_BUILD_TESTS */
diff --git a/src/polkit/polkit-policy-cache.h b/src/polkit/polkit-policy-cache.h
index e7e5662..b087613 100644
--- a/src/polkit/polkit-policy-cache.h
+++ b/src/polkit/polkit-policy-cache.h
@@ -47,10 +47,12 @@ typedef struct _PolKitPolicyCache PolKitPolicyCache;
  * @user_data: user data passed to polkit_policy_cache_foreach()
  *
  * Callback function for polkit_policy_cache_foreach().
+ *
+ * Returns: #TRUE to short-circuit; e.g. stop the iteration
  **/
-typedef void (*PolKitPolicyCacheForeachFunc) (PolKitPolicyCache *policy_cache,
-                                              PolKitPolicyFileEntry *entry,
-                                              void *user_data);
+typedef polkit_bool_t (*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);
@@ -64,7 +66,7 @@ PolKitPolicyFileEntry* polkit_policy_cache_get_entry_by_annotation (PolKitPolicy
                                                                     const char *annotation_key,
                                                                     const char *annotation_value);
 
-void                   polkit_policy_cache_foreach   (PolKitPolicyCache *policy_cache, 
+polkit_bool_t          polkit_policy_cache_foreach   (PolKitPolicyCache *policy_cache, 
                                                       PolKitPolicyCacheForeachFunc callback,
                                                       void *user_data);
 
diff --git a/src/polkit/polkit-policy-file-entry.c b/src/polkit/polkit-policy-file-entry.c
index 5517ea2..de37dba 100644
--- a/src/polkit/polkit-policy-file-entry.c
+++ b/src/polkit/polkit-policy-file-entry.c
@@ -290,8 +290,7 @@ _annotations_cb (PolKitHash *hash,
                  void *user_data)
 {
         _AnnotationsClosure *closure = user_data;
-        closure->cb (closure->pfe, (const char *) key, (const char *) value, closure->user_data);
-        return FALSE;
+        return closure->cb (closure->pfe, (const char *) key, (const char *) value, closure->user_data);
 }
 
 /**
@@ -301,25 +300,27 @@ _annotations_cb (PolKitHash *hash,
  * @user_data: user data to pass to the callback function
  *
  * Iterate over all annotations on the policy file entry.
+ *
+ * Returns: #TRUE only if the iteration was short-circuited
  */
-void
+polkit_bool_t
 polkit_policy_file_entry_annotations_foreach (PolKitPolicyFileEntry *policy_file_entry,
                                               PolKitPolicyFileEntryAnnotationsForeachFunc cb,
                                               void *user_data)
 {
         _AnnotationsClosure closure;
 
-        g_return_if_fail (policy_file_entry != NULL);
+        g_return_val_if_fail (policy_file_entry != NULL, FALSE);
         if (policy_file_entry->annotations == NULL)
-                return;
+                return FALSE;
 
         closure.pfe = policy_file_entry;
         closure.cb = cb;
         closure.user_data = user_data;
 
-        polkit_hash_foreach (policy_file_entry->annotations,
-                             _annotations_cb,
-                             &closure);
+        return polkit_hash_foreach (policy_file_entry->annotations,
+                                    _annotations_cb,
+                                    &closure);
 }
 
 /**
@@ -348,7 +349,7 @@ polkit_policy_file_entry_get_annotation (PolKitPolicyFileEntry *policy_file_entr
 
 #ifdef POLKIT_BUILD_TESTS
 
-static void
+static polkit_bool_t
 _pfe_cb (PolKitPolicyFileEntry *pfe,
          const char *key,
          const char *value,
@@ -360,9 +361,11 @@ _pfe_cb (PolKitPolicyFileEntry *pfe,
                 *count += 1;
         else if (strcmp (key, "a2") == 0 && strcmp (value, "v2") == 0)
                 *count += 1;
+
+        return FALSE;
 }
 
-static void
+static polkit_bool_t
 _pfe_cb2 (PolKitPolicyFileEntry *pfe,
           const char *key,
           const char *value,
@@ -370,6 +373,8 @@ _pfe_cb2 (PolKitPolicyFileEntry *pfe,
 {
         int *count = (int *) user_data;
         *count += 1;
+
+        return FALSE;
 }
 
 
diff --git a/src/polkit/polkit-policy-file-entry.h b/src/polkit/polkit-policy-file-entry.h
index 8eb88a9..1317025 100644
--- a/src/polkit/polkit-policy-file-entry.h
+++ b/src/polkit/polkit-policy-file-entry.h
@@ -47,11 +47,13 @@ typedef struct _PolKitPolicyFileEntry PolKitPolicyFileEntry;
  * @user_data: user data passed to polkit_policy_file_entry_annotations_foreach()
  *
  * Callback function for polkit_policy_file_entry_annotations_foreach().
+ *
+ * Returns: Pass #TRUE to short-circuit, e.g. stop the iteration
  **/
-typedef void (*PolKitPolicyFileEntryAnnotationsForeachFunc) (PolKitPolicyFileEntry *policy_file_entry,
-                                                             const char *key,
-                                                             const char *value,
-                                                             void *user_data);
+typedef polkit_bool_t (*PolKitPolicyFileEntryAnnotationsForeachFunc) (PolKitPolicyFileEntry *policy_file_entry,
+                                                                      const char *key,
+                                                                      const char *value,
+                                                                      void *user_data);
 
 PolKitPolicyFileEntry *polkit_policy_file_entry_ref   (PolKitPolicyFileEntry *policy_file_entry);
 void                   polkit_policy_file_entry_unref (PolKitPolicyFileEntry *policy_file_entry);
@@ -63,7 +65,7 @@ PolKitPolicyDefault   *polkit_policy_file_entry_get_default  (PolKitPolicyFileEn
 const char            *polkit_policy_file_entry_get_action_description (PolKitPolicyFileEntry *policy_file_entry);
 const char            *polkit_policy_file_entry_get_action_message (PolKitPolicyFileEntry *policy_file_entry);
 
-void                   polkit_policy_file_entry_annotations_foreach (PolKitPolicyFileEntry *policy_file_entry,
+polkit_bool_t          polkit_policy_file_entry_annotations_foreach (PolKitPolicyFileEntry *policy_file_entry,
                                                                      PolKitPolicyFileEntryAnnotationsForeachFunc cb,
                                                                      void *user_data);
 const char            *polkit_policy_file_entry_get_annotation (PolKitPolicyFileEntry *policy_file_entry,
diff --git a/src/polkit/polkit-policy-file.c b/src/polkit/polkit-policy-file.c
index 0873965..1b7d238 100644
--- a/src/polkit/polkit-policy-file.c
+++ b/src/polkit/polkit-policy-file.c
@@ -634,27 +634,32 @@ polkit_policy_file_unref (PolKitPolicyFile *policy_file)
  * @user_data: user data
  * 
  * Visits all entries in a policy file.
+ *
+ * Returns: #TRUE if the iteration was short-circuited
  **/
-void
+polkit_bool_t
 polkit_policy_file_entry_foreach (PolKitPolicyFile                 *policy_file,
                                   PolKitPolicyFileEntryForeachFunc  cb,
                                   void                              *user_data)
 {
         PolKitList *i;
 
-        g_return_if_fail (policy_file != NULL);
-        g_return_if_fail (cb != NULL);
+        g_return_val_if_fail (policy_file != NULL, FALSE);
+        g_return_val_if_fail (cb != NULL, FALSE);
 
         for (i = policy_file->entries; i != NULL; i = i->next) {
                 PolKitPolicyFileEntry *pfe = i->data;
-                cb (policy_file, pfe, user_data);
+                if (cb (policy_file, pfe, user_data))
+                        return TRUE;
         }
+
+        return FALSE;
 }
 
 #ifdef POLKIT_BUILD_TESTS
 
 /* this checks that the policy descriptions read from test-valid-3-lang.policy are correct */
-static void
+static polkit_bool_t
 _check_pf (PolKitPolicyFile *pf, PolKitPolicyFileEntry *pfe, void *user_data)
 {
         const char *r_msg;
@@ -705,6 +710,8 @@ _check_pf (PolKitPolicyFile *pf, PolKitPolicyFileEntry *pfe, void *user_data)
                     strcmp (r_msg, msg) == 0) 
                         *counter += 1;
         }
+
+        return FALSE;
 }
 
 static polkit_bool_t
@@ -715,19 +722,19 @@ _run_test (void)
         PolKitPolicyFile *pf;
         PolKitError *error;
         const char *valid_files[] = {
-                TEST_DATA_DIR "test-valid-1.policy",
-                TEST_DATA_DIR "test-valid-2-annotations.policy",
-                TEST_DATA_DIR "test-valid-3-lang.policy",
-                TEST_DATA_DIR "test-valid-4-unknown-tags.policy",
+                TEST_DATA_DIR "valid/test-valid-1.policy",
+                TEST_DATA_DIR "valid/test-valid-2-annotations.policy",
+                TEST_DATA_DIR "valid/test-valid-3-lang.policy",
+                TEST_DATA_DIR "valid/test-valid-4-unknown-tags.policy",
         };
         const char *invalid_files[] = {
-                TEST_DATA_DIR "non-existant-file.policy",
-                TEST_DATA_DIR "bad.extension",
-                TEST_DATA_DIR "test-invalid-1-action-id.policy",
-                TEST_DATA_DIR "test-invalid-2-bogus-any.policy",
-                TEST_DATA_DIR "test-invalid-3-bogus-inactive.policy",
-                TEST_DATA_DIR "test-invalid-4-bogus-active.policy",
-                TEST_DATA_DIR "test-invalid-5-max-depth.policy",
+                TEST_DATA_DIR "invalid/non-existant-file.policy",
+                TEST_DATA_DIR "invalid/bad.extension",
+                TEST_DATA_DIR "invalid/test-invalid-1-action-id.policy",
+                TEST_DATA_DIR "invalid/test-invalid-2-bogus-any.policy",
+                TEST_DATA_DIR "invalid/test-invalid-3-bogus-inactive.policy",
+                TEST_DATA_DIR "invalid/test-invalid-4-bogus-active.policy",
+                TEST_DATA_DIR "invalid/test-invalid-5-max-depth.policy",
         };
 
         for (n = 0; n < sizeof (invalid_files) / sizeof (char*); n++) {
diff --git a/src/polkit/polkit-policy-file.h b/src/polkit/polkit-policy-file.h
index ac590c3..0ee29dc 100644
--- a/src/polkit/polkit-policy-file.h
+++ b/src/polkit/polkit-policy-file.h
@@ -46,19 +46,21 @@ typedef struct _PolKitPolicyFile PolKitPolicyFile;
  * @user_data: user data
  *
  * Type for function used in polkit_policy_file_entry_foreach().
+ *
+ * Returns: #TRUE to short-circuit, e.g.  stop the iteration
  **/
-typedef void (*PolKitPolicyFileEntryForeachFunc) (PolKitPolicyFile      *policy_file, 
-                                                  PolKitPolicyFileEntry *policy_file_entry,
-                                                  void                  *user_data);
+typedef polkit_bool_t (*PolKitPolicyFileEntryForeachFunc) (PolKitPolicyFile      *policy_file, 
+                                                           PolKitPolicyFileEntry *policy_file_entry,
+                                                           void                  *user_data);
 
 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,
-                                                       PolKitPolicyFileEntryForeachFunc  cb,
-                                                       void                              *user_data);
+polkit_bool_t     polkit_policy_file_entry_foreach (PolKitPolicyFile                 *policy_file,
+                                                    PolKitPolicyFileEntryForeachFunc  cb,
+                                                    void                              *user_data);
 
 POLKIT_END_DECLS
 
diff --git a/src/polkit/polkit-private.h b/src/polkit/polkit-private.h
index a8c9004..614e409 100644
--- a/src/polkit/polkit-private.h
+++ b/src/polkit/polkit-private.h
@@ -59,7 +59,7 @@ polkit_bool_t _polkit_authorization_db_auth_file_add (const char *root, polkit_b
 PolKitAuthorizationDB *_polkit_authorization_db_new            (void);
 void                   _polkit_authorization_db_invalidate_cache (PolKitAuthorizationDB *authdb);
 
-void                   _polkit_authorization_db_pfe_foreach   (PolKitPolicyCache *policy_cache, 
+polkit_bool_t          _polkit_authorization_db_pfe_foreach   (PolKitPolicyCache *policy_cache, 
                                                                PolKitPolicyCacheForeachFunc callback,
                                                                void *user_data);
 
diff --git a/src/polkit/polkit-test.c b/src/polkit/polkit-test.c
index 650c906..5631a04 100644
--- a/src/polkit/polkit-test.c
+++ b/src/polkit/polkit-test.c
@@ -50,6 +50,7 @@ static PolKitTest *tests[] = {
         &_test_policy_default,
         &_test_policy_file_entry,
         &_test_policy_file,
+        &_test_policy_cache,
 };
 
 int 
diff --git a/src/polkit/polkit-test.h b/src/polkit/polkit-test.h
index 9f938de..03b02e9 100644
--- a/src/polkit/polkit-test.h
+++ b/src/polkit/polkit-test.h
@@ -61,6 +61,7 @@ extern PolKitTest _test_policy_file_entry;
 extern PolKitTest _test_hash;
 extern PolKitTest _test_policy_file;
 extern PolKitTest _test_list;
+extern PolKitTest _test_policy_cache;
 
 POLKIT_END_DECLS
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 067dbcf..c062a69 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,15 +1,16 @@
 
-EXTRA_DIST = 					\
-	create-coverage-report.sh		\
-	test-invalid-1-action-id.policy		\
-	test-invalid-2-bogus-any.policy		\
-	test-invalid-3-bogus-inactive.policy	\
-	test-invalid-4-bogus-active.policy	\
-	test-invalid-5-max-depth.policy		\
-	test-valid-1.policy			\
-	test-valid-2-annotations.policy		\
-	test-valid-3-lang.policy		\
-	test-valid-4-unknown-tags.policy
+EXTRA_DIST = 						\
+	create-coverage-report.sh			\
+	invalid/test-invalid-1-action-id.policy		\
+	invalid/test-invalid-2-bogus-any.policy		\
+	invalid/test-invalid-3-bogus-inactive.policy	\
+	invalid/test-invalid-4-bogus-active.policy	\
+	invalid/test-invalid-5-max-depth.policy		\
+	valid/test-valid-1.policy			\
+	valid/test-valid-2-annotations.policy		\
+	valid/test-valid-3-lang.policy			\
+	valid/test-valid-4-unknown-tags.policy		\
+	valid/test-valid-5-wrong-extension.policy~
 
 clean-local :
 	rm -f *~
diff --git a/test/invalid/test-invalid-1-action-id.policy b/test/invalid/test-invalid-1-action-id.policy
new file mode 100644
index 0000000..0875d5f
--- /dev/null
+++ b/test/invalid/test-invalid-1-action-id.policy
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="4org.example.invalid1">
+    <description>foo</description>
+    <message>bar</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/invalid/test-invalid-2-bogus-any.policy b/test/invalid/test-invalid-2-bogus-any.policy
new file mode 100644
index 0000000..529e2c5
--- /dev/null
+++ b/test/invalid/test-invalid-2-bogus-any.policy
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.invalid2">
+    <description>foo</description>
+    <message>bar</message>
+    <defaults>
+      <allow_any>_bogus_</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/invalid/test-invalid-3-bogus-inactive.policy b/test/invalid/test-invalid-3-bogus-inactive.policy
new file mode 100644
index 0000000..555976d
--- /dev/null
+++ b/test/invalid/test-invalid-3-bogus-inactive.policy
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.invalid3">
+    <description>foo</description>
+    <message>bar</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>_bogus_</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/invalid/test-invalid-4-bogus-active.policy b/test/invalid/test-invalid-4-bogus-active.policy
new file mode 100644
index 0000000..0f82e7b
--- /dev/null
+++ b/test/invalid/test-invalid-4-bogus-active.policy
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.invalid4">
+    <description>foo</description>
+    <message>bar</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>_bogus_</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/invalid/test-invalid-5-max-depth.policy b/test/invalid/test-invalid-5-max-depth.policy
new file mode 100644
index 0000000..1dd1520
--- /dev/null
+++ b/test/invalid/test-invalid-5-max-depth.policy
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <future>
+    <future>
+      <future>
+        <future>
+          <future>
+            <future>
+              <future>
+                <future>
+                  <future>
+                    <future>
+                      <future>
+                        <future>
+                          <future>
+                            <future>
+                              <future>
+                                <future>
+                                  <future>
+                                    <future>
+                                      <future>
+                                        <future>
+                                          <future>
+                                            <future>
+                                              <future>
+                                                <future>
+                                                  <future>
+                                                    <future>
+                                                      <future>
+                                                        <future>
+                                                          <future>
+                                                            <future>
+                                                              <future>
+                                                                <future>
+                                                                  <future>
+                                                                    <future>
+                                                                      <future>
+                                                                        <future>
+                                                                        </future>
+                                                                      </future>
+                                                                    </future>
+                                                                  </future>
+                                                                </future>
+                                                              </future>
+                                                            </future>
+                                                          </future>
+                                                        </future>
+                                                      </future>
+                                                    </future>
+                                                  </future>
+                                                </future>
+                                              </future>
+                                            </future>
+                                          </future>
+                                        </future>
+                                      </future>
+                                    </future>
+                                  </future>
+                                </future>
+                              </future>
+                            </future>
+                          </future>
+                        </future>
+                      </future>
+                    </future>
+                  </future>
+                </future>
+              </future>
+            </future>
+          </future>
+        </future>
+      </future>
+    </future>
+  </future>
+
+  <action id="org.example.invalid5">
+    <description>foo</description>
+    <message>bar</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/test-invalid-1-action-id.policy b/test/test-invalid-1-action-id.policy
deleted file mode 100644
index 0875d5f..0000000
--- a/test/test-invalid-1-action-id.policy
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="4org.example.invalid1">
-    <description>foo</description>
-    <message>bar</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-invalid-2-bogus-any.policy b/test/test-invalid-2-bogus-any.policy
deleted file mode 100644
index 529e2c5..0000000
--- a/test/test-invalid-2-bogus-any.policy
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.invalid2">
-    <description>foo</description>
-    <message>bar</message>
-    <defaults>
-      <allow_any>_bogus_</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-invalid-3-bogus-inactive.policy b/test/test-invalid-3-bogus-inactive.policy
deleted file mode 100644
index 555976d..0000000
--- a/test/test-invalid-3-bogus-inactive.policy
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.invalid3">
-    <description>foo</description>
-    <message>bar</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>_bogus_</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-invalid-4-bogus-active.policy b/test/test-invalid-4-bogus-active.policy
deleted file mode 100644
index 0f82e7b..0000000
--- a/test/test-invalid-4-bogus-active.policy
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.invalid4">
-    <description>foo</description>
-    <message>bar</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>_bogus_</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-invalid-5-max-depth.policy b/test/test-invalid-5-max-depth.policy
deleted file mode 100644
index 1dd1520..0000000
--- a/test/test-invalid-5-max-depth.policy
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <future>
-    <future>
-      <future>
-        <future>
-          <future>
-            <future>
-              <future>
-                <future>
-                  <future>
-                    <future>
-                      <future>
-                        <future>
-                          <future>
-                            <future>
-                              <future>
-                                <future>
-                                  <future>
-                                    <future>
-                                      <future>
-                                        <future>
-                                          <future>
-                                            <future>
-                                              <future>
-                                                <future>
-                                                  <future>
-                                                    <future>
-                                                      <future>
-                                                        <future>
-                                                          <future>
-                                                            <future>
-                                                              <future>
-                                                                <future>
-                                                                  <future>
-                                                                    <future>
-                                                                      <future>
-                                                                        <future>
-                                                                        </future>
-                                                                      </future>
-                                                                    </future>
-                                                                  </future>
-                                                                </future>
-                                                              </future>
-                                                            </future>
-                                                          </future>
-                                                        </future>
-                                                      </future>
-                                                    </future>
-                                                  </future>
-                                                </future>
-                                              </future>
-                                            </future>
-                                          </future>
-                                        </future>
-                                      </future>
-                                    </future>
-                                  </future>
-                                </future>
-                              </future>
-                            </future>
-                          </future>
-                        </future>
-                      </future>
-                    </future>
-                  </future>
-                </future>
-              </future>
-            </future>
-          </future>
-        </future>
-      </future>
-    </future>
-  </future>
-
-  <action id="org.example.invalid5">
-    <description>foo</description>
-    <message>bar</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-valid-1.policy b/test/test-valid-1.policy
deleted file mode 100644
index 24bd602..0000000
--- a/test/test-valid-1.policy
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.valid1">
-    <description>example</description>
-    <message>example</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-valid-2-annotations.policy b/test/test-valid-2-annotations.policy
deleted file mode 100644
index e58ea9b..0000000
--- a/test/test-valid-2-annotations.policy
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.valid2">
-    <description>example 2</description>
-    <message>message 2</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-    <annotate key="the.key1">Some Value 1</annotate>
-    <annotate key="the.key2">Some Value 2</annotate>
-  </action>
-
-</policyconfig>
diff --git a/test/test-valid-3-lang.policy b/test/test-valid-3-lang.policy
deleted file mode 100644
index c13bd14..0000000
--- a/test/test-valid-3-lang.policy
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.valid3">
-    <description>example</description>
-    <message>message</message>
-    <description xml:lang="da">example (danish)</description>
-    <message xml:lang="da">message (danish)</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-  <action id="org.example.valid3b">
-    <description>example 2</description>
-    <message>message 2</message>
-    <description xml:lang="da">example 2 (danish)</description>
-    <message xml:lang="da">message 2 (danish)</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-  </action>
-
-</policyconfig>
diff --git a/test/test-valid-4-unknown-tags.policy b/test/test-valid-4-unknown-tags.policy
deleted file mode 100644
index af0ba07..0000000
--- a/test/test-valid-4-unknown-tags.policy
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<policyconfig>
-
-  <action id="org.example.valid4">
-    <description>example</description>
-    <message>example</message>
-    <defaults>
-      <allow_any>no</allow_any>
-      <allow_inactive>no</allow_inactive>
-      <allow_active>auth_admin_keep_always</allow_active>
-    </defaults>
-    <future_tag>
-      <future_tag2/>
-      <future_tag3>
-        <future_tag4/>
-      </future_tag3>
-    </future_tag>
-  </action>
-
-</policyconfig>
diff --git a/test/valid/test-valid-1.policy b/test/valid/test-valid-1.policy
new file mode 100644
index 0000000..24bd602
--- /dev/null
+++ b/test/valid/test-valid-1.policy
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.valid1">
+    <description>example</description>
+    <message>example</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/valid/test-valid-2-annotations.policy b/test/valid/test-valid-2-annotations.policy
new file mode 100644
index 0000000..3fbfd33
--- /dev/null
+++ b/test/valid/test-valid-2-annotations.policy
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.valid2">
+    <description>example 2</description>
+    <message>message 2</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+    <annotate key="the.key1">Some Value 1</annotate>
+    <annotate key="the.key2">Some Value 2</annotate>
+  </action>
+
+  <action id="org.example.valid2b">
+    <description>example 2</description>
+    <message>message 2</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+    <annotate key="the.key1">Some Value 1b</annotate>
+  </action>
+
+</policyconfig>
diff --git a/test/valid/test-valid-3-lang.policy b/test/valid/test-valid-3-lang.policy
new file mode 100644
index 0000000..c13bd14
--- /dev/null
+++ b/test/valid/test-valid-3-lang.policy
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.valid3">
+    <description>example</description>
+    <message>message</message>
+    <description xml:lang="da">example (danish)</description>
+    <message xml:lang="da">message (danish)</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+  <action id="org.example.valid3b">
+    <description>example 2</description>
+    <message>message 2</message>
+    <description xml:lang="da">example 2 (danish)</description>
+    <message xml:lang="da">message 2 (danish)</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/test/valid/test-valid-4-unknown-tags.policy b/test/valid/test-valid-4-unknown-tags.policy
new file mode 100644
index 0000000..af0ba07
--- /dev/null
+++ b/test/valid/test-valid-4-unknown-tags.policy
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.valid4">
+    <description>example</description>
+    <message>example</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+    <future_tag>
+      <future_tag2/>
+      <future_tag3>
+        <future_tag4/>
+      </future_tag3>
+    </future_tag>
+  </action>
+
+</policyconfig>
diff --git a/test/valid/test-valid-5-wrong-extension.policy~ b/test/valid/test-valid-5-wrong-extension.policy~
new file mode 100644
index 0000000..24bd602
--- /dev/null
+++ b/test/valid/test-valid-5-wrong-extension.policy~
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<policyconfig>
+
+  <action id="org.example.valid1">
+    <description>example</description>
+    <message>example</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>auth_admin_keep_always</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
diff --git a/tools/polkit-action.c b/tools/polkit-action.c
index 9ebdec5..f0ae680 100644
--- a/tools/polkit-action.c
+++ b/tools/polkit-action.c
@@ -46,13 +46,14 @@ usage (int argc, char *argv[])
         exit (1);
 }
 
-static void
+static polkit_bool_t
 _print_annotations (PolKitPolicyFileEntry *policy_file_entry,
                     const char *key,
                     const char *value,
                     void *user_data)
 {
         printf ("annotation:       %s -> %s\n", key, value);
+        return FALSE;
 }
 
 static void
@@ -86,7 +87,7 @@ _print_details_for_entry (PolKitPolicyFileEntry *pfe)
         polkit_policy_file_entry_annotations_foreach (pfe, _print_annotations, NULL);
 }
 
-static void
+static polkit_bool_t
 _print_entry (PolKitPolicyCache *policy_cache,
               PolKitPolicyFileEntry *pfe,
               void *user_data)
@@ -95,6 +96,8 @@ _print_entry (PolKitPolicyCache *policy_cache,
 
         action_id = polkit_policy_file_entry_get_id (pfe);
         printf ("%s\n", action_id);
+
+        return FALSE;
 }
 
 int
diff --git a/tools/polkit-auth.c b/tools/polkit-auth.c
index dd6f285..ac4d96c 100644
--- a/tools/polkit-auth.c
+++ b/tools/polkit-auth.c
@@ -497,7 +497,7 @@ out:
         return FALSE;
 }
 
-static void
+static polkit_bool_t
 pfe_iterator_cb (PolKitPolicyCache *policy_cache,
                  PolKitPolicyFileEntry *pfe,
                  void *user_data)
@@ -516,9 +516,11 @@ pfe_iterator_cb (PolKitPolicyCache *policy_cache,
         }
 
         polkit_action_unref (action);
+
+        return FALSE;
 }
 
-static void
+static polkit_bool_t
 pfe_iterator_show_obtainable_cb (PolKitPolicyCache *policy_cache,
                                  PolKitPolicyFileEntry *pfe,
                                  void *user_data)
@@ -552,6 +554,8 @@ pfe_iterator_show_obtainable_cb (PolKitPolicyCache *policy_cache,
         }
 
         polkit_action_unref (action);
+
+        return FALSE;
 }
 
 


More information about the hal-commit mailing list