PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Wed Feb 27 17:06:39 PST 2008


 src/polkit-dbus/polkit-simple.c |  153 ++++++++++++++++++++++++++++++++++++++++
 src/polkit-dbus/polkit-simple.h |    3 
 src/polkit/polkit-action.c      |   94 ++++++++++++++++++++++++
 src/polkit/polkit-action.h      |    5 +
 4 files changed, 253 insertions(+), 2 deletions(-)

New commits:
commit 58f0474286541970f6b535189514d706d9985cc2
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Feb 27 20:05:30 2008 -0500

    add convenience API to consistently report authorization failures over D-Bus

diff --git a/src/polkit-dbus/polkit-simple.c b/src/polkit-dbus/polkit-simple.c
index 4654cdf..d815046 100644
--- a/src/polkit-dbus/polkit-simple.c
+++ b/src/polkit-dbus/polkit-simple.c
@@ -398,11 +398,164 @@ out:
 }
 
 
+/**
+ * polkit_dbus_error_generate:
+ * @action: the action that the caller needs an authorization for
+ * @result: the result from e.g. polkit_context_is_caller_authorized()
+ * @error: the #DBusError to set
+ *
+ * Convenience function to generate a #DBusError that encapsulates
+ * information that the caller is not authorized. This includes
+ * information such as @action that describes what action the caller
+ * lacks an authorization for, as well as @result that describes if
+ * the caller can obtain an authorization through authentication.
+ *
+ * Typically a privileged mechanism uses this function to generate
+ * errors. At the other end of the wire, the caller can use
+ * polkit_dbus_error_parse() to extract @action and @result.
+ *
+ * The form of the #DBusError is as follows. The name is
+ * set to
+ * <literal>org.freedesktop.PolicyKit.Error.NotAuthorized</literal>
+ * and the message consists of two strings separated by a single
+ * space: the string representation of the action
+ * (cf. polkit_action_to_string_representation()) and the string
+ * representation of the result
+ * (cf. polkit_result_to_string_representation()).
+ *
+ * This function is in <literal>libpolkit-dbus</literal>.
+ *
+ * Returns: TRUE if @error was set. FALSE on error or OOM.
+ *
+ * Since: 0.8
+ */
+polkit_bool_t
+polkit_dbus_error_generate (PolKitAction *action, PolKitResult result, DBusError *error)
+{
+        polkit_bool_t ret;
+        const char *action_str;
+        const char *result_str;
+
+        ret = FALSE;
+
+        kit_return_val_if_fail (error != NULL && !dbus_error_is_set (error), FALSE);
+        kit_return_val_if_fail (action != NULL && polkit_action_validate (action), FALSE);
+
+        action_str = polkit_action_to_string_representation (action);
+        if (action_str == NULL)
+                goto out;
+
+        result_str = polkit_result_to_string_representation (result);
+        if (result_str == NULL)
+                goto out;
+
+        dbus_set_error (error, 
+                        "org.freedesktop.PolicyKit.Error.NotAuthorized",
+                        "%s %s",
+                        action_str, result_str);
+
+        /* on OOM, error->name and error->message are set to preallocated strings */
+        if (strcmp (error->name, "org.freedesktop.PolicyKit.Error.NotAuthorized") != 0)
+                goto out;
+
+        ret = TRUE;
+
+out:
+        return ret;
+}
+
+/**
+ * polkit_dbus_error_parse:
+ * @error: error to parse; must be set
+ * @action: return location for #PolKitAction object
+ * @result: return location for #PolKitResult variable
+ *
+ * Parse an error received over D-Bus, typically generated by
+ * polkit_dbus_error_generate(), into what action an authorization is
+ * missing for and whether that authorization can be obtained.
+ *
+ * This function is in <literal>libpolkit-dbus</literal>.
+ *
+ * Returns: TRUE only if @error was successfully parsed and @action
+ * and @result is set (and caller must free @action using
+ * polkit_action_unref()).
+ *
+ * Since: 0.8
+ */
+polkit_bool_t
+polkit_dbus_error_parse (DBusError *error, PolKitAction **action, PolKitResult *result)
+{
+        char **tokens;
+        size_t num_tokens;
+        polkit_bool_t ret;
+
+        kit_return_val_if_fail (error != NULL && dbus_error_is_set (error), FALSE);
+        kit_return_val_if_fail (action != NULL, FALSE);
+        kit_return_val_if_fail (result != NULL, FALSE);
+
+        ret = FALSE;
+        tokens = NULL;
+        *action = NULL;
+
+        if (!dbus_error_has_name (error, "org.freedesktop.PolicyKit.Error.NotAuthorized"))
+                goto out;
+
+        tokens = kit_strsplit (error->message, ' ', &num_tokens);
+        if (tokens == NULL || num_tokens != 2)
+                goto out;
+
+        *action = polkit_action_new_from_string_representation (tokens[0]);
+        if (*action == NULL)
+                goto out;
+
+        if (!polkit_result_from_string_representation (tokens[1], result)) {
+                polkit_action_unref (*action);
+                *action = NULL;
+                goto out;
+        }
+        
+        ret = TRUE;
+
+out:
+        if (!ret)
+                *result = POLKIT_RESULT_UNKNOWN;
+
+
+        if (tokens != NULL)
+                kit_strfreev (tokens);
+
+        return ret;
+}
+
 #ifdef POLKIT_BUILD_TESTS
 
 static polkit_bool_t
 _run_test (void)
 {
+        PolKitAction *a;
+        PolKitResult r;
+
+        a = polkit_action_new ();
+        r = POLKIT_RESULT_ONLY_VIA_SELF_AUTH;
+        if (a != NULL) {
+                if (polkit_action_set_action_id (a, "org.example.foo")) {
+                        DBusError error;
+
+                        dbus_error_init (&error);
+                        if (polkit_dbus_error_generate (a, r, &error)) {
+                                PolKitAction *a2;
+                                PolKitResult r2;
+
+                                if (polkit_dbus_error_parse (&error, &a2, &r2)) {
+                                        kit_assert (polkit_action_equal (a, a2));
+                                        kit_assert (r == r2);
+                                        polkit_action_unref (a2);
+                                }
+                        }
+                }
+                polkit_action_unref (a);
+        }
+
         return TRUE;
 }
 
diff --git a/src/polkit-dbus/polkit-simple.h b/src/polkit-dbus/polkit-simple.h
index a84e47d..0aff3d4 100644
--- a/src/polkit-dbus/polkit-simple.h
+++ b/src/polkit-dbus/polkit-simple.h
@@ -43,6 +43,9 @@ polkit_uint64_t polkit_check_authv (pid_t pid, const char **action_ids);
 
 polkit_bool_t   polkit_auth_obtain (const char *action_id, polkit_uint32_t xid, pid_t pid, DBusError *error);
 
+polkit_bool_t  polkit_dbus_error_generate              (PolKitAction *action, PolKitResult result, DBusError *error);
+polkit_bool_t  polkit_dbus_error_parse                 (DBusError *error, PolKitAction **action, PolKitResult *result);
+
 POLKIT_END_DECLS
 
 #endif /* POLKIT_SIMPLE_H */
diff --git a/src/polkit/polkit-action.c b/src/polkit/polkit-action.c
index 1292de2..6a81e6a 100644
--- a/src/polkit/polkit-action.c
+++ b/src/polkit/polkit-action.c
@@ -87,6 +87,80 @@ out:
 }
 
 /**
+ * polkit_action_to_string_representation:
+ * @action: the action object
+ *
+ * Serializes @action into a textual form that can be transferred from
+ * process to process or saved on disk. Use
+ * polkit_action_new_from_string_representation() to deserialize it.
+ *
+ * Returns: A string representation of @action or #NULL if the action
+ * is not valid. String is valid until @action is freed.
+ *
+ * Since: 0.8
+ */
+const char *
+polkit_action_to_string_representation (PolKitAction *action)
+{
+        kit_return_val_if_fail (action != NULL, NULL);
+        kit_return_val_if_fail (polkit_action_validate_id (action->id), NULL);
+        return action->id;
+}
+
+/**
+ * polkit_action_new_from_string_representation:
+ * @str: textual representation of an action; typically obtained from
+ * polkit_action_to_string_representation()
+ *
+ * Creates a new #PolKitAction object from a textual representation.
+ *
+ * Returns: A new #PolKitAction object or #NULL if OOM or if the
+ * representation isn't valid. Caller must free this object with
+ * polkit_action_unref().
+ *
+ * Since: 0.8
+ */
+PolKitAction *
+polkit_action_new_from_string_representation (const char *str)
+{
+        PolKitAction *action;
+
+        kit_return_val_if_fail (str != NULL, NULL);
+
+        action = polkit_action_new ();
+        if (action == NULL)
+                goto out;
+
+        if (!polkit_action_set_action_id (action, str)) {
+                polkit_action_unref (action);
+                action = NULL;
+        }
+out:
+        return action;
+}
+
+/**
+ * polkit_action_equal:
+ * @a: first action
+ * @b: second action
+ *
+ * Test if @a and @b refer to the same action.
+ *
+ * Returns: #TRUE iff @a and @b refer to the same action.
+ *
+ * Since: 0.8
+ */
+polkit_bool_t
+polkit_action_equal (PolKitAction *a, PolKitAction *b)
+{
+        kit_return_val_if_fail (a != NULL && polkit_action_validate (a), FALSE);
+        kit_return_val_if_fail (b != NULL && polkit_action_validate (b), FALSE);
+
+        return strcmp (a->id, b->id) == 0;
+}
+
+
+/**
  * polkit_action_ref:
  * @action: the action object
  * 
@@ -241,6 +315,8 @@ polkit_action_validate (PolKitAction *action)
 static polkit_bool_t
 _run_test (void)
 {
+        PolKitAction *a;
+        char *s;
         int n;
         char *valid_action_ids[]   = {"org.example.action",
                                       "org.example.action-foo", 
@@ -263,8 +339,6 @@ _run_test (void)
                 kit_assert (! polkit_action_validate_id (invalid_action_ids[n]));
         }
 
-        PolKitAction *a;
-        char *s;
         a = polkit_action_new ();
         if (a == NULL) {
                 /* OOM */
@@ -294,6 +368,22 @@ _run_test (void)
                 polkit_action_unref (a);
         }
         
+        a = polkit_action_new ();
+        if (a != NULL) {
+                if (polkit_action_set_action_id (a, "org.example.foo")) {
+                        const char *action_str;
+                        PolKitAction *a2;
+
+                        action_str = polkit_action_to_string_representation (a);
+                        kit_assert (action_str != NULL);
+                        a2 = polkit_action_new_from_string_representation (action_str);
+                        if (a2 != NULL) {
+                                kit_assert (polkit_action_equal (a, a2));
+                                polkit_action_unref (a2);
+                        }
+                }
+                polkit_action_unref (a);
+        }
 
         return TRUE;
 }
diff --git a/src/polkit/polkit-action.h b/src/polkit/polkit-action.h
index 08b51c3..be2e807 100644
--- a/src/polkit/polkit-action.h
+++ b/src/polkit/polkit-action.h
@@ -52,6 +52,11 @@ polkit_bool_t polkit_action_validate      (PolKitAction *action);
 
 polkit_bool_t polkit_action_validate_id   (const char   *action_id);
 
+polkit_bool_t polkit_action_equal         (PolKitAction *a, PolKitAction *b);
+
+const char   *polkit_action_to_string_representation       (PolKitAction *action);
+PolKitAction *polkit_action_new_from_string_representation (const char *str);
+
 POLKIT_END_DECLS
 
 #endif /* POLKIT_ACTION_H */


More information about the hal-commit mailing list