You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GConf2/polkit1.patch

1340 lines
42 KiB

16 years ago
diff -up GConf-2.26.2/configure.in.polkit1 GConf-2.26.2/configure.in
--- GConf-2.26.2/configure.in.polkit1 2009-05-14 11:18:34.000000000 -0400
+++ GConf-2.26.2/configure.in 2009-06-09 21:12:21.335927355 -0400
@@ -181,7 +181,7 @@ AC_ARG_ENABLE(defaults_service,
, enable_defaults_service=auto)
if test "x$enable_defaults_service" != "xno" ; then
16 years ago
- PKG_CHECK_MODULES(DEFAULTS, glib-2.0 gobject-2.0 dbus-1 dbus-glib-1 polkit-dbus, HAVE_POLKIT=yes)
+ PKG_CHECK_MODULES(DEFAULTS, glib-2.0 gobject-2.0 dbus-1 dbus-glib-1 polkit-gobject-1, HAVE_POLKIT=yes)
if test "x$HAVE_POLKIT" = "xno"; then
if test "x$enable_defaults_service" = "xyes" ; then
AC_MSG_ERROR([[
16 years ago
@@ -194,13 +194,6 @@ fi
if test "x$enable_defaults_service" != "xno" ; then
AC_DEFINE(ENABLE_DEFAULTS_SERVICE, 1, [enable defaults DBus service])
-
- AC_CHECK_PROG([POLKIT_POLICY_FILE_VALIDATE],
16 years ago
- [polkit-policy-file-validate], [polkit-policy-file-validate])
-
- if test -z "$POLKIT_POLICY_FILE_VALIDATE"; then
16 years ago
- AC_MSG_ERROR([polkit-policy-file-validate not found])
- fi
fi
AM_CONDITIONAL(ENABLE_DEFAULTS_SERVICE, [test "x$enable_defaults_service" != "xno"])
16 years ago
diff -up GConf-2.26.2/defaults/gconf-defaults.c.polkit1 GConf-2.26.2/defaults/gconf-defaults.c
--- GConf-2.26.2/defaults/gconf-defaults.c.polkit1 2009-05-14 11:13:40.000000000 -0400
+++ GConf-2.26.2/defaults/gconf-defaults.c 2009-06-09 21:07:45.472634301 -0400
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
- * Copyright (C) 2008 Matthias Clasen <mclasen@redhat.com>
+ * Copyright (C) 2008, 2009 Matthias Clasen <mclasen@redhat.com>
*
* 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
@@ -37,7 +37,6 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include <polkit-dbus/polkit-dbus.h>
#include <polkit/polkit.h>
#define GCONF_ENABLE_INTERNALS
16 years ago
@@ -56,10 +55,14 @@ do_exit (gpointer user_data)
}
static guint timer_id = 0;
+gboolean disable_killtimer = FALSE;
static void
stop_killtimer (void)
{
+ if (disable_killtimer)
+ return;
+
if (timer_id > 0) {
g_source_remove (timer_id);
timer_id = 0;
16 years ago
@@ -69,15 +72,38 @@ stop_killtimer (void)
static void
start_killtimer (void)
{
- g_debug ("Setting killtimer to 30 seconds...");
- timer_id = g_timeout_add_seconds (30, do_exit, NULL);
+ if (disable_killtimer)
+ return;
+
+ if (timer_id == 0) {
+ g_debug ("Setting killtimer to 30 seconds...");
+ timer_id = g_timeout_add_seconds (30, do_exit, NULL);
+ }
+}
+
+static gint operations = 0;
+
+static void
+start_operation (void)
+{
+ if (operations == 0)
+ stop_killtimer ();
+ operations++;
+}
+
+static void
+stop_operation (void)
+{
+ if (operations == 1)
+ start_killtimer ();
+ operations --;
}
struct GConfDefaultsPrivate
{
DBusGConnection *system_bus_connection;
DBusGProxy *system_bus_proxy;
- PolKitContext *pol_ctx;
+ PolkitAuthority *auth;
};
static void gconf_defaults_finalize (GObject *object);
16 years ago
@@ -105,7 +131,7 @@ GType
gconf_defaults_error_get_type (void)
{
static GType etype = 0;
-
+
if (etype == 0)
{
static const GEnumValue values[] =
16 years ago
@@ -114,12 +140,12 @@ gconf_defaults_error_get_type (void)
ENUM_ENTRY (GCONF_DEFAULTS_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
{ 0, 0, 0 }
};
-
+
g_assert (GCONF_DEFAULTS_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
-
+
etype = g_enum_register_static ("GConfDefaultsError", values);
}
-
+
return etype;
}
16 years ago
@@ -191,56 +217,18 @@ gconf_defaults_finalize (GObject *object
g_return_if_fail (mechanism->priv != NULL);
+ g_object_unref (mechanism->priv->auth);
g_object_unref (mechanism->priv->system_bus_proxy);
G_OBJECT_CLASS (gconf_defaults_parent_class)->finalize (object);
}
static gboolean
-pk_io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
-{
- int fd;
- PolKitContext *pk_context = user_data;
- fd = g_io_channel_unix_get_fd (channel);
- polkit_context_io_func (pk_context, fd);
- return TRUE;
-}
-
-static int
-pk_io_add_watch (PolKitContext *pk_context, int fd)
-{
- guint id = 0;
- GIOChannel *channel;
- channel = g_io_channel_unix_new (fd);
- if (channel == NULL)
- goto out;
- id = g_io_add_watch (channel, G_IO_IN, pk_io_watch_have_data, pk_context);
- if (id == 0) {
- g_io_channel_unref (channel);
- goto out;
- }
- g_io_channel_unref (channel);
-out:
- return id;
-}
-
-static void
-pk_io_remove_watch (PolKitContext *pk_context, int watch_id)
-{
- g_source_remove (watch_id);
-}
-
-static gboolean
register_mechanism (GConfDefaults *mechanism)
{
GError *error = NULL;
- mechanism->priv->pol_ctx = polkit_context_new ();
- polkit_context_set_io_watch_functions (mechanism->priv->pol_ctx, pk_io_add_watch, pk_io_remove_watch);
- if (!polkit_context_init (mechanism->priv->pol_ctx, NULL)) {
- g_critical ("cannot initialize libpolkit");
- goto error;
- }
+ mechanism->priv->auth = polkit_authority_get ();
error = NULL;
mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
16 years ago
@@ -252,7 +240,7 @@ register_mechanism (GConfDefaults *mecha
goto error;
}
- dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/",
+ dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/",
G_OBJECT (mechanism));
mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection,
16 years ago
@@ -288,33 +276,37 @@ gconf_defaults_new (void)
static const char *
polkit_action_for_gconf_path (GConfDefaults *mechanism,
+ GList *action_descriptions,
const char *annotation_key,
const char *path)
{
- PolKitPolicyCache *cache;
- PolKitPolicyFileEntry *entry;
char *prefix, *p;
const char *action;
+ GList *l;
+ PolkitActionDescription *action_description;
+ const gchar *annotation;
- cache = polkit_context_get_policy_cache (mechanism->priv->pol_ctx);
prefix = g_strdup (path);
while (1) {
- entry = polkit_policy_cache_get_entry_by_annotation (cache,
- annotation_key,
- prefix);
- if (entry) {
- action = polkit_policy_file_entry_get_id (entry);
- break;
+ for (l = action_descriptions; l; l = l->next) {
+ action_description = l->data;
+
+ annotation = polkit_action_description_get_annotation (action_description, annotation_key);
+ if (g_strcmp0 (prefix, annotation) == 0) {
+ action = polkit_action_description_get_action_id (action_description);
+ g_debug ("action for path '%s': '%s'\n", action, path);
+ break;
+ }
}
-
+
p = strrchr (prefix, '/');
if (p == NULL || p == prefix) {
action = NULL;
break;
}
-
+
*p = 0;
}
16 years ago
@@ -323,56 +315,158 @@ polkit_action_for_gconf_path (GConfDefau
return action;
}
-static gboolean
-check_polkit_for_action (GConfDefaults *mechanism,
- DBusGMethodInvocation *context,
- const char *action)
-{
- const char *sender;
- GError *error;
- DBusError dbus_error;
- PolKitCaller *pk_caller;
- PolKitAction *pk_action;
- PolKitResult pk_result;
+static void
+throw_error (DBusGMethodInvocation *context,
+ gint error_code,
+ const gchar *format,
+ ...)
+{
+ GError *error;
+ va_list args;
+ gchar *message;
- error = NULL;
+ va_start (args, format);
+ message = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ error = g_error_new (GCONF_DEFAULTS_ERROR,
+ error_code,
+ "%s", message);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ g_free (message);
+}
+
+typedef void (*AuthObtainedCallback) (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gpointer user_data);
+
+typedef struct
+{
+ GConfDefaults *mechanism;
+ DBusGMethodInvocation *context;
+ gchar **actions;
+ gint id;
+ gint flags;
+ AuthObtainedCallback auth_obtained_callback;
+ GAsyncReadyCallback check_auth_callback;
+ gpointer user_data;
+ GDestroyNotify destroy;
+ PolkitSubject *subject;
+} CheckAuthData;
- /* Check that caller is privileged */
- sender = dbus_g_method_get_sender (context);
- dbus_error_init (&dbus_error);
- pk_caller = polkit_caller_new_from_dbus_name (
- dbus_g_connection_get_connection (mechanism->priv->system_bus_connection),
- sender,
- &dbus_error);
- if (pk_caller == NULL) {
- error = g_error_new (GCONF_DEFAULTS_ERROR,
- GCONF_DEFAULTS_ERROR_GENERAL,
- "Error getting information about caller: %s: %s",
- dbus_error.name, dbus_error.message);
- dbus_error_free (&dbus_error);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return FALSE;
- }
+static void
+check_auth_data_free (CheckAuthData *data)
+{
+ g_object_unref (data->mechanism);
+ g_strfreev (data->actions);
+ if (data->destroy)
+ data->destroy (data->user_data);
+ g_object_unref (data->subject);
+ g_free (data);
+}
- pk_action = polkit_action_new ();
- polkit_action_set_action_id (pk_action, action);
- pk_result = polkit_context_is_caller_authorized (mechanism->priv->pol_ctx, pk_action, pk_caller, TRUE, NULL);
- polkit_caller_unref (pk_caller);
-
- if (pk_result != POLKIT_RESULT_YES) {
- dbus_error_init (&dbus_error);
- polkit_dbus_error_generate (pk_action, pk_result, &dbus_error);
- dbus_set_g_error (&error, &dbus_error);
- dbus_g_method_return_error (context, error);
- dbus_error_free (&dbus_error);
- g_error_free (error);
- polkit_action_unref (pk_action);
- return FALSE;
- }
+static void check_next_action (CheckAuthData *data);
- polkit_action_unref (pk_action);
- return TRUE;
+static void
+check_authorization_callback (PolkitAuthority *authority,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CheckAuthData *data = user_data;
+ PolkitAuthorizationResult *result;
+ GError *error;
+ gboolean is_authorized;
+
+ is_authorized = FALSE;
+
+ error = NULL;
+ result = polkit_authority_check_authorization_finish (authority,
+ res,
+ &error);
+ if (error != NULL) {
+ g_debug ("error checking action '%s'\n", error->message);
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_NOT_PRIVILEGED,
+ "Not Authorized: %s", error->message);
+ g_error_free (error);
+ }
+ else {
+ if (polkit_authorization_result_get_is_authorized (result)) {
+ g_debug ("result for '%s': authorized\n",
+ data->actions[data->id]);
+ is_authorized = TRUE;
+ }
+ else if (polkit_authorization_result_get_is_challenge (result)) {
+ g_debug ("result for '%s': challenge\n",
+ data->actions[data->id]);
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_NOT_PRIVILEGED,
+ "Authorization is required");
+ }
+ else {
+ g_debug ("result for '%s': not authorized\n",
+ data->actions[data->id]);
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_NOT_PRIVILEGED,
+ "Not Authorized");
+ }
+ }
+
+ if (is_authorized) {
+ data->id++;
+ if (data->actions[data->id] == NULL)
+ data->auth_obtained_callback (data->mechanism,
+ data->context,
+ data->user_data);
+ else {
+ check_next_action (data);
+ return; /* continue operation */
+ }
+ }
+
+ check_auth_data_free (data);
+ g_object_unref (result);
+ stop_operation ();
+}
+
+static void
+check_next_action (CheckAuthData *data)
+{
+ g_debug ("checking action '%s'\n", data->actions[data->id]);
+ polkit_authority_check_authorization (data->mechanism->priv->auth,
+ data->subject,
+ data->actions[data->id],
+ NULL,
+ data->flags,
+ NULL,
+ data->check_auth_callback,
+ data);
+}
+
+static void
+check_polkit_for_actions (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gchar **actions,
+ AuthObtainedCallback auth_obtained_callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ CheckAuthData *data;
+
+ data = g_new0 (CheckAuthData, 1);
+ data->mechanism = g_object_ref (mechanism);
+ data->context = context;
+ data->actions = actions;
+ data->flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
+ data->id = 0;
+ data->auth_obtained_callback = auth_obtained_callback;
+ data->check_auth_callback = (GAsyncReadyCallback)check_authorization_callback;
+ data->user_data = user_data;
+ data->destroy = destroy;
+ data->subject = polkit_system_bus_name_new (dbus_g_method_get_sender (context));
+
+ check_next_action (data);
}
static char *
16 years ago
@@ -398,11 +492,11 @@ gconf_address_for_caller (GConfDefaults
dbus_error_free (&error);
return NULL;
}
-
+
pwd = getpwuid (uid);
if (pwd == NULL) {
- g_set_error (gerror,
- 0, 0,
+ g_set_error (gerror,
+ 0, 0,
"Failed to get passwd information for uid %d", uid);
return NULL;
}
16 years ago
@@ -434,13 +528,13 @@ copy_tree (GConfClient *src,
GSList *list, *l;
GConfEntry *entry;
- if (path_is_excluded (path, excludes))
+ if (path_is_excluded (path, excludes))
return;
list = gconf_client_all_entries (src, path, NULL);
for (l = list; l; l = l->next) {
entry = l->data;
- if (!path_is_excluded (entry->key, excludes))
+ if (!path_is_excluded (entry->key, excludes))
gconf_change_set_set (changes, entry->key, entry->value);
}
g_slist_foreach (list, (GFunc)gconf_entry_free, NULL);
16 years ago
@@ -461,7 +555,7 @@ copy_entry (GConfClient *src,
{
GConfValue *value;
- if (path_is_excluded (path, excludes))
+ if (path_is_excluded (path, excludes))
return;
value = gconf_client_get (src, path, NULL);
16 years ago
@@ -471,69 +565,66 @@ copy_entry (GConfClient *src,
}
}
+typedef void (*ChangeSetCallback) (GConfDefaults *mechanism,
+ GConfChangeSet *changes,
+ gpointer data);
+
+typedef struct
+{
+ GConfDefaults *mechanism;
+ DBusGMethodInvocation *context;
+ const char *dest_address;
+ char **actions;
+ char **includes;
+ char **excludes;
+ ChangeSetCallback changeset_callback;
+ gpointer user_data;
+ GDestroyNotify destroy;
+} CopyData;
static void
-do_copy (GConfDefaults *mechanism,
- gboolean mandatory,
- const char **includes,
- const char **excludes,
- DBusGMethodInvocation *context,
- GConfChangeSet **changeset_out)
+copy_data_free (gpointer user_data)
{
- char *address = NULL;
- GConfClient *source = NULL;
+ CopyData *data = user_data;
+
+ g_object_unref (data->mechanism);
+ g_strfreev (data->includes);
+ g_strfreev (data->excludes);
+ g_strfreev (data->actions);
+ if (data->destroy)
+ data->destroy (data->user_data);
+ g_free (data);
+}
+
+static void
+do_copy_authorized (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ CopyData *data = user_data;
+ GConfClient *source = NULL;
GConfClient *dest = NULL;
GConfChangeSet *changes = NULL;
GConfEngine *engine;
+ char *address = NULL;
+ gint i;
GError *error;
- GError *error2;
- const char *action;
- const char *annotation_key;
- const char *default_action;
- const char *dest_address;
- int i;
-
- if (changeset_out)
- *changeset_out = NULL;
-
- stop_killtimer ();
-
- /* check privileges for each include */
- if (mandatory) {
- annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix";
- default_action = "org.gnome.gconf.defaults.set-mandatory";
- dest_address = "xml:merged:" SYSGCONFDIR "/gconf.xml.mandatory";
- }
- else {
- annotation_key = "org.gnome.gconf.defaults.set-system.prefix";
- default_action = "org.gnome.gconf.defaults.set-system";
- dest_address = "xml:merged:" SYSGCONFDIR "/gconf.xml.system";
- }
-
- for (i = 0; includes[i]; i++) {
- action = polkit_action_for_gconf_path (mechanism, annotation_key, includes[i]);
- if (action == NULL)
- action = default_action;
-
- if (!check_polkit_for_action (mechanism, context, action))
- goto out;
- }
error = NULL;
- engine = gconf_engine_get_local (dest_address, &error);
- if (error)
- goto cleanup;
+ engine = gconf_engine_get_local (data->dest_address, &error);
+ if (error)
+ goto cleanup;
dest = gconf_client_get_for_engine (engine);
gconf_engine_unref (engine);
/* find the address to from the caller id */
- address = gconf_address_for_caller (mechanism, context, &error);
+ address = gconf_address_for_caller (data->mechanism, data->context, &error);
if (error)
goto cleanup;
engine = gconf_engine_get_local (address, &error);
- if (error)
+ if (error)
goto cleanup;
source = gconf_client_get_for_engine (engine);
16 years ago
@@ -542,45 +633,175 @@ do_copy (GConfDefaults *mechani
changes = gconf_change_set_new ();
/* recursively copy each include, leaving out the excludes */
- for (i = 0; includes[i]; i++) {
- if (gconf_client_dir_exists (source, includes[i], NULL))
- copy_tree (source, includes[i], changes, excludes);
+ for (i = 0; data->includes[i]; i++) {
+ if (gconf_client_dir_exists (source, data->includes[i], NULL))
+ copy_tree (source, data->includes[i], changes, (const char **)data->excludes);
else
- copy_entry (source, includes[i], changes, excludes);
+ copy_entry (source, data->includes[i], changes, (const char **)data->excludes);
}
gconf_client_commit_change_set (dest, changes, FALSE, &error);
gconf_client_suggest_sync (dest, NULL);
- if (changeset_out) {
- *changeset_out = changes;
- changes = NULL;
+ if (data->changeset_callback) {
+ data->changeset_callback (data->mechanism, changes, data->user_data);
}
cleanup:
g_free (address);
if (changes)
gconf_change_set_unref (changes);
- if (dest)
+ if (dest)
g_object_unref (dest);
if (source)
g_object_unref (source);
if (error) {
- g_print ("failed to set GConf values: %s\n", error->message);
- error2 = g_error_new_literal (GCONF_DEFAULTS_ERROR,
- GCONF_DEFAULTS_ERROR_GENERAL,
- error->message);
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_GENERAL,
+ "%s", error->message);
g_error_free (error);
-
- dbus_g_method_return_error (context, error2);
- g_error_free (error2);
}
else
- dbus_g_method_return (context);
+ dbus_g_method_return (data->context);
+}
-out:
- start_killtimer ();
+typedef void (*ActionsReadyCallback) (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gchar **actions,
+ AuthObtainedCallback auth_obtained_callback,
+ gpointer data,
+ GDestroyNotify destroy);
+
+typedef struct
+{
+ GConfDefaults *mechanism;
+ DBusGMethodInvocation *context;
+ char **includes;
+ const char *default_action;
+ const char *annotation_key;
+ ActionsReadyCallback actions_ready_callback;
+ AuthObtainedCallback auth_obtained_callback;
+ gpointer data;
+ GDestroyNotify destroy;
+} ActionData;
+
+static void
+action_data_free (ActionData *data)
+{
+ g_object_unref (data->mechanism);
+ g_strfreev (data->includes);
+ if (data->destroy)
+ data->destroy (data->data);
+ g_free (data);
+}
+
+static void
+actions_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ActionData *data = user_data;
+ GList *action_descriptions;
+ GError *error = NULL;
+ int i;
+ GHashTable *obtained;
+ GHashTableIter iter;
+ const gchar *action;
+ gchar **actions;
+ gpointer key, value;
+
+ action_descriptions = polkit_authority_enumerate_actions_finish (data->mechanism->priv->auth, res, &error);
+
+ if (error) {
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_GENERAL,
+ "Failed to get action descriptions: %s", error->message);
+ g_error_free (error);
+ action_data_free (data);
+ stop_operation ();
+ return;
+ }
+
+ obtained = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (i = 0; data->includes[i]; i++) {
+ action = polkit_action_for_gconf_path (data->mechanism, action_descriptions, data->annotation_key, data->includes[i]);
+ if (action == NULL) {
+ g_debug ("using default action '%s' for path '%s'",
+ data->default_action, data->includes[i]);
+ action = data->default_action;
+ }
+
+ g_hash_table_insert (obtained, (gpointer)action, (gpointer)action);
+ }
+ actions = g_new0 (char *, g_hash_table_size (obtained) + 1);
+ g_hash_table_iter_init (&iter, obtained);
+ i = 0;
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ actions[i] = g_strdup ((char *)key);
+ i++;
+ }
+ g_hash_table_destroy (obtained);
+ g_list_foreach (action_descriptions, (GFunc)g_object_unref, NULL);
+ g_list_free (action_descriptions);
+
+ data->actions_ready_callback (data->mechanism, data->context, actions, data->auth_obtained_callback, data->data, data->destroy);
+
+ data->destroy = NULL;
+ action_data_free (data);
+}
+
+static void
+do_copy (GConfDefaults *mechanism,
+ gboolean mandatory,
+ const gchar **includes,
+ const gchar **excludes,
+ DBusGMethodInvocation *context,
+ ChangeSetCallback changeset_callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ CopyData *cdata;
+ ActionData *adata;
+
+ start_operation ();
+
+ cdata = g_new0 (CopyData, 1);
+ cdata->mechanism = g_object_ref (mechanism);
+ cdata->context = context;
+ cdata->includes = g_strdupv ((gchar **)includes);
+ cdata->excludes = g_strdupv ((gchar **)excludes);
+ cdata->actions = NULL;
+ cdata->changeset_callback = changeset_callback;
+ cdata->user_data = user_data;
+ cdata->destroy = destroy;
+
+ adata = g_new0 (ActionData, 1);
+ adata->mechanism = g_object_ref (mechanism);
+ adata->context = context;
+ adata->includes = g_strdupv ((gchar **)includes);
+ adata->actions_ready_callback = check_polkit_for_actions;
+ adata->auth_obtained_callback = do_copy_authorized;
+ adata->data = cdata;
+ adata->destroy = copy_data_free;
+
+ /* check privileges for each include */
+ if (mandatory) {
+ adata->annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix";
+ adata->default_action = "org.gnome.gconf.defaults.set-mandatory";
+ cdata->dest_address = "xml:merged:" SYSGCONFDIR "/gconf.xml.mandatory";
+ }
+ else {
+ adata->annotation_key = "org.gnome.gconf.defaults.set-system.prefix";
+ adata->default_action = "org.gnome.gconf.defaults.set-system";
+ cdata->dest_address = "xml:merged:" SYSGCONFDIR "/gconf.xml.system";
+ }
+
+ polkit_authority_enumerate_actions (mechanism->priv->auth,
+ NULL,
+ actions_ready_cb,
+ adata);
}
static void
16 years ago
@@ -594,20 +815,13 @@ append_key (GConfChangeSet *cs,
g_ptr_array_add (keys, (gpointer) key);
}
-void
-gconf_defaults_set_system (GConfDefaults *mechanism,
- const char **includes,
- const char **excludes,
- DBusGMethodInvocation *context)
+static void
+set_system_changes (GConfDefaults *mechanism,
+ GConfChangeSet *changes,
+ gpointer data)
{
- GConfChangeSet *changes = NULL;
GPtrArray *keys;
- do_copy (mechanism, FALSE, includes, excludes, context, &changes);
-
- if (!changes)
- return;
-
keys = g_ptr_array_new ();
gconf_change_set_foreach (changes, append_key, keys);
g_ptr_array_add (keys, NULL);
16 years ago
@@ -615,7 +829,15 @@ gconf_defaults_set_system (GConfDefaults
g_signal_emit (mechanism, signals[SYSTEM_SET], 0, keys->pdata);
g_ptr_array_free (keys, TRUE);
- gconf_change_set_unref (changes);
+}
+
+void
+gconf_defaults_set_system (GConfDefaults *mechanism,
+ const char **includes,
+ const char **excludes,
+ DBusGMethodInvocation *context)
+{
+ do_copy (mechanism, FALSE, includes, excludes, context, set_system_changes, NULL, NULL);
}
void
16 years ago
@@ -624,7 +846,7 @@ gconf_defaults_set_mandatory (GConfDefau
const char **excludes,
DBusGMethodInvocation *context)
{
- do_copy (mechanism, TRUE, includes, excludes, context, NULL);
+ do_copy (mechanism, TRUE, includes, excludes, context, NULL, NULL, NULL);
}
static void
16 years ago
@@ -636,13 +858,13 @@ unset_tree (GConfClient *dest,
GSList *list, *l;
GConfEntry *entry;
- if (path_is_excluded (path, excludes))
+ if (path_is_excluded (path, excludes))
return;
list = gconf_client_all_entries (dest, path, NULL);
for (l = list; l; l = l->next) {
entry = l->data;
- if (!path_is_excluded (entry->key, excludes))
+ if (!path_is_excluded (entry->key, excludes))
gconf_change_set_unset (changes, entry->key);
}
g_slist_foreach (list, (GFunc)gconf_entry_free, NULL);
16 years ago
@@ -654,25 +876,25 @@ unset_tree (GConfClient *dest,
g_slist_foreach (list, (GFunc)g_free, NULL);
g_slist_free (list);
}
-
+
static void
unset_entry (GConfClient *dest,
const char *path,
GConfChangeSet *changes,
const char **excludes)
{
- if (path_is_excluded (path, excludes))
+ if (path_is_excluded (path, excludes))
return;
gconf_change_set_unset (changes, path);
}
-
+
static void
-unset_in_db (GConfDefaults *mechanism,
- const char *address,
- const char **includes,
- const char **excludes,
- GError **error)
+unset_in_db (GConfDefaults *mechanism,
+ const gchar *address,
+ const gchar **includes,
+ const gchar **excludes,
+ GError **error)
{
GConfEngine *engine;
GConfClient *dest = NULL;
16 years ago
@@ -680,7 +902,7 @@ unset_in_db (GConfDefaults *mechanism,
int i;
engine = gconf_engine_get_local (address, error);
- if (*error)
+ if (*error)
goto out;
dest = gconf_client_get_for_engine (engine);
16 years ago
@@ -706,48 +928,219 @@ out:
gconf_change_set_unref (changes);
}
+typedef struct
+{
+ GConfDefaults *mechanism;
+ DBusGMethodInvocation *context;
+ char **includes;
+ char **excludes;
+} UnsetData;
+
+static void
+unset_data_free (gpointer user_data)
+{
+ UnsetData *data = user_data;
+
+ g_object_unref (data->mechanism);
+ g_strfreev (data->includes);
+ g_strfreev (data->excludes);
+ g_free (data);
+}
+
+static void
+do_unset_authorized (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ UnsetData *data = user_data;
+ GError *error;
+
+ error = NULL;
+ unset_in_db (mechanism, "xml:merged:" SYSGCONFDIR "/gconf.xml.mandatory",
+ (const gchar **)data->includes,
+ (const gchar **)data->excludes, &error);
+
+ if (error) {
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR,
+ GCONF_DEFAULTS_ERROR_GENERAL,
+ "%s", error->message);
+ g_error_free (error);
+ }
+ else
+ dbus_g_method_return (data->context);
+}
+
void
gconf_defaults_unset_mandatory (GConfDefaults *mechanism,
const char **includes,
const char **excludes,
DBusGMethodInvocation *context)
{
- const char *annotation_key;
- const char *default_action;
- int i;
- const char *action;
- GError *error;
- GError *error2;
+ UnsetData *udata;
+ ActionData *adata;
- stop_killtimer ();
+ start_operation ();
- annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix";
- default_action = "org.gnome.gconf.defaults.set-mandatory";
+ udata = g_new0 (UnsetData, 1);
+ udata->mechanism = g_object_ref (mechanism);
+ udata->context = context;
+ udata->includes = g_strdupv ((gchar **)includes);
+ udata->excludes = g_strdupv ((gchar **)excludes);
+
+ adata = g_new0 (ActionData, 1);
+ adata->mechanism = g_object_ref (mechanism);
+ adata->context = context;
+ adata->includes = g_strdupv ((gchar **)includes);
+ adata->auth_obtained_callback = do_unset_authorized;
+ adata->data = udata;
+ adata->destroy = unset_data_free;
+
+ adata->annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix";
+ adata->default_action = "org.gnome.gconf.defaults.set-mandatory";
+
+ polkit_authority_enumerate_actions (mechanism->priv->auth,
+ NULL,
+ actions_ready_cb,
+ adata);
+}
- for (i = 0; includes[i]; i++) {
- action = polkit_action_for_gconf_path (mechanism, annotation_key, includes[i]);
- if (action == NULL)
- action = default_action;
+static void
+check_authorization_only_callback (PolkitAuthority *authority,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CheckAuthData *data = user_data;
+ PolkitAuthorizationResult *result;
+ GError *error;
+ gboolean is_authorized;
- if (!check_polkit_for_action (mechanism, context, action))
- goto out;
- }
+ is_authorized = FALSE;
error = NULL;
- unset_in_db (mechanism, "xml:merged:" SYSGCONFDIR "/gconf.xml.mandatory",
- includes, excludes, &error);
-
- if (error) {
- error2 = g_error_new_literal (GCONF_DEFAULTS_ERROR,
- GCONF_DEFAULTS_ERROR_GENERAL,
- error->message);
+ result = polkit_authority_check_authorization_finish (authority,
+ res,
+ &error);
+ if (error != NULL) {
+ g_debug ("error checking action '%s'\n", error->message);
+ throw_error (data->context,
+ GCONF_DEFAULTS_ERROR_NOT_PRIVILEGED,
+ "Not Authorized: %s", error->message);
g_error_free (error);
+ goto out;
+ }
+ else {
+ if (polkit_authorization_result_get_is_authorized (result)) {
+ g_debug ("result for '%s': authorized\n",
+ data->actions[data->id]);
+ is_authorized = TRUE;
+ }
+ else if (polkit_authorization_result_get_is_challenge (result)) {
+ g_debug ("result for '%s': challenge\n",
+ data->actions[data->id]);
+ is_authorized = TRUE;
+ }
+ else {
+ g_debug ("result for '%s': not authorized\n",
+ data->actions[data->id]);
+ is_authorized = FALSE;
+ }
+ }
- dbus_g_method_return_error (context, error2);
- g_error_free (error2);
+ if (is_authorized) {
+ data->id++;
+ if (data->actions[data->id] == NULL) {
+ g_debug ("return TRUE\n");
+ dbus_g_method_return (data->context, TRUE);
+ }
+ else {
+ check_next_action (data);
+ return; /* continue operation */
+ }
}
- else
- dbus_g_method_return (context);
+ else {
+ g_debug ("return FALSE\n");
+ dbus_g_method_return (data->context, FALSE);
+ }
+
out:
- start_killtimer();
+ check_auth_data_free (data);
+ g_object_unref (result);
+ stop_operation ();
+}
+
+static void
+check_permissions_only (GConfDefaults *mechanism,
+ DBusGMethodInvocation *context,
+ gchar **actions,
+ AuthObtainedCallback auth_obtained_callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ CheckAuthData *data;
+
+ data = g_new0 (CheckAuthData, 1);
+ data->mechanism = g_object_ref (mechanism);
+ data->context = context;
+ data->actions = actions;
+ data->flags = 0;
+ data->id = 0;
+ data->check_auth_callback = (GAsyncReadyCallback)check_authorization_only_callback;
+ data->auth_obtained_callback = NULL;
+ data->user_data = NULL;
+ data->destroy = NULL;
+ data->subject = polkit_system_bus_name_new (dbus_g_method_get_sender (context));
+
+ check_next_action (data);
+}
+
+static void
+do_check (GConfDefaults *mechanism,
+ gboolean mandatory,
+ const gchar **includes,
+ DBusGMethodInvocation *context)
+{
+ ActionData *adata;
+
+ start_operation ();
+
+ adata = g_new0 (ActionData, 1);
+ adata->mechanism = g_object_ref (mechanism);
+ adata->context = context;
+ adata->includes = g_strdupv ((gchar **)includes);
+ adata->actions_ready_callback = check_permissions_only;
+ adata->auth_obtained_callback = NULL;
+ adata->data = NULL;
+ adata->destroy = NULL;
+
+ if (mandatory) {
+ adata->annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix";
+ adata->default_action = "org.gnome.gconf.defaults.set-mandatory";
+ }
+ else {
+ adata->annotation_key = "org.gnome.gconf.defaults.set-system.prefix";
+ adata->default_action = "org.gnome.gconf.defaults.set-system";
+ }
+
+ polkit_authority_enumerate_actions (mechanism->priv->auth,
+ NULL,
+ actions_ready_cb,
+ adata);
+}
+
+void
+gconf_defaults_can_set_system (GConfDefaults *mechanism,
+ const char **includes,
+ DBusGMethodInvocation *context)
+{
+ do_check (mechanism, FALSE, includes, context);
}
+
+void
+gconf_defaults_can_set_mandatory (GConfDefaults *mechanism,
+ const char **includes,
+ DBusGMethodInvocation *context)
+{
+ do_check (mechanism, TRUE, includes, context);
+}
+
16 years ago
diff -up GConf-2.26.2/defaults/gconf-defaults.h.polkit1 GConf-2.26.2/defaults/gconf-defaults.h
--- GConf-2.26.2/defaults/gconf-defaults.h.polkit1 2009-05-14 11:13:40.000000000 -0400
+++ GConf-2.26.2/defaults/gconf-defaults.h 2009-06-09 21:07:45.474639261 -0400
@@ -83,6 +83,14 @@ void gconf_defaults_unset_mand
const char **excludes,
DBusGMethodInvocation *context);
+void gconf_defaults_can_set_system (GConfDefaults *mechanism,
+ const char **includes,
+ DBusGMethodInvocation *context);
+
+void gconf_defaults_can_set_mandatory (GConfDefaults *mechanism,
+ const char **includes,
+ DBusGMethodInvocation *context);
+
G_END_DECLS
#endif /* GCONF_DEFAULTS_H */
16 years ago
diff -up GConf-2.26.2/defaults/gconf-defaults-main.c.polkit1 GConf-2.26.2/defaults/gconf-defaults-main.c
--- GConf-2.26.2/defaults/gconf-defaults-main.c.polkit1 2009-05-05 20:37:32.000000000 -0400
+++ GConf-2.26.2/defaults/gconf-defaults-main.c 2009-06-09 21:07:45.475644220 -0400
@@ -122,6 +122,29 @@ get_system_bus (void)
return bus;
}
+extern gboolean disable_killtimer;
+gboolean debug = FALSE;
+
+GOptionEntry entries [] = {
+ { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Emit debug output", NULL },
+ { "no-kill", 0, 0, G_OPTION_ARG_NONE, &disable_killtimer, "Don't exit when idle", NULL },
+ { NULL, }
+};
+
+static gint log_levels = (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
+
+void
+log_default_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer unused_data)
+{
+ if ((log_level & log_levels) != 0) {
+ g_log_default_handler (log_domain, log_level, message, unused_data);
+ }
+}
+
+
int
main (int argc, char **argv)
{
16 years ago
@@ -130,6 +153,8 @@ main (int argc, char **argv)
DBusGProxy *bus_proxy;
DBusGConnection *connection;
int ret;
+ GOptionContext *options;
+ GError *error = NULL;
ret = 1;
16 years ago
@@ -139,8 +164,22 @@ main (int argc, char **argv)
dbus_g_thread_init ();
g_type_init ();
+ options = g_option_context_new (NULL);
+ g_option_context_add_main_entries (options, entries, NULL);
+ if (!g_option_context_parse (options, &argc, &argv, &error)) {
+ g_warning ("Failed to parse options: %s\n", error->message);
+ g_error_free (error);
+ }
+ g_option_context_free (options);
+
+ g_log_set_default_handler (log_default_handler, NULL);
+ if (debug) {
+ log_levels = log_levels | G_LOG_LEVEL_DEBUG;
+ }
+
connection = get_system_bus ();
if (connection == NULL) {
+ g_warning ("Could not get system bus connection; bailing out");
goto out;
}
16 years ago
diff -up GConf-2.26.2/defaults/gconf-defaults.xml.polkit1 GConf-2.26.2/defaults/gconf-defaults.xml
--- GConf-2.26.2/defaults/gconf-defaults.xml.polkit1 2009-05-14 11:13:40.000000000 -0400
+++ GConf-2.26.2/defaults/gconf-defaults.xml 2009-06-09 21:07:45.476638353 -0400
@@ -2,12 +2,12 @@
<node name="/">
<interface name="org.gnome.GConf.Defaults">
<!--
- includes: an array of GConf paths to copy from the
+ includes: an array of GConf paths to copy from the
callers GConf database to the system database
excludes: an array of GConf paths to omit
- Copies values from the callers GConf database to the system-wide
- database. The subtree below each included path is copied recursively,
+ Copies values from the callers GConf database to the system-wide
+ database. The subtree below each included path is copied recursively,
skipping the excluded subtrees.
To decide which PolicyKit privilege to require for the copying of
each path in includes, the mechanism looks for a privilege with an
@@ -21,16 +21,22 @@
<arg name="excludes" direction="in" type="as"/>
</method>
+ <method name="CanSetSystem">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="includes" direction="in" type="as"/>
+ <arg name="result" direction="out" type="b"/>
+ </method>
+
<signal name="SystemSet">
<arg name="keys" type="as"/>
</signal>
<!--
- includes: an array of GConf paths to copy from the
+ includes: an array of GConf paths to copy from the
callers GConf database to the mandatory database
excludes: an array of GConf paths to omit
- Copies values from the callers GConf database to the system-wide
- mandatory database. The subtree below each included path is copied
+ Copies values from the callers GConf database to the system-wide
+ mandatory database. The subtree below each included path is copied
recursively, skipping the excluded subtrees.
To decide which PolicyKit privilege to require for the copying of
each path in includes, the mechanism looks for a privilege with an
@@ -41,12 +47,12 @@
<method name="SetMandatory">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="includes" direction="in" type="as"/>
- <arg name="excludes" direction="in" type="as"/>
+ <arg name="result" direction="out" type="b"/>
</method>
<!--
Unsets keys in the system-wide mandatory GConf database, making the
- keys writable again. The subtree below each included path is copied
+ keys writable again. The subtree below each included path is copied
recursively, skipping the excluded subtrees.
To decide which PolicyKit privilege to require for the copying of
each path in includes, the mechanism looks for a privilege with an
@@ -59,6 +65,12 @@
<arg name="includes" direction="in" type="as"/>
<arg name="excludes" direction="in" type="as"/>
</method>
-
+
+ <method name="CanSetMandatory">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="includes" direction="in" type="as"/>
+ <arg name="result" direction="out" type="b"/>
+ </method>
+
</interface>
</node>
16 years ago
diff -up GConf-2.26.2/defaults/Makefile.am.polkit1 GConf-2.26.2/defaults/Makefile.am
--- GConf-2.26.2/defaults/Makefile.am.polkit1 2009-04-25 02:44:06.000000000 -0400
+++ GConf-2.26.2/defaults/Makefile.am 2009-06-09 21:07:45.478662799 -0400
@@ -20,13 +20,13 @@ INCLUDES = \
gconf_defaults_mechanism_LDADD = \
$(top_builddir)/gconf/libgconf-2.la \
- $(DEFAULTS_LIBS)
+ $(DEFAULTS_LIBS)
BUILT_SOURCES = gconf-defaults-glue.h
dbus_servicesdir = $(datadir)/dbus-1/system-services
dbus_confdir = $(sysconfdir)/dbus-1/system.d
-polkitdir = $(datadir)/PolicyKit/policy
+polkitdir = $(datadir)/polkit-1/actions
dbus_services_in_files = org.gnome.GConf.Defaults.service.in
polkit_in_files = org.gnome.gconf.defaults.policy.in
16 years ago
@@ -41,9 +41,6 @@ dbus_conf_DATA = org.gnome.GConf.Default
@INTLTOOL_POLICY_RULE@
polkit_DATA = $(polkit_in_files:.policy.in=.policy)
-check:
- $(POLKIT_POLICY_FILE_VALIDATE) $(polkit_DATA)
-
EXTRA_DIST = \
$(dbus_services_in_files) \
org.gnome.GConf.Defaults.conf \