diff --git a/PackageKit-port-to-polkit1.patch b/PackageKit-port-to-polkit1.patch new file mode 100644 index 0000000..e18c14a --- /dev/null +++ b/PackageKit-port-to-polkit1.patch @@ -0,0 +1,5520 @@ +diff --git a/configure.ac b/configure.ac +index 47b6e4e..d6364d2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -130,8 +130,7 @@ GIO_REQUIRED=2.16.1 + DBUS_REQUIRED=1.1.1 + DBUS_GLIB_REQUIRED=0.74 + LIBNM_GLIB_REQUIRED=0.6.4 +-POLKIT_DBUS_REQUIRED=0.8 +-POLKIT_GRANT_REQUIRED=0.8 ++POLKIT_GOBJECT_REQUIRED=0.91 + QTCORE_REQUIRED=4.4.0 + QTDBUS_REQUIRED=4.4.0 + QTGUI_REQUIRED=4.4.0 +@@ -549,15 +548,9 @@ AC_SUBST(security_framework, "$with_security_framework") + + if test x$with_security_framework = xpolkit; then + PKG_CHECK_MODULES(POLKIT, \ +- polkit-dbus >= $POLKIT_DBUS_REQUIRED \ +- polkit-grant >= $POLKIT_GRANT_REQUIRED) ++ polkit-gobject-1 >= $POLKIT_GOBJECT_REQUIRED) + AC_SUBST(POLKIT_CFLAGS) + AC_SUBST(POLKIT_LIBS) +- 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 + AC_DEFINE(USE_SECURITY_POLKIT, 1, [if we should use PolicyKit]) + elif test x$with_security_framework = xdummy; then + AC_DEFINE(USE_SECURITY_DUMMY, 1, [if we should use a dummy security framework]) +diff --git a/lib/packagekit-glib/pk-client.c b/lib/packagekit-glib/pk-client.c +index c9200e9..1461451 100644 +--- a/lib/packagekit-glib/pk-client.c ++++ b/lib/packagekit-glib/pk-client.c +@@ -42,10 +42,6 @@ + #include + #include + +-#ifdef USE_SECURITY_POLKIT +-#include +-#endif +- + #include + #include + #include +@@ -190,131 +186,53 @@ pk_client_error_get_type (void) + * pk_client_error_fixup: + * @error: a %GError + **/ +-static gboolean +-pk_client_error_fixup (GError **error) ++static GError * ++pk_client_error_fixup (GError *error_local) + { ++ GError *error; + const gchar *name; +- guint code; +- if (error != NULL && *error != NULL) { +- /* get some proper debugging */ +- if ((*error)->domain == DBUS_GERROR && +- (*error)->code == DBUS_GERROR_REMOTE_EXCEPTION) { +- /* use one of our local codes */ +- name = dbus_g_error_get_name (*error); +- code = PK_CLIENT_ERROR_FAILED; +- +- /* trim common prefix */ +- if (g_str_has_prefix (name, "org.freedesktop.PackageKit.Transaction.")) +- name = &name[39]; +- +- /* try to get a better error */ +- if (g_str_has_prefix (name, "PermissionDenied") || +- g_str_has_prefix (name, "RefusedByPolicy")) +- code = PK_CLIENT_ERROR_FAILED_AUTH; +- else if (g_str_has_prefix (name, "PackageIdInvalid") || +- g_str_has_prefix (name, "SearchInvalid") || +- g_str_has_prefix (name, "FilterInvalid") || +- g_str_has_prefix (name, "InvalidProvide") || +- g_str_has_prefix (name, "InputInvalid")) +- code = PK_CLIENT_ERROR_INVALID_INPUT; +- else if (g_str_has_prefix (name, "PackInvalid") || +- g_str_has_prefix (name, "NoSuchFile") || +- g_str_has_prefix (name, "NoSuchDirectory")) +- code = PK_CLIENT_ERROR_INVALID_FILE; +- else if (g_str_has_prefix (name, "NotSupported")) +- code = PK_CLIENT_ERROR_NOT_SUPPORTED; +- +- egg_debug ("fixing up code from %s to %i", name, code); +- (*error)->code = code; +- } +- if (g_str_has_prefix ((*error)->message, "org.freedesktop.packagekit.")) { +- egg_debug ("fixing up code for Policykit auth failure"); +- g_error_free (*error); +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED_AUTH, "PolicyKit authorization failure"); +- } +- return TRUE; +- } +- return FALSE; +-} +- +-/** +- * pk_client_error_refused_by_policy: +- * @error: a valid #GError +- * +- * Return value: %TRUE if the error is the PolicyKit "RefusedByPolicy" +- **/ +-static gboolean +-pk_client_error_refused_by_policy (GError *error) +-{ +- const gchar *error_name; +- +- /* if not set */ +- if (error == NULL) +- return FALSE; +- +- /* not a dbus error */ +- if (error->code != DBUS_GERROR_REMOTE_EXCEPTION) { +- egg_warning ("not a remote exception: %s", error->message); +- return FALSE; +- } +- +- /* check for specific error */ +- error_name = dbus_g_error_get_name (error); +- egg_debug ("ERROR: %s: %s", error_name, error->message); +- if (egg_strequal (error_name, "org.freedesktop.PackageKit.RefusedByPolicy")) +- return TRUE; +- if (egg_strequal (error_name, "org.freedesktop.PackageKit.Transaction.RefusedByPolicy")) +- return TRUE; +- return FALSE; +-} +- +-/** +- * pk_client_error_auth_obtain: +- * @error: the GError with the failure +- * +- * This function is indented to be passed failure messages from dbus methods +- * so that extra auth can be requested. +- * +- * Return value: if we gained the privilege we asked for +- **/ +-static gboolean +-pk_client_error_auth_obtain (GError *error) +-{ +- gboolean ret = FALSE; +-#ifdef USE_SECURITY_POLKIT +- PolKitAction *action = NULL; +- PolKitResult result; +- gchar *action_id = NULL; /* we don't free this */ +- DBusError error2; +- dbus_error_init (&error2); + +- g_return_val_if_fail (error != NULL, FALSE); ++ g_return_val_if_fail (error_local != NULL, NULL); + +- /* get PolKitAction */ +- ret = polkit_dbus_error_parse_from_strings ("org.freedesktop.PolicyKit.Error.NotAuthorized", error->message, &action, &result); +- if (!ret) { +- egg_warning ("Not a polkit auth failure: %s", error->message); +- return FALSE; ++ /* PolicyKit failure */ ++ if (g_str_has_prefix (error_local->message, "org.freedesktop.packagekit.")) { ++ egg_debug ("fixing up code for Policykit auth failure"); ++ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED_AUTH, "PolicyKit authorization failure"); ++ goto out; + } + +- /* get action_id from PolKitAction */ +- ret = polkit_action_get_action_id (action, &action_id); +- if (!ret) { +- egg_warning ("Unable to get an action ID"); +- return FALSE; ++ /* new default error with correct domain and code */ ++ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "%s", error_local->message); ++ ++ /* get some proper debugging */ ++ if (error_local->domain == DBUS_GERROR && ++ error_local->code == DBUS_GERROR_REMOTE_EXCEPTION) { ++ /* use one of our local codes */ ++ name = dbus_g_error_get_name (error_local); ++ ++ /* trim common prefix */ ++ if (g_str_has_prefix (name, "org.freedesktop.PackageKit.Transaction.")) ++ name = &name[39]; ++ ++ /* try to get a better error */ ++ if (g_str_has_prefix (name, "PermissionDenied") || ++ g_str_has_prefix (name, "RefusedByPolicy")) ++ error->code = PK_CLIENT_ERROR_FAILED_AUTH; ++ else if (g_str_has_prefix (name, "PackageIdInvalid") || ++ g_str_has_prefix (name, "SearchInvalid") || ++ g_str_has_prefix (name, "FilterInvalid") || ++ g_str_has_prefix (name, "InvalidProvide") || ++ g_str_has_prefix (name, "InputInvalid")) ++ error->code = PK_CLIENT_ERROR_INVALID_INPUT; ++ else if (g_str_has_prefix (name, "PackInvalid") || ++ g_str_has_prefix (name, "NoSuchFile") || ++ g_str_has_prefix (name, "NoSuchDirectory")) ++ error->code = PK_CLIENT_ERROR_INVALID_FILE; ++ else if (g_str_has_prefix (name, "NotSupported")) ++ error->code = PK_CLIENT_ERROR_NOT_SUPPORTED; + } +- +- /* this blocks - use polkit_gnome_auth_obtain for non blocking version */ +- ret = polkit_auth_obtain (action_id, 0, getpid (), &error2); +- if (dbus_error_is_set (&error2)) +- egg_warning ("Failed to obtain auth: %s", error2.message); +- dbus_error_free (&error2); +- +- egg_debug ("gained %s privilege = %d", action_id, ret); +- +- polkit_action_unref (action); +-#endif +- return ret; ++out: ++ return error; + } + + /** +@@ -944,7 +862,8 @@ pk_client_allow_cancel_cb (DBusGProxy *proxy, gboolean allow_cancel, PkClient *c + gboolean + pk_client_get_allow_cancel (PkClient *client, gboolean *allow_cancel, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (client->priv->tid != NULL, FALSE); +@@ -954,13 +873,21 @@ pk_client_get_allow_cancel (PkClient *client, gboolean *allow_cancel, GError **e + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetAllowCancel", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetAllowCancel", &error_local, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, allow_cancel, + G_TYPE_INVALID); +- pk_client_error_fixup (error); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++out: + return ret; + } + +@@ -1033,8 +960,9 @@ pk_client_message_cb (DBusGProxy *proxy, const gchar *message_text, const gchar + gboolean + pk_client_get_status (PkClient *client, PkStatusEnum *status, GError **error) + { +- gboolean ret; +- gchar *status_text; ++ gboolean ret = FALSE; ++ gchar *status_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (status != NULL, FALSE); + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -1045,17 +973,23 @@ pk_client_get_status (PkClient *client, PkStatusEnum *status, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetStatus", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetStatus", &error_local, + G_TYPE_INVALID, + G_TYPE_STRING, &status_text, + G_TYPE_INVALID); +- pk_client_error_fixup (error); +- if (ret) { +- *status = pk_status_enum_from_text (status_text); +- g_free (status_text); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } ++ *status = pk_status_enum_from_text (status_text); ++out: ++ g_free (status_text); + return ret; + } + +@@ -1073,7 +1007,8 @@ pk_client_get_status (PkClient *client, PkStatusEnum *status, GError **error) + gboolean + pk_client_get_package (PkClient *client, gchar **package, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package != NULL, FALSE); +@@ -1084,13 +1019,21 @@ pk_client_get_package (PkClient *client, gchar **package, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetPackageLast", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetPackageLast", &error_local, + G_TYPE_INVALID, + G_TYPE_STRING, package, + G_TYPE_INVALID); +- pk_client_error_fixup (error); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++out: + return ret; + } + +@@ -1114,7 +1057,8 @@ gboolean + pk_client_get_progress (PkClient *client, guint *percentage, guint *subpercentage, + guint *elapsed, guint *remaining, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (client->priv->tid != NULL, FALSE); +@@ -1124,16 +1068,24 @@ pk_client_get_progress (PkClient *client, guint *percentage, guint *subpercentag + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetProgress", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetProgress", &error_local, + G_TYPE_INVALID, + G_TYPE_UINT, percentage, + G_TYPE_UINT, subpercentage, + G_TYPE_UINT, elapsed, + G_TYPE_UINT, remaining, + G_TYPE_INVALID); +- pk_client_error_fixup (error); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++out: + return ret; + } + +@@ -1152,9 +1104,10 @@ pk_client_get_progress (PkClient *client, guint *percentage, guint *subpercentag + gboolean + pk_client_get_role (PkClient *client, PkRoleEnum *role, gchar **text, GError **error) + { +- gboolean ret; +- gchar *role_text; ++ gboolean ret = FALSE; ++ gchar *role_text = NULL; + gchar *text_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (role != NULL, FALSE); +@@ -1164,7 +1117,7 @@ pk_client_get_role (PkClient *client, PkRoleEnum *role, gchar **text, GError **e + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } + + /* we can avoid a trip to the daemon */ +@@ -1173,41 +1126,25 @@ pk_client_get_role (PkClient *client, PkRoleEnum *role, gchar **text, GError **e + return TRUE; + } + +- ret = dbus_g_proxy_call (client->priv->proxy, "GetRole", error, ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetRole", &error_local, + G_TYPE_INVALID, + G_TYPE_STRING, &role_text, + G_TYPE_STRING, &text_temp, + G_TYPE_INVALID); +- if (ret) { +- *role = pk_role_enum_from_text (role_text); +- g_free (role_text); +- if (text != NULL) +- *text = text_temp; +- else +- g_free (text_temp); +- } +- pk_client_error_fixup (error); +- return ret; +-} +- +-/** +- * pk_client_cancel_action: +- **/ +-static gboolean +-pk_client_cancel_action (PkClient *client, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "Cancel", error, +- G_TYPE_INVALID, G_TYPE_INVALID); ++ *role = pk_role_enum_from_text (role_text); ++ if (text != NULL) ++ *text = text_temp; ++ else ++ g_free (text_temp); ++out: ++ g_free (role_text); + return ret; + } + +@@ -1227,38 +1164,35 @@ pk_client_cancel_action (PkClient *client, GError **error) + gboolean + pk_client_cancel (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* we don't need to cancel, so return TRUE */ +- if (client->priv->proxy == NULL) +- return TRUE; ++ if (client->priv->proxy == NULL) { ++ ret = TRUE; ++ goto out; ++ } + + /* we cannot cancel a client in ::Finished() */ + if (client->priv->is_finishing) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "unable to cancel client in finished handler"); +- return FALSE; ++ goto out; + } + +- /* hopefully do the operation first time */ +- ret = pk_client_cancel_action (client, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* retry the action now we have got auth */ +- ret = pk_client_cancel_action (client, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "Cancel", &error_local, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* no error to process */ + if (ret) + goto out; +@@ -1272,8 +1206,9 @@ pk_client_cancel (PkClient *client, GError **error) + } + + /* we failed one of these, return the error to the user */ +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); + out: + return ret; + } +@@ -1316,8 +1251,8 @@ pk_client_transaction_timeout_cb (PkClient *client) + static gboolean + pk_client_allocate_transaction_id (PkClient *client, GError **error) + { +- gboolean ret; +- gchar *tid; ++ gboolean ret = FALSE; ++ gchar *tid = NULL; + GError *error_local = NULL; + const gchar **list; + guint len; +@@ -1332,7 +1267,7 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error) + if (len > 0) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "will not queue as timeout 0"); +- return FALSE; ++ goto out; + } + } + +@@ -1346,7 +1281,7 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to get a TID: %s (%i)", error_local->message, error_local->code); + } + g_error_free (error_local); +- return FALSE; ++ goto out; + } + + /* free any old tid */ +@@ -1355,19 +1290,19 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error) + + /* set that new ID to this GObject */ + ret = pk_client_set_tid (client, tid, &error_local); +- g_free (tid); + if (!ret) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to set TID: %s", error_local->message); + g_error_free (error_local); +- return FALSE; ++ goto out; + } + + /* set a timeout */ + if (client->priv->timeout > 0) + client->priv->timeout_id = g_timeout_add (client->priv->timeout, (GSourceFunc) pk_client_transaction_timeout_cb, client); +- +- return TRUE; ++out: ++ g_free (tid); ++ return ret; + } + + /** +@@ -1383,8 +1318,9 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error) + gboolean + pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1393,13 +1329,13 @@ pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_UPDATES; +@@ -1409,14 +1345,24 @@ pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdates", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdates", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1424,7 +1370,8 @@ pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1440,7 +1387,8 @@ pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error) + gboolean + pk_client_get_categories (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1449,13 +1397,13 @@ pk_client_get_categories (PkClient *client, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_CATEGORIES; +@@ -1468,11 +1416,22 @@ pk_client_get_categories (PkClient *client, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetCategories", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetCategories", &error_local, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1480,30 +1439,7 @@ pk_client_get_categories (PkClient *client, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); +- return ret; +-} +- +-/** +- * pk_client_update_system_action: +- **/ +-static gboolean +-pk_client_update_system_action (PkClient *client, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- if (error != NULL) +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "UpdateSystem", error, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -1524,7 +1460,7 @@ pk_client_update_system_action (PkClient *client, GError **error) + gboolean + pk_client_update_system (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -1534,7 +1470,7 @@ pk_client_update_system (PkClient *client, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -1545,34 +1481,28 @@ pk_client_update_system (PkClient *client, GError **error) + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_UPDATE_SYSTEM; + +- /* hopefully do the operation first time */ +- ret = pk_client_update_system_action (client, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_update_system_action (client, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ if (error != NULL) ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ ret = FALSE; ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "UpdateSystem", &error_local, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1580,7 +1510,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- ++out: + return ret; + } + +@@ -1599,8 +1529,9 @@ out: + gboolean + pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1609,13 +1540,13 @@ pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_SEARCH_NAME; +@@ -1626,15 +1557,25 @@ pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "SearchName", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "SearchName", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1642,7 +1583,8 @@ pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1662,8 +1604,9 @@ pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search + gboolean + pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *search, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1672,13 +1615,13 @@ pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *sea + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_SEARCH_DETAILS; +@@ -1689,15 +1632,25 @@ pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *sea + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "SearchDetails", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "SearchDetails", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1705,7 +1658,8 @@ pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *sea + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1723,8 +1677,9 @@ pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *sea + gboolean + pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *search, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1733,13 +1688,13 @@ pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *searc + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_SEARCH_GROUP; +@@ -1750,15 +1705,25 @@ pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *searc + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "SearchGroup", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "SearchGroup", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1766,7 +1731,8 @@ pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *searc + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1784,8 +1750,9 @@ pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *searc + gboolean + pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1794,13 +1761,13 @@ pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_SEARCH_FILE; +@@ -1811,15 +1778,25 @@ pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "SearchFile", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "SearchFile", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1827,7 +1804,8 @@ pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1846,9 +1824,10 @@ pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search + gboolean + pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids, gboolean recursive, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -1858,7 +1837,7 @@ pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -1868,13 +1847,13 @@ pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_DEPENDS; +@@ -1886,16 +1865,26 @@ pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "GetDepends", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetDepends", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRV, package_ids, + G_TYPE_BOOLEAN, recursive, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1903,7 +1892,8 @@ pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -1919,8 +1909,9 @@ pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids + gboolean + pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar *directory, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -1930,7 +1921,7 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -1940,14 +1931,13 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); +- if (!ret) { +- return FALSE; +- } ++ if (!ret) ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_DOWNLOAD_PACKAGES; +@@ -1958,12 +1948,23 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "DownloadPackages", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "DownloadPackages", &error_local, + G_TYPE_STRV, package_ids, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -1971,7 +1972,7 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: + return ret; + } + +@@ -1988,8 +1989,9 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar + gboolean + pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1998,13 +2000,13 @@ pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_PACKAGES; +@@ -2014,14 +2016,24 @@ pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "GetPackages", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetPackages", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2029,7 +2041,8 @@ pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -2048,7 +2061,8 @@ pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error) + gboolean + pk_client_set_locale (PkClient *client, const gchar *code, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (code != NULL, FALSE); +@@ -2058,12 +2072,20 @@ pk_client_set_locale (PkClient *client, const gchar *code, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "SetLocale", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "SetLocale", &error_local, + G_TYPE_STRING, code, + G_TYPE_INVALID, G_TYPE_INVALID); +- pk_client_error_fixup (error); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++out: + return ret; + } + +@@ -2082,9 +2104,10 @@ pk_client_set_locale (PkClient *client, const gchar *code, GError **error) + gboolean + pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_ids, gboolean recursive, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -2094,7 +2117,7 @@ pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_id + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2104,13 +2127,13 @@ pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_id + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_REQUIRES; +@@ -2122,16 +2145,26 @@ pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_id + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "GetRequires", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetRequires", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRV, package_ids, + G_TYPE_BOOLEAN, recursive, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2139,7 +2172,8 @@ pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_id + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -2161,9 +2195,10 @@ gboolean + pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum provides, + const gchar *search, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + const gchar *provides_text; +- gchar *filter_text; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (provides != PK_PROVIDES_ENUM_UNKNOWN, FALSE); +@@ -2174,13 +2209,13 @@ pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum pr + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_WHAT_PROVIDES; +@@ -2194,16 +2229,26 @@ pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum pr + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "WhatProvides", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "WhatProvides", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRING, provides_text, + G_TYPE_STRING, search, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2211,7 +2256,8 @@ pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum pr + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -2229,8 +2275,9 @@ pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum pr + gboolean + pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -2240,7 +2287,7 @@ pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **err + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2250,13 +2297,13 @@ pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **err + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_UPDATE_DETAIL; +@@ -2270,12 +2317,23 @@ pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **err + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdateDetail", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdateDetail", &error_local, + G_TYPE_STRV, package_ids, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2283,30 +2341,7 @@ pk_client_get_update_detail (PkClient *client, gchar **package_ids, GError **err + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); +- return ret; +-} +- +-/** +- * pk_client_rollback_action: +- **/ +-static gboolean +-pk_client_rollback_action (PkClient *client, const gchar *transaction_id, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "Rollback", error, +- G_TYPE_STRING, transaction_id, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -2324,7 +2359,7 @@ pk_client_rollback_action (PkClient *client, const gchar *transaction_id, GError + gboolean + pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -2334,46 +2369,39 @@ pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **erro + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_ROLLBACK; + client->priv->cached_transaction_id = g_strdup (transaction_id); + +- /* hopefully do the operation first time */ +- ret = pk_client_rollback_action (client, transaction_id, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_rollback_action (client, transaction_id, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "Rollback", &error_local, ++ G_TYPE_STRING, transaction_id, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2381,7 +2409,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- ++out: + return ret; + } + +@@ -2401,8 +2429,9 @@ out: + gboolean + pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (packages != NULL, FALSE); +@@ -2412,13 +2441,13 @@ pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GErro + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_RESOLVE; +@@ -2429,15 +2458,25 @@ pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GErro + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "Resolve", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "Resolve", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_STRV, packages, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2445,7 +2484,8 @@ pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GErro + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -2463,8 +2503,9 @@ pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GErro + gboolean + pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -2474,7 +2515,7 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2484,13 +2525,13 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* we use the cached objects support */ + pk_obj_list_set_copy (client->priv->cached_data, (PkObjListCopyFunc) pk_details_obj_copy); +@@ -2504,12 +2545,23 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetDetails", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetDetails", &error_local, + G_TYPE_STRV, package_ids, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2517,7 +2569,7 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: + return ret; + } + +@@ -2534,7 +2586,8 @@ pk_client_get_details (PkClient *client, gchar **package_ids, GError **error) + gboolean + pk_client_get_distro_upgrades (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -2543,13 +2596,13 @@ pk_client_get_distro_upgrades (PkClient *client, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_DISTRO_UPGRADES; +@@ -2562,11 +2615,22 @@ pk_client_get_distro_upgrades (PkClient *client, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetDistroUpgrades", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetDistroUpgrades", &error_local, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2574,7 +2638,7 @@ pk_client_get_distro_upgrades (PkClient *client, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); ++out: + return ret; + } + +@@ -2591,8 +2655,9 @@ pk_client_get_distro_upgrades (PkClient *client, GError **error) + gboolean + pk_client_get_files (PkClient *client, gchar **package_ids, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (package_ids != NULL, FALSE); +@@ -2602,7 +2667,7 @@ pk_client_get_files (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2612,13 +2677,13 @@ pk_client_get_files (PkClient *client, gchar **package_ids, GError **error) + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_FILES; +@@ -2628,12 +2693,23 @@ pk_client_get_files (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetFiles", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetFiles", &error_local, + G_TYPE_STRV, package_ids, + G_TYPE_INVALID, G_TYPE_INVALID); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2641,34 +2717,7 @@ pk_client_get_files (PkClient *client, gchar **package_ids, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- pk_client_error_fixup (error); +- return ret; +-} +- +-/** +- * pk_client_remove_packages_action: +- **/ +-static gboolean +-pk_client_remove_packages_action (PkClient *client, gchar **package_ids, +- gboolean allow_deps, gboolean autoremove, +- GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "RemovePackages", error, +- G_TYPE_STRV, package_ids, +- G_TYPE_BOOLEAN, allow_deps, +- G_TYPE_BOOLEAN, autoremove, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -2690,7 +2739,7 @@ gboolean + pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow_deps, + gboolean autoremove, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + +@@ -2702,7 +2751,7 @@ pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2712,7 +2761,7 @@ pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -2726,34 +2775,29 @@ pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow + client->priv->cached_autoremove = autoremove; + client->priv->cached_package_ids = g_strdupv (package_ids); + +- /* hopefully do the operation first time */ +- ret = pk_client_remove_packages_action (client, package_ids, allow_deps, autoremove, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_remove_packages_action (client, package_ids, allow_deps, autoremove, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "RemovePackages", &error_local, ++ G_TYPE_STRV, package_ids, ++ G_TYPE_BOOLEAN, allow_deps, ++ G_TYPE_BOOLEAN, autoremove, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2761,30 +2805,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_refresh_cache_action: +- **/ +-static gboolean +-pk_client_refresh_cache_action (PkClient *client, gboolean force, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "RefreshCache", error, +- G_TYPE_BOOLEAN, force, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -2804,7 +2825,7 @@ pk_client_refresh_cache_action (PkClient *client, gboolean force, GError **error + gboolean + pk_client_refresh_cache (PkClient *client, gboolean force, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -2814,7 +2835,7 @@ pk_client_refresh_cache (PkClient *client, gboolean force, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -2826,34 +2847,27 @@ pk_client_refresh_cache (PkClient *client, gboolean force, GError **error) + client->priv->role = PK_ROLE_ENUM_REFRESH_CACHE; + client->priv->cached_force = force; + +- /* hopefully do the operation first time */ +- ret = pk_client_refresh_cache_action (client, force, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_refresh_cache_action (client, force, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "RefreshCache", &error_local, ++ G_TYPE_BOOLEAN, force, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2861,30 +2875,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_install_package_action: +- **/ +-static gboolean +-pk_client_install_package_action (PkClient *client, gchar **package_ids, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "InstallPackages", error, +- G_TYPE_STRV, package_ids, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -2901,7 +2892,7 @@ pk_client_install_package_action (PkClient *client, gchar **package_ids, GError + gboolean + pk_client_install_packages (PkClient *client, gchar **package_ids, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + +@@ -2913,7 +2904,7 @@ pk_client_install_packages (PkClient *client, gchar **package_ids, GError **erro + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -2923,7 +2914,7 @@ pk_client_install_packages (PkClient *client, gchar **package_ids, GError **erro + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -2935,34 +2926,27 @@ pk_client_install_packages (PkClient *client, gchar **package_ids, GError **erro + client->priv->role = PK_ROLE_ENUM_INSTALL_PACKAGES; + client->priv->cached_package_ids = g_strdupv (package_ids); + +- /* hopefully do the operation first time */ +- ret = pk_client_install_package_action (client, package_ids, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_install_package_action (client, package_ids, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "InstallPackages", &error_local, ++ G_TYPE_STRV, package_ids, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -2970,35 +2954,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_install_signature_action: +- **/ +-static gboolean +-pk_client_install_signature_action (PkClient *client, PkSigTypeEnum type, const gchar *key_id, +- const gchar *package_id, GError **error) +-{ +- gboolean ret; +- const gchar *type_text; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- type_text = pk_sig_type_enum_to_text (type); +- ret = dbus_g_proxy_call (client->priv->proxy, "InstallSignature", error, +- G_TYPE_STRING, type_text, +- G_TYPE_STRING, key_id, +- G_TYPE_STRING, package_id, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -3016,7 +2972,8 @@ gboolean + pk_client_install_signature (PkClient *client, PkSigTypeEnum type, const gchar *key_id, + const gchar *package_id, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ const gchar *type_text; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -3029,7 +2986,7 @@ pk_client_install_signature (PkClient *client, PkSigTypeEnum type, const gchar * + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3042,34 +2999,30 @@ pk_client_install_signature (PkClient *client, PkSigTypeEnum type, const gchar * + client->priv->cached_package_id = g_strdup (package_id); + client->priv->cached_key_id = g_strdup (key_id); + +- /* hopefully do the operation first time */ +- ret = pk_client_install_signature_action (client, type, key_id, package_id, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_install_signature_action (client, type, key_id, package_id, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } ++ type_text = pk_sig_type_enum_to_text (type); ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "InstallSignature", &error_local, ++ G_TYPE_STRING, type_text, ++ G_TYPE_STRING, key_id, ++ G_TYPE_STRING, package_id, ++ G_TYPE_INVALID, G_TYPE_INVALID); + +-out: + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3077,30 +3030,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_update_packages_action: +- **/ +-static gboolean +-pk_client_update_packages_action (PkClient *client, gchar **package_ids, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "UpdatePackages", error, +- G_TYPE_STRV, package_ids, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -3117,7 +3047,7 @@ pk_client_update_packages_action (PkClient *client, gchar **package_ids, GError + gboolean + pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + gchar *package_ids_temp; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + +@@ -3129,7 +3059,7 @@ pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* check the PackageIDs here to avoid a round trip if invalid */ +@@ -3139,7 +3069,7 @@ pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_INVALID_INPUT, "package_ids '%s' are not valid", package_ids_temp); + g_free (package_ids_temp); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3155,34 +3085,27 @@ pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error + client->priv->cached_package_ids = g_strdupv (package_ids); + } + +- /* hopefully do the operation first time */ +- ret = pk_client_update_packages_action (client, package_ids, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_update_packages_action (client, package_ids, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "UpdatePackages", &error_local, ++ G_TYPE_STRV, package_ids, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3190,31 +3113,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_install_files_action: +- **/ +-static gboolean +-pk_client_install_files_action (PkClient *client, gboolean trusted, gchar **files, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "InstallFiles", error, +- G_TYPE_BOOLEAN, trusted, +- G_TYPE_STRV, files, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -3232,9 +3131,8 @@ pk_resolve_local_path (const gchar *rel_path) + gchar *temp; + + /* don't trust realpath one little bit */ +- if (rel_path == NULL) { ++ if (rel_path == NULL) + return NULL; +- } + + /* ITS4: ignore, glibc allocates us a buffer to try and fix some brain damage */ + temp = realpath (rel_path, NULL); +@@ -3263,7 +3161,7 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel, + { + guint i; + guint length; +- gboolean ret; ++ gboolean ret = FALSE; + gchar **files = NULL; + gchar *file; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ +@@ -3276,7 +3174,7 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel, + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3304,34 +3202,28 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel, + client->priv->cached_trusted = trusted; + client->priv->cached_full_paths = g_strdupv (files); + +- /* hopefully do the operation first time */ +- ret = pk_client_install_files_action (client, trusted, files, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_install_files_action (client, trusted, files, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "InstallFiles", &error_local, ++ G_TYPE_BOOLEAN, trusted, ++ G_TYPE_STRV, files, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3339,7 +3231,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- ++out: + g_strfreev (files); + return ret; + } +@@ -3356,8 +3248,9 @@ out: + gboolean + pk_client_get_repo_list (PkClient *client, PkBitfield filters, GError **error) + { +- gboolean ret; +- gchar *filter_text; ++ gboolean ret = FALSE; ++ gchar *filter_text = NULL; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -3366,13 +3259,13 @@ pk_client_get_repo_list (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_GET_REPO_LIST; +@@ -3382,15 +3275,24 @@ pk_client_get_repo_list (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + filter_text = pk_filter_bitfield_to_text (filters); +- ret = dbus_g_proxy_call (client->priv->proxy, "GetRepoList", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetRepoList", &error_local, + G_TYPE_STRING, filter_text, + G_TYPE_INVALID, G_TYPE_INVALID); +- g_free (filter_text); +- pk_client_error_fixup (error); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3398,29 +3300,8 @@ pk_client_get_repo_list (PkClient *client, PkBitfield filters, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- return ret; +-} +- +-/** +- * pk_client_accept_eula_action: +- **/ +-static gboolean +-pk_client_accept_eula_action (PkClient *client, const gchar *eula_id, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "AcceptEula", error, +- G_TYPE_STRING, eula_id, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: ++ g_free (filter_text); + return ret; + } + +@@ -3437,7 +3318,7 @@ pk_client_accept_eula_action (PkClient *client, const gchar *eula_id, GError **e + gboolean + pk_client_accept_eula (PkClient *client, const gchar *eula_id, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -3448,7 +3329,7 @@ pk_client_accept_eula (PkClient *client, const gchar *eula_id, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3459,34 +3340,27 @@ pk_client_accept_eula (PkClient *client, const gchar *eula_id, GError **error) + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_ACCEPT_EULA; + +- /* hopefully do the operation first time */ +- ret = pk_client_accept_eula_action (client, eula_id, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_accept_eula_action (client, eula_id, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "AcceptEula", &error_local, ++ G_TYPE_STRING, eula_id, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3494,31 +3368,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_repo_enable_action: +- **/ +-static gboolean +-pk_client_repo_enable_action (PkClient *client, const gchar *repo_id, gboolean enabled, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "RepoEnable", error, +- G_TYPE_STRING, repo_id, +- G_TYPE_BOOLEAN, enabled, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -3536,7 +3386,7 @@ pk_client_repo_enable_action (PkClient *client, const gchar *repo_id, gboolean e + gboolean + pk_client_repo_enable (PkClient *client, const gchar *repo_id, gboolean enabled, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -3547,7 +3397,7 @@ pk_client_repo_enable (PkClient *client, const gchar *repo_id, gboolean enabled, + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3558,34 +3408,28 @@ pk_client_repo_enable (PkClient *client, const gchar *repo_id, gboolean enabled, + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_REPO_ENABLE; + +- /* hopefully do the operation first time */ +- ret = pk_client_repo_enable_action (client, repo_id, enabled, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_repo_enable_action (client, repo_id, enabled, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "RepoEnable", &error_local, ++ G_TYPE_STRING, repo_id, ++ G_TYPE_BOOLEAN, enabled, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3593,33 +3437,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- +- return ret; +-} +- +-/** +- * pk_client_repo_set_data_action: +- **/ +-static gboolean +-pk_client_repo_set_data_action (PkClient *client, const gchar *repo_id, +- const gchar *parameter, const gchar *value, GError **error) +-{ +- gboolean ret; +- +- g_return_val_if_fail (client != NULL, FALSE); +- g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- +- /* check to see if we have a valid proxy */ +- if (client->priv->proxy == NULL) { +- *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; +- } +- ret = dbus_g_proxy_call (client->priv->proxy, "RepoSetData", error, +- G_TYPE_STRING, repo_id, +- G_TYPE_STRING, parameter, +- G_TYPE_STRING, value, +- G_TYPE_INVALID, G_TYPE_INVALID); ++out: + return ret; + } + +@@ -3640,7 +3458,7 @@ gboolean + pk_client_repo_set_data (PkClient *client, const gchar *repo_id, const gchar *parameter, + const gchar *value, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + GError *error_local = NULL; /* we can't use the same error as we might be NULL */ + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -3653,7 +3471,7 @@ pk_client_repo_set_data (PkClient *client, const gchar *repo_id, const gchar *pa + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ +@@ -3664,34 +3482,29 @@ pk_client_repo_set_data (PkClient *client, const gchar *repo_id, const gchar *pa + /* save this so we can re-issue it */ + client->priv->role = PK_ROLE_ENUM_REPO_SET_DATA; + +- /* hopefully do the operation first time */ +- ret = pk_client_repo_set_data_action (client, repo_id, parameter, value, &error_local); +- +- /* we were refused by policy */ +- if (!ret && pk_client_error_refused_by_policy (error_local)) { +- /* try to get auth */ +- if (pk_client_error_auth_obtain (error_local)) { +- /* clear old error */ +- g_clear_error (&error_local); +- +- /* get a new tid */ +- ret = pk_client_allocate_transaction_id (client, &error_local); +- if (!ret) +- goto out; +- +- /* retry the action now we have got auth */ +- ret = pk_client_repo_set_data_action (client, repo_id, parameter, value, &error_local); +- } ++ /* check to see if we have a valid proxy */ ++ if (client->priv->proxy == NULL) { ++ *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); ++ goto out; + } + +-out: ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "RepoSetData", &error_local, ++ G_TYPE_STRING, repo_id, ++ G_TYPE_STRING, parameter, ++ G_TYPE_STRING, value, ++ G_TYPE_INVALID, G_TYPE_INVALID); ++ + /* we failed one of these, return the error to the user */ + if (!ret) { +- pk_client_error_fixup (&error_local); +- g_propagate_error (error, error_local); ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; + } + +- if (ret && !client->priv->is_finished) { ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3699,7 +3512,7 @@ out: + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } +- ++out: + return ret; + } + +@@ -3717,7 +3530,8 @@ out: + gboolean + pk_client_is_caller_active (PkClient *client, gboolean *is_active, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (is_active != NULL, FALSE); +@@ -3727,13 +3541,22 @@ pk_client_is_caller_active (PkClient *client, gboolean *is_active, GError **erro + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "IsCallerActive", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "IsCallerActive", &error_local, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, is_active, + G_TYPE_INVALID); +- pk_client_error_fixup (error); ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++out: + return ret; + } + +@@ -3750,7 +3573,8 @@ pk_client_is_caller_active (PkClient *client, gboolean *is_active, GError **erro + gboolean + pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; ++ GError *error_local = NULL; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -3759,13 +3583,13 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "TID already set to %s", client->priv->tid); +- return FALSE; ++ goto out; + } + + /* get and set a new ID */ + ret = pk_client_allocate_transaction_id (client, error); + if (!ret) +- return FALSE; ++ goto out; + + /* we use the cached objects support */ + pk_obj_list_set_copy (client->priv->cached_data, (PkObjListCopyFunc) pk_transaction_obj_copy); +@@ -3775,13 +3599,23 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + if (client->priv->proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction"); +- return FALSE; ++ ret = FALSE; ++ goto out; + } +- ret = dbus_g_proxy_call (client->priv->proxy, "GetOldTransactions", error, ++ ++ /* do the method */ ++ ret = dbus_g_proxy_call (client->priv->proxy, "GetOldTransactions", &error_local, + G_TYPE_UINT, number, + G_TYPE_INVALID, G_TYPE_INVALID); +- pk_client_error_fixup (error); +- if (ret && !client->priv->is_finished) { ++ if (!ret) { ++ if (error != NULL) ++ *error = pk_client_error_fixup (error_local); ++ g_error_free (error_local); ++ goto out; ++ } ++ ++ /* is not already finished */ ++ if (!client->priv->is_finished) { + /* allow clients to respond in the status changed callback */ + pk_client_change_status (client, PK_STATUS_ENUM_WAIT); + +@@ -3789,6 +3623,7 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + if (client->priv->synchronous) + g_main_loop_run (client->priv->loop); + } ++out: + return ret; + } + +@@ -3806,7 +3641,7 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error) + gboolean + pk_client_requeue (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + PkClientPrivate *priv = PK_CLIENT_GET_PRIVATE (client); + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); +@@ -3816,14 +3651,14 @@ pk_client_requeue (PkClient *client, GError **error) + if (priv->role == PK_ROLE_ENUM_UNKNOWN) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_ROLE_UNKNOWN, "role unknown for reque"); +- return FALSE; ++ goto out; + } + +- /* are we still running? */ ++ /* is not already finished */ + if (!client->priv->is_finished) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "not finished, so cannot requeue"); +- return FALSE; ++ goto out; + } + + /* clear enough data of the client to allow us to requeue */ +@@ -3886,9 +3721,9 @@ pk_client_requeue (PkClient *client, GError **error) + else { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_ROLE_UNKNOWN, "role unknown for reque"); +- return FALSE; ++ goto out; + } +- pk_client_error_fixup (error); ++out: + return ret; + } + +@@ -3908,6 +3743,7 @@ gboolean + pk_client_set_tid (PkClient *client, const gchar *tid, GError **error) + { + DBusGProxy *proxy = NULL; ++ gboolean ret = FALSE; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -3915,7 +3751,7 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error) + if (client->priv->tid != NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_ALREADY_TID, "cannot set the tid on an already set client"); +- return FALSE; ++ goto out; + } + + /* get a connection */ +@@ -3924,7 +3760,7 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error) + if (proxy == NULL) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_ALREADY_TID, "Cannot connect to PackageKit tid %s", tid); +- return FALSE; ++ goto out; + } + + /* don't timeout, as dbus-glib sets the timeout ~25 seconds */ +@@ -4016,8 +3852,9 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error) + dbus_g_proxy_connect_signal (proxy, "Destroy", + G_CALLBACK (pk_client_destroy_cb), client, NULL); + client->priv->proxy = proxy; +- +- return TRUE; ++ ret = TRUE; ++out: ++ return ret; + } + + /** +@@ -4425,7 +4262,7 @@ pk_client_disconnect_proxy (PkClient *client) + gboolean + pk_client_reset (PkClient *client, GError **error) + { +- gboolean ret; ++ gboolean ret = FALSE; + + g_return_val_if_fail (PK_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -4436,7 +4273,7 @@ pk_client_reset (PkClient *client, GError **error) + if (client->priv->is_finishing && client->priv->synchronous) { + if (error != NULL) + *error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "unable to reset synchronous client in finished handler"); +- return FALSE; ++ goto out; + } + + if (client->priv->tid != NULL && !client->priv->is_finished) { +@@ -4444,7 +4281,7 @@ pk_client_reset (PkClient *client, GError **error) + /* we try to cancel the running tranaction */ + ret = pk_client_cancel (client, error); + if (!ret) +- return FALSE; ++ goto out; + } + + /* stop the timeout timer if running */ +@@ -4489,7 +4326,9 @@ pk_client_reset (PkClient *client, GError **error) + + /* TODO: make clean */ + pk_obj_list_clear (client->priv->cached_data); +- return TRUE; ++ ret = TRUE; ++out: ++ return ret; + } + + /** +diff --git a/lib/packagekit-qt/src/client.cpp b/lib/packagekit-qt/src/client.cpp +index d231d0e..ffcd200 100644 +--- a/lib/packagekit-qt/src/client.cpp ++++ b/lib/packagekit-qt/src/client.cpp +@@ -153,10 +153,12 @@ void Client::setLocale(const QString& locale) + + void Client::setProxy(const QString& http_proxy, const QString& ftp_proxy) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_NETWORK_PROXY_CONFIGURE)) { + emit authError(AUTH_SYSTEM_NETWORK_PROXY_CONFIGURE); + return; + } ++#endif + + d->daemon->SetProxy(http_proxy, ftp_proxy); + } +@@ -180,10 +182,12 @@ Client::DaemonError Client::getLastError () + + Transaction* Client::acceptEula(EulaInfo info) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_PACKAGE_EULA_ACCEPT)) { + emit authError(AUTH_PACKAGE_EULA_ACCEPT); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -376,10 +380,12 @@ Transaction* Client::getDistroUpgrades() + Transaction* Client::installFiles(const QStringList& files, bool trusted) + { + QString polkitAction = trusted ? AUTH_PACKAGE_INSTALL : AUTH_PACKAGE_INSTALL_UNTRUSTED; ++#if 0 + if(!PolkitClient::instance()->getAuth(polkitAction)) { + emit authError(polkitAction); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -399,10 +405,12 @@ Transaction* Client::installFile(const QString& file, bool trusted) + + Transaction* Client::installPackages(const QList& packages) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_PACKAGE_INSTALL)) { + emit authError(AUTH_PACKAGE_INSTALL); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -422,10 +430,12 @@ Transaction* Client::installPackage(Package* p) + + Transaction* Client::installSignature(SignatureType type, const QString& key_id, Package* p) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_TRUST_SIGNING_KEY)) { + emit authError(AUTH_SYSTEM_TRUST_SIGNING_KEY); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -440,10 +450,12 @@ Transaction* Client::installSignature(SignatureType type, const QString& key_id, + + Transaction* Client::refreshCache(bool force) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_SOURCES_REFRESH)) { + emit authError(AUTH_SYSTEM_SOURCES_REFRESH); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -458,10 +470,12 @@ Transaction* Client::refreshCache(bool force) + + Transaction* Client::removePackages(const QList& packages, bool allow_deps, bool autoremove) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_PACKAGE_REMOVE)) { + emit authError(AUTH_PACKAGE_REMOVE); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -481,10 +495,12 @@ Transaction* Client::removePackage(Package* p, bool allow_deps, bool autoremove) + + Transaction* Client::repoEnable(const QString& repo_id, bool enable) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_SOURCES_CONFIGURE)) { + emit authError(AUTH_SYSTEM_SOURCES_CONFIGURE); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -499,10 +515,12 @@ Transaction* Client::repoEnable(const QString& repo_id, bool enable) + + Transaction* Client::repoSetData(const QString& repo_id, const QString& parameter, const QString& value) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_SOURCES_CONFIGURE)) { + emit authError(AUTH_SYSTEM_SOURCES_CONFIGURE); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -535,10 +553,12 @@ Transaction* Client::resolve(const QString& packageName, Filters filters) + + Transaction* Client::rollback(Transaction* oldtrans) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_ROLLBACK)) { + emit authError(AUTH_SYSTEM_ROLLBACK); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -627,10 +647,12 @@ Package* Client::searchFromDesktopFile(const QString& path) + + Transaction* Client::updatePackages(const QList& packages) + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_UPDATE)) { + emit authError(AUTH_SYSTEM_UPDATE); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +@@ -650,10 +672,12 @@ Transaction* Client::updatePackage(Package* package) + + Transaction* Client::updateSystem() + { ++#if 0 + if(!PolkitClient::instance()->getAuth(AUTH_SYSTEM_UPDATE)) { + emit authError(AUTH_SYSTEM_UPDATE); + return NULL; + } ++#endif + + Transaction* t = d->createNewTransaction(); + if (!t) { +diff --git a/lib/packagekit-qt/src/polkitclient.cpp b/lib/packagekit-qt/src/polkitclient.cpp +index 7998752..5623c31 100644 +--- a/lib/packagekit-qt/src/polkitclient.cpp ++++ b/lib/packagekit-qt/src/polkitclient.cpp +@@ -19,10 +19,6 @@ + */ + #include "config.h" + +-#ifdef USE_SECURITY_POLKIT +- #include +-#endif +- + #include "polkitclient.h" + + using namespace PackageKit; +@@ -38,6 +34,8 @@ PolkitClient* PolkitClient::instance() + PolkitClient::PolkitClient(QObject *parent) : QObject(parent) { + } + ++#if 0 ++ + #ifdef USE_SECURITY_POLKIT + bool PolkitClient::getAuth(const QString &action) { + DBusError e; +@@ -55,10 +53,11 @@ bool PolkitClient::getAuth(const QString &action) { + } + #else + bool PolkitClient::getAuth(const QString &action) { +- qDebug() << "Not configured with PolicyKit support"; ++ qDebug() << "Not configured with old PolicyKit support"; + return false; + } + #endif ++#endif + + #include "polkitclient.moc" + +diff --git a/lib/packagekit-qt/src/polkitclient.h b/lib/packagekit-qt/src/polkitclient.h +index 2b8bd91..4788951 100644 +--- a/lib/packagekit-qt/src/polkitclient.h ++++ b/lib/packagekit-qt/src/polkitclient.h +@@ -31,7 +31,9 @@ class PolkitClient : QObject{ + + public: + static PolkitClient* instance(); ++#if 0 + bool getAuth(const QString& action); ++#endif + private: + static PolkitClient* m_instance; + PolkitClient(QObject *parent = 0); +diff --git a/lib/packagekit-qt/src/transaction.cpp b/lib/packagekit-qt/src/transaction.cpp +index 7948441..9414e84 100644 +--- a/lib/packagekit-qt/src/transaction.cpp ++++ b/lib/packagekit-qt/src/transaction.cpp +@@ -102,13 +102,14 @@ bool Transaction::callerActive() + void Transaction::cancel() + { + if (!d->p->Cancel().isValid ()) { ++#if 0 + // Cancel failed, maybe it's not our transaction and we need authorization + if(!PolkitClient::instance()->getAuth(AUTH_CANCEL_FOREIGN)) { + // FIXME : should warn somehow here + qDebug () << "Authorization to cancel foreign failed"; + return; + } +- ++#endif + d->p->Cancel(); + } + } +diff --git a/policy/Makefile.am b/policy/Makefile.am +index 9fcdc91..9f0ab3c 100644 +--- a/policy/Makefile.am ++++ b/policy/Makefile.am +@@ -1,7 +1,7 @@ + + NULL = + +-polkit_policydir = $(datadir)/PolicyKit/policy ++polkit_policydir = $(datadir)/polkit-1/actions + dist_polkit_policy_DATA = \ + org.freedesktop.packagekit.policy \ + $(NULL) +@@ -10,11 +10,6 @@ dist_polkit_policy_DATA = \ + # http://bugzilla.gnome.org/show_bug.cgi?id=462312 + @INTLTOOL_POLICY_RULE@ + +-if SECURITY_TYPE_POLKIT +-check: +- $(POLKIT_POLICY_FILE_VALIDATE) $(top_srcdir)/policy/$(dist_polkit_policy_DATA) +-endif +- + EXTRA_DIST = org.freedesktop.packagekit.policy.in + DISTCLEANFILES = org.freedesktop.packagekit.policy + +diff --git a/policy/org.freedesktop.packagekit.policy.in b/policy/org.freedesktop.packagekit.policy.in +index b12b8ab..98bf5f3 100644 +--- a/policy/org.freedesktop.packagekit.policy.in ++++ b/policy/org.freedesktop.packagekit.policy.in +@@ -6,7 +6,7 @@ + + + + The PackageKit Project +@@ -18,8 +18,9 @@ + <_message>Authentication is required to cancel a task that was not started by yourself + pk-package-delete + ++ no + no +- auth_admin_keep_always ++ auth_admin_keep + + + +@@ -28,8 +29,9 @@ + <_message>Authentication is required to install a signed package + pk-package-add + ++ no + no +- auth_admin_keep_always ++ yes + + + +@@ -38,6 +40,7 @@ + <_message>Authentication is required to install an untrusted package + pk-package-add + ++ no + no + auth_admin + +@@ -48,6 +51,7 @@ + <_message>Authentication is required to consider a key used for signing packages as trusted + pk-package-add + ++ no + no + auth_admin + +@@ -58,6 +62,7 @@ + <_message>Authentication is required to accept a EULA + pk-package-add + ++ no + no + yes + +@@ -68,8 +73,9 @@ + <_message>Authentication is required to remove packages + pk-package-delete + ++ no + no +- auth_admin_keep_always ++ auth_admin_keep + + + +@@ -78,8 +84,9 @@ + <_message>Authentication is required to update packages + pk-package-update + ++ no + no +- auth_admin_keep_always ++ yes + + + +@@ -88,8 +95,9 @@ + <_message>Authentication is required to rollback a transaction + pk-rollback + ++ no + no +- auth_admin_keep_always ++ auth_admin + + + +@@ -98,8 +106,9 @@ + <_message>Authentication is required to change software source parameters + pk-package-info + ++ no + no +- auth_admin_keep_always ++ auth_admin_keep + + + +@@ -108,6 +117,7 @@ + <_message>Authentication is required to refresh the system sources + pk-refresh-cache + ++ no + no + yes + +@@ -118,6 +128,7 @@ + <_message>Authentication is required to set the network proxy used for downloading packages + applications-internet + ++ no + no + yes + +diff --git a/src/Makefile.am b/src/Makefile.am +index 5969300..8f3a310 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -109,14 +109,6 @@ shared_SOURCES += \ + pk-network-stack-connman.c + endif + +-if SECURITY_TYPE_POLKIT +-shared_SOURCES += pk-security-polkit.c +-endif +- +-if SECURITY_TYPE_DUMMY +-shared_SOURCES += pk-security-dummy.c +-endif +- + sbin_PROGRAMS = \ + packagekitd \ + $(NULL) +@@ -170,7 +162,7 @@ org.freedesktop.PackageKit.h: org.freedesktop.PackageKit.xml + $(LIBTOOL) --mode=execute dbus-binding-tool \ + --prefix=pk_engine \ + --mode=glib-server \ +- --output=org.freedesktop.PackageKit.h \ ++ --output=org.freedesktop.PackageKit.h \ + $(srcdir)/org.freedesktop.PackageKit.xml + + org.freedesktop.PackageKit.Transaction.h: org.freedesktop.PackageKit.Transaction.xml +@@ -225,8 +217,6 @@ install-data-hook: + + EXTRA_DIST = \ + pk-marshal.list \ +- pk-security-polkit.c \ +- pk-security-dummy.c \ + org.freedesktop.PackageKit.xml \ + org.freedesktop.PackageKit.Transaction.xml \ + org.freedesktop.PackageKit.Backend.xml \ +diff --git a/src/pk-engine.c b/src/pk-engine.c +index 88c3e4b..0d88e46 100644 +--- a/src/pk-engine.c ++++ b/src/pk-engine.c +@@ -1,6 +1,6 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * +- * Copyright (C) 2007-2008 Richard Hughes ++ * Copyright (C) 2007-2009 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * +@@ -38,6 +38,9 @@ + #include + #include + #include ++#ifdef USE_SECURITY_POLKIT ++#include ++#endif + + #include "egg-debug.h" + #include "egg-string.h" +@@ -55,7 +58,6 @@ + #include "pk-marshal.h" + #include "pk-notify.h" + #include "pk-file-monitor.h" +-#include "pk-security.h" + #include "pk-conf.h" + + static void pk_engine_finalize (GObject *object); +@@ -95,7 +97,6 @@ struct PkEnginePrivate + PkBackend *backend; + PkInhibit *inhibit; + PkNetwork *network; +- PkSecurity *security; + PkNotify *notify; + PkConf *conf; + PkFileMonitor *file_monitor_conf; +@@ -106,6 +107,11 @@ struct PkEnginePrivate + gchar *mime_types; + guint signal_state_priority_timeout; + guint signal_state_normal_timeout; ++#ifdef USE_SECURITY_POLKIT ++ PolkitAuthority *authority; ++#endif ++ gchar *proxy_http; ++ gchar *proxy_ftp; + }; + + enum { +@@ -577,61 +583,103 @@ pk_engine_suggest_daemon_quit (PkEngine *engine, GError **error) + return TRUE; + } + ++#ifdef USE_SECURITY_POLKIT + /** +- * pk_engine_set_proxy: ++ * pk_engine_action_obtain_authorization: + **/ +-void +-pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *proxy_ftp, DBusGMethodInvocation *context) ++static void ++pk_engine_action_obtain_authorization_finished_cb (GObject *source_object, GAsyncResult *res, PkEngine *engine) + { ++ PolkitAuthorizationResult *result; ++ GError *error = NULL; + gboolean ret; +- GError *error; +- gchar *sender = NULL; +- gchar *error_detail = NULL; +- PkSecurityCaller *caller; +- +- g_return_if_fail (PK_IS_ENGINE (engine)); + +- egg_debug ("SetProxy method called: %s, %s", proxy_http, proxy_ftp); ++ /* finish the call */ ++ result = polkit_authority_check_authorization_finish (engine->priv->authority, res, &error); + +- /* check if the action is allowed from this client - if not, set an error */ +- sender = dbus_g_method_get_sender (context); ++ /* failed */ ++ if (result == NULL) { ++ egg_warning ("failed to check for auth: %s", error->message); ++ g_error_free (error); ++ goto out; ++ } + +- /* get caller */ +- caller = pk_security_caller_new_from_sender (engine->priv->security, sender); +- if (caller == NULL) { +- error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_REFUSED_BY_POLICY, +- "caller %s not found", sender); +- dbus_g_method_return_error (context, error); ++ /* did not auth */ ++ if (!polkit_authorization_result_get_is_authorized (result)) { ++ egg_warning ("failed to obtain auth"); + goto out; + } + +- /* use security model to get auth */ +- ret = pk_security_action_is_allowed (engine->priv->security, caller, FALSE, PK_ROLE_ENUM_SET_PROXY_PRIVATE, &error_detail); ++ /* try to set the new proxy */ ++ ret = pk_backend_set_proxy (engine->priv->backend, engine->priv->proxy_http, engine->priv->proxy_ftp); + if (!ret) { +- error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_REFUSED_BY_POLICY, "%s", error_detail); +- dbus_g_method_return_error (context, error); ++ egg_warning ("setting the proxy failed"); + goto out; + } ++out: ++ if (result != NULL) ++ g_object_unref (result); ++ return; ++} ++#endif ++ ++/** ++ * pk_engine_set_proxy: ++ **/ ++void ++pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *proxy_ftp, DBusGMethodInvocation *context) ++{ ++#ifdef USE_SECURITY_POLKIT ++ gchar *sender = NULL; ++ PolkitSubject *subject; ++#else ++ gboolean ret; ++ GError *error = NULL; ++#endif ++ g_return_if_fail (PK_IS_ENGINE (engine)); ++ ++ egg_debug ("SetProxy method called: %s, %s", proxy_http, proxy_ftp); ++ ++ /* save these so we can set them after the auth success */ ++ egg_debug ("potentially changing http proxy from %s to %s", engine->priv->proxy_http, proxy_http); ++ egg_debug ("potentially changing ftp proxy from %s to %s", engine->priv->proxy_ftp, proxy_ftp); ++ g_free (engine->priv->proxy_http); ++ g_free (engine->priv->proxy_ftp); ++ engine->priv->proxy_http = g_strdup (proxy_http); ++ engine->priv->proxy_ftp = g_strdup (proxy_ftp); ++ ++#ifdef USE_SECURITY_POLKIT ++ /* check subject */ ++ sender = dbus_g_method_get_sender (context); ++ subject = polkit_system_bus_name_new (sender); ++ polkit_authority_check_authorization (engine->priv->authority, subject, ++ "org.freedesktop.packagekit.system-network-proxy-configure", ++ NULL, ++ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, ++ NULL, ++ (GAsyncReadyCallback) pk_engine_action_obtain_authorization_finished_cb, ++ engine); ++#else ++ egg_warning ("*** THERE IS NO SECURITY MODEL BEING USED!!! ***"); + + /* try to set the new proxy */ + ret = pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp); + if (!ret) { + error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_CANNOT_SET_PROXY, "%s", "setting the proxy failed"); + dbus_g_method_return_error (context, error); +- goto out; ++ return; + } +- ++#endif + /* all okay */ + dbus_g_method_return (context); + + /* reset the timer */ + pk_engine_reset_timer (engine); + +-out: +- if (caller != NULL) +- pk_security_caller_unref (caller); ++#ifdef USE_SECURITY_POLKIT ++ g_object_unref (subject); + g_free (sender); +- g_free (error_detail); ++#endif + } + + /** +@@ -793,8 +841,6 @@ pk_engine_init (PkEngine *engine) + DBusGConnection *connection; + gboolean ret; + gchar *filename; +- gchar *proxy_http; +- gchar *proxy_ftp; + + engine->priv = PK_ENGINE_GET_PRIVATE (engine); + engine->priv->notify_clients_of_upgrade = FALSE; +@@ -820,9 +866,6 @@ pk_engine_init (PkEngine *engine) + if (!ret) + egg_error ("could not lock backend, you need to restart the daemon"); + +- /* we dont need this, just don't keep creating and destroying it */ +- engine->priv->security = pk_security_new (); +- + /* proxy the network state */ + engine->priv->network = pk_network_new (); + g_signal_connect (engine->priv->network, "state-changed", +@@ -863,18 +906,21 @@ pk_engine_init (PkEngine *engine) + G_CALLBACK (pk_engine_conf_file_changed_cb), engine); + g_free (filename); + ++#ifdef USE_SECURITY_POLKIT ++ /* protect the session SetProxy with a PolicyKit action */ ++ engine->priv->authority = polkit_authority_get (); ++#endif ++ + /* monitor the binary file for changes */ + engine->priv->file_monitor_binary = pk_file_monitor_new (); + pk_file_monitor_set_file (engine->priv->file_monitor_binary, SBINDIR "/packagekitd"); + g_signal_connect (engine->priv->file_monitor_binary, "file-changed", + G_CALLBACK (pk_engine_binary_file_changed_cb), engine); + +- /* set the proxy */ +- proxy_http = pk_conf_get_string (engine->priv->conf, "ProxyHTTP"); +- proxy_ftp = pk_conf_get_string (engine->priv->conf, "ProxyFTP"); +- pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp); +- g_free (proxy_http); +- g_free (proxy_ftp); ++ /* set the default proxy */ ++ engine->priv->proxy_http = pk_conf_get_string (engine->priv->conf, "ProxyHTTP"); ++ engine->priv->proxy_ftp = pk_conf_get_string (engine->priv->conf, "ProxyFTP"); ++ pk_backend_set_proxy (engine->priv->backend, engine->priv->proxy_http, engine->priv->proxy_ftp); + + engine->priv->transaction_list = pk_transaction_list_new (); + g_signal_connect (engine->priv->transaction_list, "changed", +@@ -928,12 +974,16 @@ pk_engine_finalize (GObject *object) + g_object_unref (engine->priv->transaction_list); + g_object_unref (engine->priv->transaction_db); + g_object_unref (engine->priv->network); +- g_object_unref (engine->priv->security); ++#ifdef USE_SECURITY_POLKIT ++ g_object_unref (engine->priv->authority); ++#endif + g_object_unref (engine->priv->notify); + g_object_unref (engine->priv->backend); + g_object_unref (engine->priv->cache); + g_object_unref (engine->priv->conf); + g_free (engine->priv->mime_types); ++ g_free (engine->priv->proxy_http); ++ g_free (engine->priv->proxy_ftp); + + G_OBJECT_CLASS (pk_engine_parent_class)->finalize (object); + } +diff --git a/src/pk-post-trans.c b/src/pk-post-trans.c +index 199d258..4575c53 100644 +--- a/src/pk-post-trans.c ++++ b/src/pk-post-trans.c +@@ -32,11 +32,6 @@ + #include + #include + +-#ifdef USE_SECURITY_POLKIT +- #include +- #include +-#endif +- + #include "egg-debug.h" + + #include "pk-post-trans.h" +@@ -542,6 +537,32 @@ pk_post_trans_update_files_check_running_cb (PkBackend *backend, const gchar *pa + pk_package_id_free (id); + } + ++#ifdef USE_SECURITY_POLKIT ++/** ++ * dkp_post_trans_get_cmdline: ++ **/ ++static gchar * ++dkp_post_trans_get_cmdline (guint pid) ++{ ++ gboolean ret; ++ gchar *filename = NULL; ++ gchar *cmdline = NULL; ++ GError *error = NULL; ++ ++ /* get command line from proc */ ++ filename = g_strdup_printf ("/proc/%i/cmdline", pid); ++ ret = g_file_get_contents (filename, &cmdline, NULL, &error); ++ if (!ret) { ++ egg_debug ("failed to get cmdline: %s", error->message); ++ g_error_free (error); ++ goto out; ++ } ++out: ++ g_free (filename); ++ return cmdline; ++} ++#endif ++ + /** + * pk_post_trans_update_process_list: + **/ +@@ -556,8 +577,7 @@ pk_post_trans_update_process_list (PkPostTrans *post) + gboolean ret; + guint uid; + pid_t pid; +- gint retval; +- gchar exec[128]; ++ gchar *exec; + + uid = getuid (); + dir = g_dir_open ("/proc", 0, NULL); +@@ -582,12 +602,12 @@ pk_post_trans_update_process_list (PkPostTrans *post) + /* get the exec for the pid */ + pid = atoi (name); + #ifdef USE_SECURITY_POLKIT +- retval = polkit_sysdeps_get_exe_for_pid (pid, exec, 128); ++ exec = dkp_post_trans_get_cmdline (pid); ++ if (exec == NULL) ++ goto out; + #else +- retval = -1; ++ goto out; + #endif +- if (retval <= 0) +- goto out; + + /* can be /usr/libexec/notification-daemon.#prelink#.9sOhao */ + offset = g_strrstr (exec, ".#prelink#."); +diff --git a/src/pk-security-dummy.c b/src/pk-security-dummy.c +deleted file mode 100644 +index 3e3713a..0000000 +--- a/src/pk-security-dummy.c ++++ /dev/null +@@ -1,155 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Richard Hughes +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * 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 +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +- +-#include "egg-debug.h" +-#include "pk-security.h" +- +-#define PK_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_SECURITY, PkSecurityPrivate)) +- +-struct PkSecurityPrivate +-{ +- gpointer data; +-}; +- +-typedef gpointer PkSecurityCaller_; +- +-G_DEFINE_TYPE (PkSecurity, pk_security, G_TYPE_OBJECT) +- +-/** +- * pk_security_caller_new_from_sender: +- **/ +-PkSecurityCaller * +-pk_security_caller_new_from_sender (PkSecurity *security, const gchar *sender) +-{ +- g_return_val_if_fail (PK_IS_SECURITY (security), NULL); +- return GUINT_TO_POINTER (1); +-} +- +-/** +- * pk_security_caller_unref: +- **/ +-void +-pk_security_caller_unref (PkSecurityCaller *caller) +-{ +- return; +-} +- +-/** +- * pk_security_get_uid: +- **/ +-guint +-pk_security_get_uid (PkSecurity *security, PkSecurityCaller *caller) +-{ +- g_return_val_if_fail (PK_IS_SECURITY (security), -1); +- return -1; +-} +- +-/** +- * pk_security_get_cmdline: +- **/ +-gchar * +-pk_security_get_cmdline (PkSecurity *security, PkSecurityCaller *caller) +-{ +- g_return_val_if_fail (PK_IS_SECURITY (security), NULL); +- return NULL; +-} +- +-/** +- * pk_security_action_is_allowed: +- **/ +-gboolean +-pk_security_action_is_allowed (PkSecurity *security, PkSecurityCaller *caller, gboolean trusted, PkRoleEnum role, gchar **error_detail) +-{ +- g_return_val_if_fail (PK_IS_SECURITY (security), FALSE); +- return TRUE; +-} +- +-/** +- * pk_security_finalize: +- **/ +-static void +-pk_security_finalize (GObject *object) +-{ +- PkSecurity *security; +- g_return_if_fail (PK_IS_SECURITY (object)); +- security = PK_SECURITY (object); +- G_OBJECT_CLASS (pk_security_parent_class)->finalize (object); +-} +- +-/** +- * pk_security_class_init: +- **/ +-static void +-pk_security_class_init (PkSecurityClass *klass) +-{ +- GObjectClass *object_class = G_OBJECT_CLASS (klass); +- object_class->finalize = pk_security_finalize; +- g_type_class_add_private (klass, sizeof (PkSecurityPrivate)); +-} +- +-/** +- * pk_security_init: +- * +- * initializes the security class. NOTE: We expect security objects +- * to *NOT* be removed or added during the session. +- * We only control the first security object if there are more than one. +- **/ +-static void +-pk_security_init (PkSecurity *security) +-{ +- egg_debug ("Using dummy security framework"); +- egg_warning ("*** THERE IS NO SECURITY MODEL BEING USED!!! ***"); +-} +- +-/** +- * pk_security_new: +- * Return value: A new security class instance. +- **/ +-PkSecurity * +-pk_security_new (void) +-{ +- PkSecurity *security; +- security = g_object_new (PK_TYPE_SECURITY, NULL); +- return PK_SECURITY (security); +-} +- +-#ifdef EGG_TEST +-#include "egg-test.h" +- +-void +-pk_security_test (EggTest *test) +-{ +- return; +-} +-#endif +- +diff --git a/src/pk-security-polkit.c b/src/pk-security-polkit.c +deleted file mode 100644 +index 2cac522..0000000 +--- a/src/pk-security-polkit.c ++++ /dev/null +@@ -1,424 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007-2008 Richard Hughes +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * 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 +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include +-#endif +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include "egg-debug.h" +-#include "egg-string.h" +- +-#include "pk-security.h" +-#include "pk-syslog.h" +- +-#define PK_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_SECURITY, PkSecurityPrivate)) +- +-struct PkSecurityPrivate +-{ +- PolKitContext *pk_context; +- DBusConnection *connection; +- PkSyslog *syslog; +-}; +- +-typedef PolKitCaller PkSecurityCaller_; +- +-G_DEFINE_TYPE (PkSecurity, pk_security, G_TYPE_OBJECT) +-static gpointer pk_security_object = NULL; +- +-/** +- * pk_security_caller_new_from_sender: +- **/ +-PkSecurityCaller * +-pk_security_caller_new_from_sender (PkSecurity *security, const gchar *sender) +-{ +- PolKitCaller *caller; +- DBusError dbus_error; +- +- g_return_val_if_fail (PK_IS_SECURITY (security), NULL); +- g_return_val_if_fail (sender != NULL, NULL); +- +- /* get the PolKitCaller information */ +- dbus_error_init (&dbus_error); +- caller = polkit_caller_new_from_dbus_name (security->priv->connection, sender, &dbus_error); +- if (dbus_error_is_set (&dbus_error)) { +- egg_debug ("failed to get caller %s: %s", dbus_error.name, dbus_error.message); +- dbus_error_free (&dbus_error); +- } +- +- return (PkSecurityCaller*) caller; +-} +- +-/** +- * pk_security_caller_unref: +- **/ +-void +-pk_security_caller_unref (PkSecurityCaller *caller) +-{ +- if (caller != NULL) +- polkit_caller_unref ((PolKitCaller *) caller); +-} +- +-/** +- * pk_security_get_uid: +- **/ +-guint +-pk_security_get_uid (PkSecurity *security, PkSecurityCaller *caller) +-{ +- polkit_bool_t retval; +- guint uid; +- +- g_return_val_if_fail (PK_IS_SECURITY (security), -1); +- g_return_val_if_fail (caller != NULL, -1); +- +- /* get uid */ +- retval = polkit_caller_get_uid ((PolKitCaller *) caller, &uid); +- if (!retval) { +- egg_warning ("failed to get UID"); +- uid = PK_SECURITY_UID_INVALID; +- } +- +- return uid; +-} +- +-/** +- * pk_security_get_cmdline: +- **/ +-gchar * +-pk_security_get_cmdline (PkSecurity *security, PkSecurityCaller *caller) +-{ +- gboolean ret; +- gchar *filename = NULL; +- gchar *cmdline = NULL; +- GError *error = NULL; +- polkit_bool_t retval; +- pid_t pid; +- +- g_return_val_if_fail (PK_IS_SECURITY (security), NULL); +- g_return_val_if_fail (caller != NULL, NULL); +- +- /* get pid */ +- retval = polkit_caller_get_pid ((PolKitCaller *) caller, &pid); +- if (!retval) { +- egg_warning ("failed to get PID"); +- goto out; +- } +- +- /* get command line from proc */ +- filename = g_strdup_printf ("/proc/%i/cmdline", pid); +- ret = g_file_get_contents (filename, &cmdline, NULL, &error); +- if (!ret) { +- egg_warning ("failed to get cmdline: %s", error->message); +- g_error_free (error); +- } +-out: +- g_free (filename); +- return cmdline; +-} +- +-/** +- * pk_security_role_to_action: +- **/ +-static const gchar * +-pk_security_role_to_action (PkSecurity *security, gboolean trusted, PkRoleEnum role) +-{ +- const gchar *policy = NULL; +- +- g_return_val_if_fail (PK_IS_SECURITY (security), NULL); +- +- if (role == PK_ROLE_ENUM_UPDATE_PACKAGES || +- role == PK_ROLE_ENUM_UPDATE_SYSTEM) { +- policy = "org.freedesktop.packagekit.system-update"; +- } else if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE) { +- policy = "org.freedesktop.packagekit.system-trust-signing-key"; +- } else if (role == PK_ROLE_ENUM_ROLLBACK) { +- policy = "org.freedesktop.packagekit.system-rollback"; +- } else if (role == PK_ROLE_ENUM_REPO_ENABLE || +- role == PK_ROLE_ENUM_REPO_SET_DATA) { +- policy = "org.freedesktop.packagekit.system-sources-configure"; +- } else if (role == PK_ROLE_ENUM_REFRESH_CACHE) { +- policy = "org.freedesktop.packagekit.system-sources-refresh"; +- } else if (role == PK_ROLE_ENUM_SET_PROXY_PRIVATE) { +- policy = "org.freedesktop.packagekit.system-network-proxy-configure"; +- } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) { +- policy = "org.freedesktop.packagekit.package-remove"; +- } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) { +- policy = "org.freedesktop.packagekit.package-install"; +- } else if (role == PK_ROLE_ENUM_INSTALL_FILES && trusted) { +- policy = "org.freedesktop.packagekit.package-install"; +- } else if (role == PK_ROLE_ENUM_INSTALL_FILES && !trusted) { +- policy = "org.freedesktop.packagekit.package-install-untrusted"; +- } else if (role == PK_ROLE_ENUM_ACCEPT_EULA) { +- policy = "org.freedesktop.packagekit.package-eula-accept"; +- } else if (role == PK_ROLE_ENUM_CANCEL) { +- policy = "org.freedesktop.packagekit.cancel-foreign"; +- } +- return policy; +-} +- +-/** +- * pk_security_action_is_allowed: +- **/ +-gboolean +-pk_security_action_is_allowed (PkSecurity *security, PkSecurityCaller *caller, gboolean trusted, PkRoleEnum role, gchar **error_detail) +-{ +- gboolean ret = FALSE; +- PolKitResult result; +- const gchar *policy; +- PolKitAction *action; +- guint uid; +- gchar *cmdline; +- +- g_return_val_if_fail (PK_IS_SECURITY (security), FALSE); +- g_return_val_if_fail (caller != NULL, FALSE); +- +- /* map the roles to policykit rules */ +- policy = pk_security_role_to_action (security, trusted, role); +- if (policy == NULL) { +- egg_warning ("policykit type required for '%s'", pk_role_enum_to_text (role)); +- return FALSE; +- } +- +- /* set action */ +- action = polkit_action_new (); +- if (action == NULL) { +- egg_warning ("error: polkit_action_new failed"); +- goto out; +- } +- polkit_action_set_action_id (action, policy); +- +- /* set caller */ +- result = polkit_context_is_caller_authorized (security->priv->pk_context, action, (PolKitCaller *) caller, TRUE, NULL); +- egg_debug ("PolicyKit result = '%s'", polkit_result_to_string_representation (result)); +- if (result != POLKIT_RESULT_YES) { +- if (error_detail != NULL) +- *error_detail = g_strdup_printf ("%s %s", policy, polkit_result_to_string_representation (result)); +- goto out; +- } +- +- /* yippee */ +- ret = TRUE; +- +-out: +- /* log result */ +- uid = pk_security_get_uid (security, caller); +- cmdline = pk_security_get_cmdline (security, caller); +- if (ret) +- pk_syslog_add (security->priv->syslog, PK_SYSLOG_TYPE_AUTH, "uid %i obtained %s auth (trusted:%i)", uid, policy, trusted); +- else +- pk_syslog_add (security->priv->syslog, PK_SYSLOG_TYPE_AUTH, "uid %i failed to obtain %s auth (trusted:%i)", uid, policy, trusted); +- g_free (cmdline); +- +- if (action != NULL) +- polkit_action_unref (action); +- return ret; +-} +- +-/** +- * pk_security_finalize: +- **/ +-static void +-pk_security_finalize (GObject *object) +-{ +- PkSecurity *security; +- g_return_if_fail (PK_IS_SECURITY (object)); +- security = PK_SECURITY (object); +- +- /* unref PolicyKit */ +- polkit_context_unref (security->priv->pk_context); +- g_object_unref (security->priv->syslog); +- +- G_OBJECT_CLASS (pk_security_parent_class)->finalize (object); +-} +- +-/** +- * pk_security_class_init: +- **/ +-static void +-pk_security_class_init (PkSecurityClass *klass) +-{ +- GObjectClass *object_class = G_OBJECT_CLASS (klass); +- object_class->finalize = pk_security_finalize; +- g_type_class_add_private (klass, sizeof (PkSecurityPrivate)); +-} +- +-/** +- * pk_security_io_watch_have_data: +- **/ +-static gboolean +-pk_security_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; +-} +- +-/** +- * pk_security_io_add_watch: +- **/ +-static int +-pk_security_io_add_watch (PolKitContext *pk_context, int fd) +-{ +- guint id = 0; +- GIOChannel *channel; +- channel = g_io_channel_unix_new (fd); +- if (channel == NULL) +- return id; +- id = g_io_add_watch (channel, G_IO_IN, pk_security_io_watch_have_data, pk_context); +- if (id == 0) { +- g_io_channel_unref (channel); +- return id; +- } +- g_io_channel_unref (channel); +- return id; +-} +- +-/** +- * pk_security_io_remove_watch: +- **/ +-static void +-pk_security_io_remove_watch (PolKitContext *pk_context, int watch_id) +-{ +- g_source_remove (watch_id); +-} +- +-/** +- * pk_security_init: +- * +- * initializes the security class. NOTE: We expect security objects +- * to *NOT* be removed or added during the session. +- * We only control the first security object if there are more than one. +- **/ +-static void +-pk_security_init (PkSecurity *security) +-{ +- PolKitError *pk_error; +- polkit_bool_t retval; +- DBusError dbus_error; +- +- security->priv = PK_SECURITY_GET_PRIVATE (security); +- +- egg_debug ("Using PolicyKit security framework"); +- +- /* use syslog */ +- security->priv->syslog = pk_syslog_new (); +- +- /* get a connection to the bus */ +- dbus_error_init (&dbus_error); +- security->priv->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error); +- if (security->priv->connection == NULL) { +- if (dbus_error_is_set (&dbus_error)) { +- egg_warning ("failed to get system connection %s: %s\n", dbus_error.name, dbus_error.message); +- dbus_error_free (&dbus_error); +- } +- } +- +- /* get PolicyKit context */ +- security->priv->pk_context = polkit_context_new (); +- +- /* watch for changes */ +- polkit_context_set_io_watch_functions (security->priv->pk_context, +- pk_security_io_add_watch, +- pk_security_io_remove_watch); +- +- pk_error = NULL; +- retval = polkit_context_init (security->priv->pk_context, &pk_error); +- if (retval == FALSE) { +- egg_warning ("Could not init PolicyKit context: %s", polkit_error_get_error_message (pk_error)); +- polkit_error_free (pk_error); +- } +-} +- +-/** +- * pk_security_new: +- * Return value: A new security class instance. +- **/ +-PkSecurity * +-pk_security_new (void) +-{ +- if (pk_security_object != NULL) { +- g_object_ref (pk_security_object); +- } else { +- pk_security_object = g_object_new (PK_TYPE_SECURITY, NULL); +- g_object_add_weak_pointer (pk_security_object, &pk_security_object); +- } +- return PK_SECURITY (pk_security_object); +-} +- +-/*************************************************************************** +- *** MAKE CHECK TESTS *** +- ***************************************************************************/ +-#ifdef EGG_TEST +-#include "egg-test.h" +- +-void +-pk_security_test (EggTest *test) +-{ +- PkSecurity *security; +- const gchar *action; +- +- if (!egg_test_start (test, "PkSecurity")) +- return; +- +- /************************************************************/ +- egg_test_title (test, "get an instance"); +- security = pk_security_new (); +- egg_test_assert (test, security != NULL); +- egg_test_title_assert (test, "check connection", security->priv->connection != NULL); +- egg_test_title_assert (test, "check PolKit context", security->priv->pk_context != NULL); +- +- /************************************************************/ +- egg_test_title (test, "map valid role to action"); +- action = pk_security_role_to_action (security, FALSE, PK_ROLE_ENUM_UPDATE_PACKAGES); +- if (egg_strequal (action, "org.freedesktop.packagekit.system-update")) +- egg_test_success (test, NULL); +- else +- egg_test_failed (test, "did not get correct action '%s'", action); +- +- /************************************************************/ +- egg_test_title (test, "map invalid role to action"); +- action = pk_security_role_to_action (security, FALSE, PK_ROLE_ENUM_SEARCH_NAME); +- if (action == NULL) +- egg_test_success (test, NULL); +- else +- egg_test_failed (test, "did not get correct action '%s'", action); +- +- g_object_unref (security); +- +- egg_test_end (test); +-} +-#endif +- +diff --git a/src/pk-security.h b/src/pk-security.h +deleted file mode 100644 +index a90d9f4..0000000 +--- a/src/pk-security.h ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2007 Richard Hughes +- * +- * Licensed under the GNU General Public License Version 2 +- * +- * 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 +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +- */ +- +-#ifndef __PK_SECURITY_H +-#define __PK_SECURITY_H +- +-#include +-#include +- +-G_BEGIN_DECLS +- +-#define PK_TYPE_SECURITY (pk_security_get_type ()) +-#define PK_SECURITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_SECURITY, PkSecurity)) +-#define PK_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_SECURITY, PkSecurityClass)) +-#define PK_IS_SECURITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_SECURITY)) +-#define PK_IS_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_SECURITY)) +-#define PK_SECURITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_SECURITY, PkSecurityClass)) +- +-/* not actually roles */ +-#define PK_ROLE_ENUM_SET_PROXY_PRIVATE (PK_ROLE_ENUM_UNKNOWN + 1) +- +-/* when the UID is invalid or not known */ +-#define PK_SECURITY_UID_INVALID G_MAXUINT +- +-typedef struct PkSecurityPrivate PkSecurityPrivate; +- +-typedef struct +-{ +- GObject parent; +- PkSecurityPrivate *priv; +-} PkSecurity; +- +-typedef struct +-{ +- GObjectClass parent_class; +-} PkSecurityClass; +- +-typedef struct PkSecurityCaller_ PkSecurityCaller; +- +-GType pk_security_get_type (void); +-PkSecurity *pk_security_new (void); +- +-PkSecurityCaller *pk_security_caller_new_from_sender (PkSecurity *security, +- const gchar *sender); +-void pk_security_caller_unref (PkSecurityCaller *caller); +-guint pk_security_get_uid (PkSecurity *security, +- PkSecurityCaller *caller); +-gchar *pk_security_get_cmdline (PkSecurity *security, +- PkSecurityCaller *caller); +-gboolean pk_security_action_is_allowed (PkSecurity *security, +- PkSecurityCaller *caller, +- gboolean trusted, +- PkRoleEnum role, +- gchar **error_detail) +- G_GNUC_WARN_UNUSED_RESULT; +- +-G_END_DECLS +- +-#endif /* __PK_SECURITY_H */ +diff --git a/src/pk-self-test.c b/src/pk-self-test.c +index e8370d9..ccaf919 100644 +--- a/src/pk-self-test.c ++++ b/src/pk-self-test.c +@@ -32,7 +32,6 @@ void pk_inhibit_test (EggTest *test); + void pk_spawn_test (EggTest *test); + void pk_transaction_list_test (EggTest *test); + void pk_transaction_db_test (EggTest *test); +-void pk_security_test (EggTest *test); + void pk_time_test (EggTest *test); + void pk_backend_test (EggTest *test); + void pk_backend_test_spawn (EggTest *test); +@@ -55,7 +54,6 @@ main (int argc, char **argv) + + /* components */ + pk_file_monitor_test (test); +- pk_security_test (test); + pk_time_test (test); + pk_conf_test (test); + pk_store_test (test); +diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c +index 95edc0d..1be4264 100644 +--- a/src/pk-transaction-list.c ++++ b/src/pk-transaction-list.c +@@ -570,10 +570,6 @@ pk_transaction_list_get_state (PkTransactionList *tlist) + if (wrong != 0) + g_string_append_printf (string, "ERROR: %i have inconsistent flags\n", wrong); + +- /* some are not committed */ +- if (no_commit != 0) +- g_string_append_printf (string, "WARNING: %i have not been committed\n", no_commit); +- + /* more than one running */ + if (running > 1) + g_string_append_printf (string, "ERROR: %i are running\n", running); +@@ -649,7 +645,7 @@ pk_transaction_list_is_consistent (PkTransactionList *tlist) + + /* some are not committed */ + if (no_commit != 0) +- egg_debug ("%i have not been committed", no_commit); ++ egg_debug ("%i have not been committed and may be pending auth", no_commit); + + /* more than one running */ + if (running > 1) { +diff --git a/src/pk-transaction.c b/src/pk-transaction.c +index 255cb7d..0897694 100644 +--- a/src/pk-transaction.c ++++ b/src/pk-transaction.c +@@ -42,6 +42,9 @@ + #include + #include + #include ++#ifdef USE_SECURITY_POLKIT ++#include ++#endif + + #include "egg-debug.h" + #include "egg-string.h" +@@ -58,7 +61,6 @@ + #include "pk-shared.h" + #include "pk-cache.h" + #include "pk-notify.h" +-#include "pk-security.h" + #include "pk-post-trans.h" + #include "pk-syslog.h" + +@@ -68,6 +70,9 @@ static void pk_transaction_dispose (GObject *object); + #define PK_TRANSACTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_TRANSACTION, PkTransactionPrivate)) + #define PK_TRANSACTION_UPDATES_CHANGED_TIMEOUT 100 /* ms */ + ++/* when the UID is invalid or not known */ ++#define PK_TRANSACTION_UID_INVALID G_MAXUINT ++ + static void pk_transaction_status_changed_cb (PkBackend *backend, PkStatusEnum status, PkTransaction *transaction); + static void pk_transaction_progress_changed_cb (PkBackend *backend, guint percentage, guint subpercentage, guint elapsed, guint remaining, PkTransaction *transaction); + +@@ -83,6 +88,7 @@ struct PkTransactionPrivate + gboolean running; + gboolean has_been_run; + gboolean allow_cancel; ++ gboolean waiting_for_auth; + gboolean emit_eula_required; + gboolean emit_signature_required; + gboolean emit_media_change_required; +@@ -94,8 +100,13 @@ struct PkTransactionPrivate + PkCache *cache; + PkConf *conf; + PkNotify *notify; +- PkSecurity *security; +- PkSecurityCaller *caller; ++#ifdef USE_SECURITY_POLKIT ++ PolkitAuthority *authority; ++ PolkitSubject *subject; ++ GCancellable *cancellable; ++#endif ++ DBusGConnection *connection; ++ DBusGProxy *proxy_pid; + PkPostTrans *post_trans; + PkSyslog *syslog; + +@@ -410,6 +421,18 @@ pk_transaction_finished_emit (PkTransaction *transaction, PkExitEnum exit_enum, + } + + /** ++ * pk_transaction_error_code_emit: ++ **/ ++static void ++pk_transaction_error_code_emit (PkTransaction *transaction, PkErrorCodeEnum error_enum, const gchar *details) ++{ ++ const gchar *text; ++ text = pk_error_enum_to_text (error_enum); ++ egg_debug ("emitting error-code %s, '%s'", text, details); ++ g_signal_emit (transaction, signals [PK_TRANSACTION_ERROR_CODE], 0, text, details); ++} ++ ++/** + * pk_transaction_allow_cancel_cb: + **/ + static void +@@ -462,8 +485,6 @@ static void + pk_transaction_error_code_cb (PkBackend *backend, PkErrorCodeEnum code, + const gchar *details, PkTransaction *transaction) + { +- const gchar *code_text; +- + g_return_if_fail (PK_IS_TRANSACTION (transaction)); + g_return_if_fail (transaction->priv->tid != NULL); + +@@ -473,9 +494,7 @@ pk_transaction_error_code_cb (PkBackend *backend, PkErrorCodeEnum code, + "- this is a backend problem and should be fixed!", pk_role_enum_to_text (transaction->priv->role)); + } + +- code_text = pk_error_enum_to_text (code); +- egg_debug ("emitting error-code %s, '%s'", code_text, details); +- g_signal_emit (transaction, signals [PK_TRANSACTION_ERROR_CODE], 0, code_text, details); ++ pk_transaction_error_code_emit (transaction, code, details); + } + + /** +@@ -727,7 +746,7 @@ pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit_enum, PkTransact + pk_inhibit_remove (transaction->priv->inhibit, transaction); + + /* report to syslog */ +- if (transaction->priv->uid != PK_SECURITY_UID_INVALID) ++ if (transaction->priv->uid != PK_TRANSACTION_UID_INVALID) + pk_syslog_add (transaction->priv->syslog, PK_SYSLOG_TYPE_INFO, "%s transaction %s from uid %i finished with %s after %ims", + pk_role_enum_to_text (transaction->priv->role), transaction->priv->tid, + transaction->priv->uid, pk_exit_enum_to_text (exit_enum), time_ms); +@@ -1235,6 +1254,31 @@ pk_transaction_set_tid (PkTransaction *transaction, const gchar *tid) + } + + /** ++ * pk_transaction_get_uid: ++ **/ ++static guint ++pk_transaction_get_uid (PkTransaction *transaction, const gchar *sender) ++{ ++ guint uid; ++ DBusError error; ++ DBusConnection *con; ++ ++ g_return_val_if_fail (PK_IS_TRANSACTION (transaction), G_MAXUINT); ++ g_return_val_if_fail (sender != NULL, G_MAXUINT); ++ ++ dbus_error_init (&error); ++ con = dbus_g_connection_get_connection (transaction->priv->connection); ++ uid = dbus_bus_get_unix_user (con, sender, &error); ++ if (dbus_error_is_set (&error)) { ++ egg_warning ("Could not get uid for connection: %s %s", error.name, error.message); ++ uid = G_MAXUINT; ++ goto out; ++ } ++out: ++ return uid; ++} ++ ++/** + * pk_transaction_set_sender: + */ + gboolean +@@ -1249,9 +1293,10 @@ pk_transaction_set_sender (PkTransaction *transaction, const gchar *sender) + egg_dbus_monitor_assign (transaction->priv->monitor, EGG_DBUS_MONITOR_SYSTEM, sender); + + /* we get the UID for all callers as we need to know when to cancel */ +- transaction->priv->caller = pk_security_caller_new_from_sender (transaction->priv->security, sender); +- if (transaction->priv->caller != NULL) +- transaction->priv->uid = pk_security_get_uid (transaction->priv->security, transaction->priv->caller); ++#ifdef USE_SECURITY_POLKIT ++ transaction->priv->subject = polkit_system_bus_name_new (sender); ++#endif ++ transaction->priv->uid = pk_transaction_get_uid (transaction, sender); + + return TRUE; + } +@@ -1270,6 +1315,77 @@ pk_transaction_release_tid (PkTransaction *transaction) + return ret; + } + ++#ifdef USE_SECURITY_POLKIT ++/** ++ * pk_transaction_get_pid: ++ **/ ++static guint ++pk_transaction_get_pid (PkTransaction *transaction, PolkitSubject *subject) ++{ ++ guint pid; ++ gboolean ret; ++ gchar *sender = NULL; ++ GError *error = NULL; ++ ++ g_return_val_if_fail (PK_IS_TRANSACTION (transaction), G_MAXUINT); ++ g_return_val_if_fail (transaction->priv->proxy_pid != NULL, G_MAXUINT); ++ g_return_val_if_fail (subject != NULL, G_MAXUINT); ++ ++ /* this comes back as 'system-bus-name::1.127' */ ++ sender = polkit_subject_to_string (subject); ++ ++ /* get pid from DBus (quite slow) */ ++ ret = dbus_g_proxy_call (transaction->priv->proxy_pid, "GetConnectionUnixProcessID", &error, ++ G_TYPE_STRING, sender+16, ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &pid, ++ G_TYPE_INVALID); ++ if (!ret) { ++ egg_error ("failed to get pid: %s", error->message); ++ g_error_free (error); ++ goto out; ++ } ++out: ++ g_free (sender); ++ return pid; ++} ++ ++ ++/** ++ * pk_transaction_get_cmdline: ++ **/ ++static gchar * ++pk_transaction_get_cmdline (PkTransaction *transaction, PolkitSubject *subject) ++{ ++ gboolean ret; ++ gchar *filename = NULL; ++ gchar *cmdline = NULL; ++ GError *error = NULL; ++ guint pid; ++ ++ g_return_val_if_fail (PK_IS_TRANSACTION (transaction), NULL); ++ g_return_val_if_fail (subject != NULL, NULL); ++ ++ /* get pid */ ++ pid = pk_transaction_get_pid (transaction, subject); ++ if (pid == G_MAXUINT) { ++ egg_warning ("failed to get PID"); ++ goto out; ++ } ++ ++ /* get command line from proc */ ++ filename = g_strdup_printf ("/proc/%i/cmdline", pid); ++ ret = g_file_get_contents (filename, &cmdline, NULL, &error); ++ if (!ret) { ++ egg_warning ("failed to get cmdline: %s", error->message); ++ g_error_free (error); ++ } ++out: ++ g_free (filename); ++ return cmdline; ++} ++#endif ++ + /** + * pk_transaction_commit: + **/ +@@ -1277,7 +1393,9 @@ G_GNUC_WARN_UNUSED_RESULT static gboolean + pk_transaction_commit (PkTransaction *transaction) + { + gboolean ret; ++#ifdef USE_SECURITY_POLKIT + gchar *cmdline; ++#endif + + g_return_val_if_fail (PK_IS_TRANSACTION (transaction), FALSE); + g_return_val_if_fail (transaction->priv->tid != NULL, FALSE); +@@ -1306,15 +1424,16 @@ pk_transaction_commit (PkTransaction *transaction) + /* save uid */ + pk_transaction_db_set_uid (transaction->priv->transaction_db, transaction->priv->tid, transaction->priv->uid); + ++#ifdef USE_SECURITY_POLKIT + /* save cmdline */ +- cmdline = pk_security_get_cmdline (transaction->priv->security, transaction->priv->caller); ++ cmdline = pk_transaction_get_cmdline (transaction, transaction->priv->subject); + pk_transaction_db_set_cmdline (transaction->priv->transaction_db, transaction->priv->tid, cmdline); ++ g_free (cmdline); ++#endif + + /* report to syslog */ + pk_syslog_add (transaction->priv->syslog, PK_SYSLOG_TYPE_INFO, "new %s transaction %s scheduled from uid %i", + pk_role_enum_to_text (transaction->priv->role), transaction->priv->tid, transaction->priv->uid); +- +- g_free (cmdline); + } + return TRUE; + } +@@ -1425,35 +1544,163 @@ out: + return ret; + } + ++#ifdef USE_SECURITY_POLKIT ++/** ++ * pk_transaction_action_obtain_authorization: ++ **/ ++static void ++pk_transaction_action_obtain_authorization_finished_cb (GObject *source_object, GAsyncResult *res, PkTransaction *transaction) ++{ ++ PolkitAuthorizationResult *result; ++ gboolean ret; ++ GError *error = NULL; ++ ++ /* finish the call */ ++ result = polkit_authority_check_authorization_finish (transaction->priv->authority, res, &error); ++ transaction->priv->waiting_for_auth = FALSE; ++ ++ /* failed */ ++ if (result == NULL) { ++ egg_warning ("failed to check for auth: %s", error->message); ++ g_error_free (error); ++ goto out; ++ } ++ ++ /* did not auth */ ++ if (!polkit_authorization_result_get_is_authorized (result)) { ++ ++ /* emit an ::ErrorCode() and then ::Finished() */ ++ pk_transaction_error_code_emit (transaction, PK_ERROR_ENUM_NOT_AUTHORIZED, "failed to obtain auth"); ++ pk_transaction_finished_emit (transaction, PK_EXIT_ENUM_FAILED, 0); ++ ++ pk_syslog_add (transaction->priv->syslog, PK_SYSLOG_TYPE_AUTH, "uid %i failed to obtain auth", transaction->priv->uid); ++ goto out; ++ } ++ ++ /* try to commit this */ ++ ret = pk_transaction_commit (transaction); ++ if (!ret) { ++ egg_warning ("Could not commit to a transaction object"); ++ pk_transaction_release_tid (transaction); ++ goto out; ++ } ++ ++ /* log success too */ ++ pk_syslog_add (transaction->priv->syslog, PK_SYSLOG_TYPE_AUTH, "uid %i obtained auth", transaction->priv->uid); ++out: ++ if (result != NULL) ++ g_object_unref (result); ++ return; ++} ++ + /** +- * pk_transaction_action_is_allowed: ++ * pk_transaction_role_to_action: ++ **/ ++static const gchar * ++pk_transaction_role_to_action (gboolean trusted, PkRoleEnum role) ++{ ++ const gchar *policy = NULL; ++ ++ if (role == PK_ROLE_ENUM_UPDATE_PACKAGES || ++ role == PK_ROLE_ENUM_UPDATE_SYSTEM) { ++ policy = "org.freedesktop.packagekit.system-update"; ++ } else if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE) { ++ policy = "org.freedesktop.packagekit.system-trust-signing-key"; ++ } else if (role == PK_ROLE_ENUM_ROLLBACK) { ++ policy = "org.freedesktop.packagekit.system-rollback"; ++ } else if (role == PK_ROLE_ENUM_REPO_ENABLE || ++ role == PK_ROLE_ENUM_REPO_SET_DATA) { ++ policy = "org.freedesktop.packagekit.system-sources-configure"; ++ } else if (role == PK_ROLE_ENUM_REFRESH_CACHE) { ++ policy = "org.freedesktop.packagekit.system-sources-refresh"; ++ } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) { ++ policy = "org.freedesktop.packagekit.package-remove"; ++ } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) { ++ policy = "org.freedesktop.packagekit.package-install"; ++ } else if (role == PK_ROLE_ENUM_INSTALL_FILES && trusted) { ++ policy = "org.freedesktop.packagekit.package-install"; ++ } else if (role == PK_ROLE_ENUM_INSTALL_FILES && !trusted) { ++ policy = "org.freedesktop.packagekit.package-install-untrusted"; ++ } else if (role == PK_ROLE_ENUM_ACCEPT_EULA) { ++ policy = "org.freedesktop.packagekit.package-eula-accept"; ++ } else if (role == PK_ROLE_ENUM_CANCEL) { ++ policy = "org.freedesktop.packagekit.cancel-foreign"; ++ } ++ return policy; ++} ++ ++/** ++ * pk_transaction_obtain_authorization: + * + * Only valid from an async caller, which is fine, as we won't prompt the user + * when not async. ++ * ++ * Because checking for authentication might have to respond to user input, this ++ * is treated as async. As such, the transaction should only be added to the ++ * transaction list when authorised, and not before. + **/ + static gboolean +-pk_transaction_action_is_allowed (PkTransaction *transaction, gboolean trusted, PkRoleEnum role, GError **error) ++pk_transaction_obtain_authorization (PkTransaction *transaction, gboolean trusted, PkRoleEnum role, GError **error) + { +- gboolean ret; +- gchar *error_detail; ++ const gchar *action_id; ++ gboolean ret = FALSE; + + g_return_val_if_fail (transaction->priv->sender != NULL, FALSE); + +- /* we should always have caller */ +- if (transaction->priv->caller == NULL) { ++ /* we should always have subject */ ++ if (transaction->priv->subject == NULL) { + *error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_REFUSED_BY_POLICY, +- "caller %s not found", transaction->priv->sender); +- return FALSE; ++ "subject %s not found", transaction->priv->sender); ++ goto out; + } + +- /* use security model to get auth */ +- ret = pk_security_action_is_allowed (transaction->priv->security, transaction->priv->caller, trusted, role, &error_detail); ++ /* map the roles to policykit rules */ ++ action_id = pk_transaction_role_to_action (trusted, role); ++ if (action_id == NULL) { ++ *error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_REFUSED_BY_POLICY, "policykit type required for '%s'", pk_role_enum_to_text (role)); ++ goto out; ++ } ++ ++ /* log */ ++ pk_syslog_add (transaction->priv->syslog, PK_SYSLOG_TYPE_AUTH, "uid %i is trying to obtain %s auth (trusted:%i)", transaction->priv->uid, action_id, trusted); ++ ++ /* check subject */ ++ transaction->priv->waiting_for_auth = TRUE; ++ polkit_authority_check_authorization (transaction->priv->authority, ++ transaction->priv->subject, ++ action_id, ++ NULL, ++ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, ++ transaction->priv->cancellable, ++ (GAsyncReadyCallback) pk_transaction_action_obtain_authorization_finished_cb, ++ transaction); ++ /* assume success, as this is async */ ++ ret = TRUE; ++out: ++ return ret; ++} ++ ++#else ++/** ++ * pk_transaction_obtain_authorization: ++ **/ ++static gboolean ++pk_transaction_obtain_authorization (PkTransaction *transaction, gboolean trusted, PkRoleEnum role, GError **error) ++{ ++ gboolean ret; ++ ++ egg_warning ("*** THERE IS NO SECURITY MODEL BEING USED!!! ***"); ++ ++ /* try to commit this */ ++ ret = pk_transaction_commit (transaction); + if (!ret) { +- *error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_REFUSED_BY_POLICY, "%s", error_detail); +- g_free (error_detail); ++ egg_warning ("Could not commit to a transaction object"); ++ pk_transaction_release_tid (transaction); + } ++ + return ret; + } ++#endif + + /** + * pk_transaction_priv_get_role: +@@ -1554,8 +1801,8 @@ pk_transaction_accept_eula (PkTransaction *transaction, const gchar *eula_id, DB + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_ACCEPT_EULA, &error); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_ACCEPT_EULA, &error); + if (!ret) { + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); +@@ -1589,7 +1836,6 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex + GError *error = NULL; + gchar *sender; + guint uid; +- PkSecurityCaller *caller; + + g_return_if_fail (PK_IS_TRANSACTION (transaction)); + g_return_if_fail (transaction->priv->tid != NULL); +@@ -1628,7 +1874,7 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex + } + + /* check if we saved the uid */ +- if (transaction->priv->uid == PK_SECURITY_UID_INVALID) { ++ if (transaction->priv->uid == PK_TRANSACTION_UID_INVALID) { + error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_CANNOT_CANCEL, + "No context from caller to get UID from"); + pk_transaction_dbus_return_error (context, error); +@@ -1637,13 +1883,11 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex + + /* get the UID of the caller */ + sender = dbus_g_method_get_sender (context); +- caller = pk_security_caller_new_from_sender (transaction->priv->security, sender); +- uid = pk_security_get_uid (transaction->priv->security, caller); ++ uid = pk_transaction_get_uid (transaction, sender); + g_free (sender); +- pk_security_caller_unref (caller); + + /* check we got a valid value */ +- if (uid == PK_SECURITY_UID_INVALID) { ++ if (uid == PK_TRANSACTION_UID_INVALID) { + error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_STATE, "unable to get uid of caller"); + pk_transaction_dbus_return_error (context, error); + return; +@@ -1652,7 +1896,7 @@ pk_transaction_cancel (PkTransaction *transaction, DBusGMethodInvocation *contex + /* check the caller uid with the originator uid */ + if (transaction->priv->uid != uid) { + egg_debug ("uid does not match (%i vs. %i)", transaction->priv->uid, uid); +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_CANCEL, &error); ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_CANCEL, &error); + if (!ret) { + pk_transaction_dbus_return_error (context, error); + return; +@@ -2680,8 +2924,8 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted, + } + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, trusted, PK_ROLE_ENUM_INSTALL_FILES, &error); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, trusted, PK_ROLE_ENUM_INSTALL_FILES, &error); + if (!ret) { + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); +@@ -2693,16 +2937,6 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean trusted, + transaction->priv->cached_full_paths = g_strdupv (full_paths); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_INSTALL_FILES); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); +- if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* return from async with success */ + pk_transaction_dbus_return (context); + return; +@@ -2755,23 +2989,13 @@ pk_transaction_install_packages (PkTransaction *transaction, gchar **package_ids + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_INSTALL_PACKAGES, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_package_ids = g_strdupv (package_ids); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_INSTALL_PACKAGES); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_INSTALL_PACKAGES, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -2834,24 +3058,14 @@ pk_transaction_install_signature (PkTransaction *transaction, const gchar *sig_t + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_INSTALL_SIGNATURE, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_package_id = g_strdup (package_id); + transaction->priv->cached_key_id = g_strdup (key_id); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_INSTALL_SIGNATURE); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_INSTALL_SIGNATURE, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -2907,14 +3121,6 @@ pk_transaction_refresh_cache (PkTransaction *transaction, gboolean force, DBusGM + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_REFRESH_CACHE, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* we unref the update cache if it exists */ + pk_cache_invalidate (transaction->priv->cache); + +@@ -2922,11 +3128,9 @@ pk_transaction_refresh_cache (PkTransaction *transaction, gboolean force, DBusGM + transaction->priv->cached_force = force; + pk_transaction_set_role (transaction, PK_ROLE_ENUM_REFRESH_CACHE); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_REFRESH_CACHE, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -2984,24 +3188,14 @@ pk_transaction_remove_packages (PkTransaction *transaction, gchar **package_ids, + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_REMOVE_PACKAGES, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_allow_deps = allow_deps; + transaction->priv->cached_package_ids = g_strdupv (package_ids); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_REMOVE_PACKAGES); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_REMOVE_PACKAGES, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3053,24 +3247,14 @@ pk_transaction_repo_enable (PkTransaction *transaction, const gchar *repo_id, gb + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_REPO_ENABLE, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_repo_id = g_strdup (repo_id); + transaction->priv->cached_enabled = enabled; + pk_transaction_set_role (transaction, PK_ROLE_ENUM_REPO_ENABLE); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_REPO_ENABLE, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3123,25 +3307,15 @@ pk_transaction_repo_set_data (PkTransaction *transaction, const gchar *repo_id, + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_REPO_SET_DATA, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_repo_id = g_strdup (repo_id); + transaction->priv->cached_parameter = g_strdup (parameter); + transaction->priv->cached_value = g_strdup (value); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_REPO_SET_DATA); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_REPO_SET_DATA, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3270,23 +3444,13 @@ pk_transaction_rollback (PkTransaction *transaction, const gchar *transaction_id + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_ROLLBACK, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_transaction_id = g_strdup (transaction_id); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_ROLLBACK); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_ROLLBACK, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3646,23 +3810,13 @@ pk_transaction_update_packages (PkTransaction *transaction, gchar **package_ids, + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_UPDATE_PACKAGES, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* save so we can run later */ + transaction->priv->cached_package_ids = g_strdupv (package_ids); + pk_transaction_set_role (transaction, PK_ROLE_ENUM_UPDATE_PACKAGES); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_UPDATE_PACKAGES, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3703,14 +3857,6 @@ pk_transaction_update_system (PkTransaction *transaction, DBusGMethodInvocation + return; + } + +- /* check if the action is allowed from this client - if not, set an error */ +- ret = pk_transaction_action_is_allowed (transaction, FALSE, PK_ROLE_ENUM_UPDATE_SYSTEM, &error); +- if (!ret) { +- pk_transaction_release_tid (transaction); +- pk_transaction_dbus_return_error (context, error); +- return; +- } +- + /* are we already performing an update? */ + if (pk_transaction_list_role_present (transaction->priv->transaction_list, PK_ROLE_ENUM_UPDATE_SYSTEM)) { + error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_TRANSACTION_EXISTS_WITH_ROLE, +@@ -3722,11 +3868,9 @@ pk_transaction_update_system (PkTransaction *transaction, DBusGMethodInvocation + + pk_transaction_set_role (transaction, PK_ROLE_ENUM_UPDATE_SYSTEM); + +- /* try to commit this */ +- ret = pk_transaction_commit (transaction); ++ /* try to get authorization */ ++ ret = pk_transaction_obtain_authorization (transaction, FALSE, PK_ROLE_ENUM_UPDATE_SYSTEM, &error); + if (!ret) { +- error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED, +- "Could not commit to a transaction object"); + pk_transaction_release_tid (transaction); + pk_transaction_dbus_return_error (context, error); + return; +@@ -3943,10 +4087,13 @@ pk_transaction_class_init (PkTransactionClass *klass) + static void + pk_transaction_init (PkTransaction *transaction) + { ++ GError *error = NULL; ++ + transaction->priv = PK_TRANSACTION_GET_PRIVATE (transaction); + transaction->priv->finished = FALSE; + transaction->priv->running = FALSE; + transaction->priv->has_been_run = FALSE; ++ transaction->priv->waiting_for_auth = FALSE; + transaction->priv->allow_cancel = TRUE; + transaction->priv->emit_eula_required = FALSE; + transaction->priv->emit_signature_required = FALSE; +@@ -3967,8 +4114,10 @@ pk_transaction_init (PkTransaction *transaction) + transaction->priv->tid = NULL; + transaction->priv->sender = NULL; + transaction->priv->locale = NULL; +- transaction->priv->caller = NULL; +- transaction->priv->uid = PK_SECURITY_UID_INVALID; ++#ifdef USE_SECURITY_POLKIT ++ transaction->priv->subject = NULL; ++#endif ++ transaction->priv->uid = PK_TRANSACTION_UID_INVALID; + transaction->priv->role = PK_ROLE_ENUM_UNKNOWN; + transaction->priv->status = PK_STATUS_ENUM_WAIT; + transaction->priv->percentage = PK_BACKEND_PERCENTAGE_INVALID; +@@ -3976,7 +4125,6 @@ pk_transaction_init (PkTransaction *transaction) + transaction->priv->elapsed = 0; + transaction->priv->remaining = 0; + transaction->priv->backend = pk_backend_new (); +- transaction->priv->security = pk_security_new (); + transaction->priv->cache = pk_cache_new (); + transaction->priv->conf = pk_conf_new (); + transaction->priv->notify = pk_notify_new (); +@@ -3984,6 +4132,10 @@ pk_transaction_init (PkTransaction *transaction) + transaction->priv->package_list = pk_package_list_new (); + transaction->priv->transaction_list = pk_transaction_list_new (); + transaction->priv->syslog = pk_syslog_new (); ++#ifdef USE_SECURITY_POLKIT ++ transaction->priv->authority = polkit_authority_get (); ++ transaction->priv->cancellable = g_cancellable_new (); ++#endif + + transaction->priv->post_trans = pk_post_trans_new (); + g_signal_connect (transaction->priv->post_trans, "status-changed", +@@ -3998,6 +4150,17 @@ pk_transaction_init (PkTransaction *transaction) + transaction->priv->monitor = egg_dbus_monitor_new (); + g_signal_connect (transaction->priv->monitor, "connection-changed", + G_CALLBACK (pk_transaction_caller_active_changed_cb), transaction); ++ ++ /* connect to DBus so we can get the pid */ ++ transaction->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); ++ transaction->priv->proxy_pid = dbus_g_proxy_new_for_name_owner (transaction->priv->connection, ++ "org.freedesktop.DBus", ++ "/org/freedesktop/DBus/Bus", ++ "org.freedesktop.DBus", &error); ++ if (transaction->priv->proxy_pid == NULL) { ++ egg_warning ("cannot connect to DBus: %s", error->message); ++ g_error_free (error); ++ } + } + + /** +@@ -4015,6 +4178,16 @@ pk_transaction_dispose (GObject *object) + /* remove any inhibit, it's okay to call this function when it's not needed */ + pk_inhibit_remove (transaction->priv->inhibit, transaction); + ++ /* were we waiting for the client to authorise */ ++ if (transaction->priv->waiting_for_auth) { ++#ifdef USE_SECURITY_POLKIT ++ g_cancellable_cancel (transaction->priv->cancellable); ++#endif ++ /* emit an ::ErrorCode() and then ::Finished() */ ++ pk_transaction_error_code_emit (transaction, PK_ERROR_ENUM_NOT_AUTHORIZED, "client did not authorize action"); ++ pk_transaction_finished_emit (transaction, PK_EXIT_ENUM_FAILED, 0); ++ } ++ + /* send signal to clients that we are about to be destroyed */ + egg_debug ("emitting destroy %s", transaction->priv->tid); + g_signal_emit (transaction, signals [PK_TRANSACTION_DESTROY], 0); +@@ -4034,6 +4207,11 @@ pk_transaction_finalize (GObject *object) + + transaction = PK_TRANSACTION (object); + ++#ifdef USE_SECURITY_POLKIT ++ if (transaction->priv->subject != NULL) ++ g_object_unref (transaction->priv->subject); ++#endif ++ + g_free (transaction->priv->last_package_id); + g_free (transaction->priv->locale); + g_free (transaction->priv->cached_package_id); +@@ -4056,11 +4234,14 @@ pk_transaction_finalize (GObject *object) + g_object_unref (transaction->priv->package_list); + g_object_unref (transaction->priv->transaction_list); + g_object_unref (transaction->priv->transaction_db); +- g_object_unref (transaction->priv->security); ++ g_object_unref (transaction->priv->proxy_pid); + g_object_unref (transaction->priv->notify); + g_object_unref (transaction->priv->syslog); + g_object_unref (transaction->priv->post_trans); +- pk_security_caller_unref (transaction->priv->caller); ++#ifdef USE_SECURITY_POLKIT ++// g_object_unref (transaction->priv->authority); ++ g_object_unref (transaction->priv->cancellable); ++#endif + + G_OBJECT_CLASS (pk_transaction_parent_class)->finalize (object); + } +@@ -4091,6 +4272,9 @@ egg_test_transaction (EggTest *test) + gboolean ret; + const gchar *temp; + GError *error = NULL; ++#ifdef USE_SECURITY_POLKIT ++ const gchar *action; ++#endif + + if (!egg_test_start (test, "PkTransaction")) + return; +@@ -4101,6 +4285,26 @@ egg_test_transaction (EggTest *test) + egg_test_assert (test, transaction != NULL); + + /************************************************************ ++ **************** MAP ROLES ****************** ++ ************************************************************/ ++#ifdef USE_SECURITY_POLKIT ++ egg_test_title (test, "map valid role to action"); ++ action = pk_transaction_role_to_action (FALSE, PK_ROLE_ENUM_UPDATE_PACKAGES); ++ if (egg_strequal (action, "org.freedesktop.packagekit.system-update")) ++ egg_test_success (test, NULL); ++ else ++ egg_test_failed (test, "did not get correct action '%s'", action); ++ ++ /************************************************************/ ++ egg_test_title (test, "map invalid role to action"); ++ action = pk_transaction_role_to_action (FALSE, PK_ROLE_ENUM_SEARCH_NAME); ++ if (action == NULL) ++ egg_test_success (test, NULL); ++ else ++ egg_test_failed (test, "did not get correct action '%s'", action); ++#endif ++ ++ /************************************************************ + **************** FILTERS ****************** + ************************************************************/ + temp = NULL; diff --git a/PackageKit.spec b/PackageKit.spec index d23eafd..4de4f1c 100644 --- a/PackageKit.spec +++ b/PackageKit.spec @@ -1,15 +1,15 @@ -%define glib2_version 2.16.1 -%define dbus_version 1.1.1 -%define dbus_glib_version 0.74 -%define policykit_version 0.8 -%define alphatag 20090616 +%define glib2_version 2.16.1 +%define dbus_version 1.1.1 +%define dbus_glib_version 0.74 +%define polkit_version 0.92 +%define alphatag 20090616 %{!?python_sitelib: %define python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} Summary: Package management service Name: PackageKit Version: 0.4.9 -Release: 0.1.%{?alphatag}git%{?dist} +Release: 0.2.%{?alphatag}git%{?dist} #Release: 1%{?dist} License: GPLv2+ Group: System Environment/Libraries @@ -24,6 +24,9 @@ Patch0: PackageKit-0.3.8-Fedora-Vendor.conf.patch # Fedora specific: the yum backend doesn't do time estimation correctly Patch1: PackageKit-0.4.4-Fedora-turn-off-time.conf.patch +# from upstream polkit1 branch, automatically generated +Patch2: PackageKit-port-to-polkit1.patch + Requires: dbus >= %{dbus_version} Requires: dbus-glib >= %{dbus_glib_version} Requires: PackageKit-glib = %{version}-%{release} @@ -42,7 +45,7 @@ BuildRequires: libX11-devel BuildRequires: xmlto BuildRequires: sqlite-devel BuildRequires: NetworkManager-glib-devel >= %{libnm_glib_version} -BuildRequires: PolicyKit-devel >= %{policykit_version} +BuildRequires: polkit-devel >= %{polkit_version} BuildRequires: libtool BuildRequires: docbook-utils BuildRequires: gnome-doc-utils @@ -61,6 +64,9 @@ BuildRequires: fontconfig-devel #BuildRequires: gtk-sharp2-devel #BuildRequires: mono-core +# low level icky tools (due to polkit1 patch) +BuildRequires: automake, autoconf, libtool + # functionality moved to udev itself Obsoletes: PackageKit-udev-helper < %{version}-%{release} Obsoletes: udev-packagekit < %{version}-%{release} @@ -217,6 +223,11 @@ using PackageKit. #%setup -q %patch0 -p1 -b .fedora %patch1 -p1 -b .no-time +%patch2 -p1 -b .polkit1 + +# we messed about with configure.ac and Makefile.am, so regenerate (due to polkit1 patch) +autoreconf +automake %build %configure --enable-yum --enable-smart --with-default-backend=yum --disable-local --disable-ruck @@ -289,7 +300,7 @@ update-mime-database %{_datadir}/mime &> /dev/null || : %dir %{_datadir}/PackageKit/icons %{_datadir}/PackageKit/helpers/test_spawn/* %{_datadir}/man/man1/*.1.gz -%{_datadir}/PolicyKit/policy/*.policy +%{_datadir}/polkit-1/actions/*.policy %{_datadir}/mime/packages/packagekit-*.xml %{_datadir}/PackageKit/pk-upgrade-distro.sh %{_sbindir}/packagekitd @@ -402,6 +413,11 @@ update-mime-database %{_datadir}/mime &> /dev/null || : %{_includedir}/PackageKit/backend/*.h %changelog +* Tue Jun 16 2009 Richard Hughes - 0.4.9-0.2.20090616git +- Apply a patch to convert to the PolKit1 API. +- Do autoreconf and automake as the polkit patch is pretty invasive +- Fix up file lists with the new polkit action paths + * Tue Jun 16 2009 Richard Hughes - 0.4.9-0.1.20090616git - Don't hardcode network access to install or update packages - Add subclasses to our registered mime-types