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