rpms/GConf2/devel polkit1.patch,NONE,1.1 GConf2.spec,1.105,1.106

Matthias Clasen mclasen at fedoraproject.org
Wed Jun 10 00:52:49 UTC 2009


Author: mclasen

Update of /cvs/pkgs/rpms/GConf2/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv31629

Modified Files:
	GConf2.spec 
Added Files:
	polkit1.patch 
Log Message:
Port to PolicyKit 1


polkit1.patch:

--- NEW FILE polkit1.patch ---
diff -u -r GConf-2.26.0/configure.in hacked/configure.in
--- GConf-2.26.0/configure.in	2009-03-16 22:54:22.000000000 -0400
+++ hacked/configure.in	2009-05-11 22:12:16.772360600 -0400
@@ -172,7 +172,7 @@
               [enable_defaults_service="$enableval"],
               [enable_defaults_service=auto])
 if test "x$enable_defaults_service" != "xno" ; then
-  PKG_CHECK_MODULES(DEFAULTS, glib-2.0 gobject-2.0 dbus-1 dbus-glib-1 polkit-dbus, HAVE_POLKIT=yes, HAVE_POLKIT=no)
+  PKG_CHECK_MODULES(DEFAULTS, glib-2.0 gobject-2.0 dbus-1 dbus-glib-1 polkit-gobject-1, HAVE_POLKIT=yes, HAVE_POLKIT=no)
   if test "x$HAVE_POLKIT" = "xno"; then
     if test "x$enable_defaults_service" = "xyes" ; then
       AC_MSG_ERROR([[
@@ -187,12 +187,6 @@
 
 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],
-                [polkit-policy-file-validate], [polkit-policy-file-validate])
-  if test -z "$POLKIT_POLICY_FILE_VALIDATE"; then
-      AC_MSG_ERROR([polkit-policy-file-validate not found])
-  fi
 fi
 
 AM_CONDITIONAL(ENABLE_DEFAULTS_SERVICE, [test "x$enable_defaults_service" != "xno"])
diff -u -r GConf-2.26.0/defaults/gconf-defaults.c hacked/defaults/gconf-defaults.c
--- GConf-2.26.0/defaults/gconf-defaults.c	2009-02-16 13:17:44.000000000 -0500
+++ hacked/defaults/gconf-defaults.c	2009-05-13 17:44:52.474938376 -0400
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2008 Matthias Clasen <mclasen at redhat.com>
+ * Copyright (C) 2008, 2009 Matthias Clasen <mclasen at 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
@@ -56,10 +55,14 @@
 }
 
 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;
@@ -69,15 +72,38 @@
 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);
@@ -105,7 +131,7 @@
 gconf_defaults_error_get_type (void)
 {
         static GType etype = 0;
-        
+
         if (etype == 0)
         {
                 static const GEnumValue values[] =
@@ -114,12 +140,12 @@
                                 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;
 }
 
@@ -191,56 +217,18 @@
 
         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);
@@ -252,7 +240,7 @@
                 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,
@@ -288,33 +276,37 @@
 
 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;
 	}
 
@@ -323,56 +315,158 @@
 	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 *
@@ -398,11 +492,11 @@
 		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;
 	}
@@ -434,13 +528,13 @@
 	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);
@@ -461,7 +555,7 @@
 {
 	GConfValue *value;
 
-	if (path_is_excluded (path, excludes)) 
+	if (path_is_excluded (path, excludes))
 		return;
 
 	value = gconf_client_get (src, path, NULL);
@@ -471,69 +565,66 @@
 	}
 }
 
+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);
@@ -542,45 +633,175 @@
 	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
@@ -594,20 +815,13 @@
 	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);
@@ -615,7 +829,15 @@
 	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
@@ -624,7 +846,7 @@
                               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
@@ -636,13 +858,13 @@
 	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);
@@ -654,25 +876,25 @@
 	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;
@@ -680,7 +902,7 @@
 	int i;
 
 	engine = gconf_engine_get_local (address, error);
-	if (*error) 
+	if (*error)
 		goto out;
 
 	dest = gconf_client_get_for_engine (engine);
@@ -706,48 +928,219 @@
 		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);
+}
+
diff -u -r GConf-2.26.0/defaults/gconf-defaults.h hacked/defaults/gconf-defaults.h
--- GConf-2.26.0/defaults/gconf-defaults.h	2008-12-02 11:06:14.000000000 -0500
+++ hacked/defaults/gconf-defaults.h	2009-05-12 13:27:54.300540238 -0400
@@ -83,6 +83,14 @@
                                                  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 */
diff -u -r GConf-2.26.0/defaults/gconf-defaults-main.c hacked/defaults/gconf-defaults-main.c
--- GConf-2.26.0/defaults/gconf-defaults-main.c	2008-12-02 11:06:14.000000000 -0500
+++ hacked/defaults/gconf-defaults-main.c	2009-05-12 13:37:59.046345548 -0400
@@ -122,6 +122,29 @@
         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)
 {
@@ -130,6 +153,8 @@
         DBusGProxy          *bus_proxy;
         DBusGConnection     *connection;
         int                  ret;
+	GOptionContext      *options;
+	GError              *error = NULL;
 
         ret = 1;
 
@@ -139,8 +164,22 @@
         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;
         }
 
diff -u -r GConf-2.26.0/defaults/gconf-defaults.xml hacked/defaults/gconf-defaults.xml
--- GConf-2.26.0/defaults/gconf-defaults.xml	2008-12-02 11:06:14.000000000 -0500
+++ hacked/defaults/gconf-defaults.xml	2009-05-12 13:18:12.873380233 -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>
diff -u -r GConf-2.26.0/defaults/Makefile.am hacked/defaults/Makefile.am
--- GConf-2.26.0/defaults/Makefile.am	2009-02-16 13:17:44.000000000 -0500
+++ hacked/defaults/Makefile.am	2009-05-11 22:12:16.773368001 -0400
@@ -20,13 +20,13 @@
 
 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
@@ -41,9 +41,6 @@
 @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		\


Index: GConf2.spec
===================================================================
RCS file: /cvs/pkgs/rpms/GConf2/devel/GConf2.spec,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -p -r1.105 -r1.106
--- GConf2.spec	16 May 2009 00:12:59 -0000	1.105
+++ GConf2.spec	10 Jun 2009 00:52:19 -0000	1.106
@@ -7,7 +7,7 @@
 Summary: A process-transparent configuration system
 Name: GConf2
 Version: 2.26.2
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: LGPLv2+
 Group: System Environment/Base
 Source: http://download.gnome.org/sources/GConf/2.26/GConf-%{version}.tar.bz2
@@ -36,6 +36,10 @@ Patch0: GConf-2.18.0.1-reload.patch
 # http://bugzilla.gnome.org/show_bug.cgi?id=568845
 Patch1: GConf-gettext.patch
 
+# https://bugzilla.redhat.com/show_bug.cgi?id=498370
+Patch2: polkit1.patch
+
+
 %description
 GConf is a process-transparent configuration database API used to
 store user preferences. It has pluggable backends and features to
@@ -71,6 +75,7 @@ which require GTK+.
 %setup -q -n GConf-%{version}
 %patch0 -p1 -b .reload
 %patch1 -p1 -b .gettext
+%patch2 -p1 -b .polkit1
 
 %build
 %configure --disable-static --enable-defaults-service
@@ -145,6 +150,9 @@ fi
 %{_libdir}/pkgconfig/*
 
 %changelog
+* Tue Jun  9 2009 Matthias Clasen  <mclasen at redhat.com> - 2.26.2-2
+- Port to PolicyKit 1
+
 * Fri May 15 2009 Matthias Clasen  <mclasen at redhat.com> - 2.26.2-1
 - Update to 2.26.2
 - See http://download.gnome.org/sources/GConf/2.26/GConf-2.26.1.news




More information about the fedora-extras-commits mailing list