diff options
author | David Zeuthen <davidz@redhat.com> | 2012-04-12 13:54:27 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2012-04-12 14:00:26 -0400 |
commit | 2dd284eb425535445f0be6e9dd7d45e8ccd3ffa6 (patch) | |
tree | 2df3f5169bde212bb49890e3b145fef3f927f1bd /src | |
parent | bda0fc1de3361fc6f377d041ce2088118048fdf7 (diff) | |
download | polkit-2dd284eb425535445f0be6e9dd7d45e8ccd3ffa6.tar.gz |
Make it possible to influence agent registration with an a{sv} parameter
Additionally, add a "fallback" option. Also add support in this in the
pkttyagent(1) program.
This slightly breaks libpolkit-backend API by adding a GVariant* param
to one of the class vfuncs... but that API is already declared
unstable so that's fine.
Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/polkit/polkitauthority.c | 164 | ||||
-rw-r--r-- | src/polkit/polkitauthority.h | 22 | ||||
-rw-r--r-- | src/polkitagent/polkitagentlistener.c | 98 | ||||
-rw-r--r-- | src/polkitagent/polkitagentlistener.h | 8 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendauthority.c | 70 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendauthority.h | 2 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendinteractiveauthority.c | 52 | ||||
-rw-r--r-- | src/programs/pkttyagent.c | 31 |
8 files changed, 394 insertions, 53 deletions
diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c index 468421e..9947cf3 100644 --- a/src/polkit/polkitauthority.c +++ b/src/polkit/polkitauthority.c @@ -1167,6 +1167,170 @@ polkit_authority_register_authentication_agent_sync (PolkitAuthority *author /* ---------------------------------------------------------------------------------------------------- */ /** + * polkit_authority_register_authentication_agent_with_options: + * @authority: A #PolkitAuthority. + * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object. + * @locale: The locale of the authentication agent. + * @object_path: The object path for the authentication agent. + * @options: (allow-none): A #GVariant with options or %NULL. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: The data to pass to @callback. + * + * Asynchronously registers an authentication agent. + * + * When the operation is finished, @callback will be invoked in the + * <link linkend="g-main-context-push-thread-default">thread-default + * main loop</link> of the thread you are calling this method + * from. You can then call + * polkit_authority_register_authentication_agent_with_options_finish() to get the + * result of the operation. + **/ +void +polkit_authority_register_authentication_agent_with_options (PolkitAuthority *authority, + PolkitSubject *subject, + const gchar *locale, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant *subject_value; + + g_return_if_fail (POLKIT_IS_AUTHORITY (authority)); + g_return_if_fail (POLKIT_IS_SUBJECT (subject)); + g_return_if_fail (locale != NULL); + g_return_if_fail (g_variant_is_object_path (object_path)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + subject_value = polkit_subject_to_gvariant (subject); + g_variant_ref_sink (subject_value); + if (options != NULL) + { + g_dbus_proxy_call (authority->proxy, + "RegisterAuthenticationAgentWithOptions", + g_variant_new ("(@(sa{sv})ss@a{sv})", + subject_value, + locale, + object_path, + options), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_register_authentication_agent_with_options)); + } + else + { + g_dbus_proxy_call (authority->proxy, + "RegisterAuthenticationAgent", + g_variant_new ("(@(sa{sv})ss)", + subject_value, + locale, + object_path), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_register_authentication_agent_with_options)); + } + g_variant_unref (subject_value); +} + +/** + * polkit_authority_register_authentication_agent_with_options_finish: + * @authority: A #PolkitAuthority. + * @res: A #GAsyncResult obtained from the callback. + * @error: (allow-none): Return location for error or %NULL. + * + * Finishes registering an authentication agent. + * + * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set. + **/ +gboolean +polkit_authority_register_authentication_agent_with_options_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error) +{ + gboolean ret; + GVariant *value; + GAsyncResult *_res; + + g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_register_authentication_agent_with_options); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); + if (value == NULL) + goto out; + ret = TRUE; + g_variant_unref (value); + + out: + return ret; +} + + +/** + * polkit_authority_register_authentication_agent_with_options_sync: + * @authority: A #PolkitAuthority. + * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object. + * @locale: The locale of the authentication agent. + * @object_path: The object path for the authentication agent. + * @options: (allow-none): A #GVariant with options or %NULL. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: (allow-none): Return location for error or %NULL. + * + * Registers an authentication agent. The calling thread is blocked + * until a reply is received. See + * polkit_authority_register_authentication_agent_with_options() for the + * asynchronous version. + * + * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set. + **/ +gboolean +polkit_authority_register_authentication_agent_with_options_sync (PolkitAuthority *authority, + PolkitSubject *subject, + const gchar *locale, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + CallSyncData *data; + + g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE); + g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE); + g_return_val_if_fail (locale != NULL, FALSE); + g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + data = call_sync_new (); + polkit_authority_register_authentication_agent_with_options (authority, subject, locale, object_path, options, cancellable, call_sync_cb, data); + call_sync_block (data); + ret = polkit_authority_register_authentication_agent_with_options_finish (authority, data->res, error); + call_sync_free (data); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** * polkit_authority_unregister_authentication_agent: * @authority: A #PolkitAuthority. * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object. diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h index edd8a62..921b712 100644 --- a/src/polkit/polkitauthority.h +++ b/src/polkit/polkitauthority.h @@ -83,6 +83,14 @@ gboolean polkit_authority_register_authentication_agent_sync ( GCancellable *cancellable, GError **error); +gboolean polkit_authority_register_authentication_agent_with_options_sync (PolkitAuthority *authority, + PolkitSubject *subject, + const gchar *locale, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GError **error); + gboolean polkit_authority_unregister_authentication_agent_sync (PolkitAuthority *authority, PolkitSubject *subject, const gchar *object_path, @@ -142,10 +150,24 @@ void polkit_authority_register_authentication_agent (Polki GAsyncReadyCallback callback, gpointer user_data); + gboolean polkit_authority_register_authentication_agent_finish (PolkitAuthority *authority, GAsyncResult *res, GError **error); +gboolean polkit_authority_register_authentication_agent_with_options_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error); + +void polkit_authority_register_authentication_agent_with_options (PolkitAuthority *authority, + PolkitSubject *subject, + const gchar *locale, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + void polkit_authority_unregister_authentication_agent (PolkitAuthority *authority, PolkitSubject *subject, const gchar *object_path, diff --git a/src/polkitagent/polkitagentlistener.c b/src/polkitagent/polkitagentlistener.c index dbbfd63..0d97501 100644 --- a/src/polkitagent/polkitagentlistener.c +++ b/src/polkitagent/polkitagentlistener.c @@ -43,7 +43,8 @@ * evidence that the user is one of the requested identities. * * To register a #PolkitAgentListener with the PolicyKit daemon, use - * polkit_agent_listener_register(). + * polkit_agent_listener_register() or + * polkit_agent_listener_register_with_options(). */ typedef struct @@ -62,6 +63,8 @@ typedef struct PolkitAgentListener *listener; + GVariant *registration_options; + PolkitSubject *subject; gchar *object_path; @@ -104,6 +107,9 @@ server_free (Server *server) if (server->interface_info != NULL) g_dbus_interface_info_unref (server->interface_info); + if (server->registration_options != NULL) + g_variant_unref (server->registration_options); + if (server->listener != NULL) g_object_unref (server->listener); @@ -143,12 +149,13 @@ server_register (Server *server, locale = "en_US.UTF-8"; local_error = NULL; - if (!polkit_authority_register_authentication_agent_sync (server->authority, - server->subject, - locale, - server->object_path, - NULL, - &local_error)) + if (!polkit_authority_register_authentication_agent_with_options_sync (server->authority, + server->subject, + locale, + server->object_path, + server->registration_options, + NULL, + &local_error)) { g_warning ("Unable to register authentication agent: %s", local_error->message); g_propagate_error (error, local_error); @@ -360,42 +367,30 @@ server_thread_func (gpointer user_data) } /** - * polkit_agent_listener_register: + * polkit_agent_listener_register_with_options: * @listener: A #PolkitAgentListener. * @flags: A set of flags from the #PolkitAgentRegisterFlags enumeration. * @subject: The subject to become an authentication agent for, typically a #PolkitUnixSession object. * @object_path: The D-Bus object path to use for the authentication agent or %NULL for the default object path. + * @options: (allow-none): A #GVariant with options or %NULL. * @cancellable: A #GCancellable or %NULL. * @error: Return location for error. * - * Registers @listener with the PolicyKit daemon as an authentication - * agent for @subject. This is implemented by registering a D-Bus - * object at @object_path on the unique name assigned by the system - * message bus. - * - * Whenever the PolicyKit daemon needs to authenticate a processes - * that is related to @subject, the methods - * polkit_agent_listener_initiate_authentication() and - * polkit_agent_listener_initiate_authentication_finish() will be - * invoked on @listener. - * - * Note that registration of an authentication agent can fail; for - * example another authentication agent may already be registered for - * @subject. - * - * Note that the calling thread is blocked until a reply is received. + * Like polkit_agent_listener_register() but takes options to influence registration. See the + * <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgentWithOptions">RegisterAuthenticationAgentWithOptions()</link> D-Bus method for details. * * Returns: (transfer full): %NULL if @error is set, otherwise a * registration handle that can be used with * polkit_agent_listener_unregister(). */ gpointer -polkit_agent_listener_register (PolkitAgentListener *listener, - PolkitAgentRegisterFlags flags, - PolkitSubject *subject, - const gchar *object_path, - GCancellable *cancellable, - GError **error) +polkit_agent_listener_register_with_options (PolkitAgentListener *listener, + PolkitAgentRegisterFlags flags, + PolkitSubject *subject, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GError **error) { Server *server; GDBusNodeInfo *node_info; @@ -425,6 +420,8 @@ polkit_agent_listener_register (PolkitAgentListener *listener, server->listener = g_object_ref (listener); + server->registration_options = options != NULL ? g_variant_ref_sink (options) : NULL; + if (flags & POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD) { server->thread = g_thread_create (server_thread_func, @@ -472,6 +469,47 @@ polkit_agent_listener_register (PolkitAgentListener *listener, } /** + * polkit_agent_listener_register: + * @listener: A #PolkitAgentListener. + * @flags: A set of flags from the #PolkitAgentRegisterFlags enumeration. + * @subject: The subject to become an authentication agent for, typically a #PolkitUnixSession object. + * @object_path: The D-Bus object path to use for the authentication agent or %NULL for the default object path. + * @cancellable: A #GCancellable or %NULL. + * @error: Return location for error. + * + * Registers @listener with the PolicyKit daemon as an authentication + * agent for @subject. This is implemented by registering a D-Bus + * object at @object_path on the unique name assigned by the system + * message bus. + * + * Whenever the PolicyKit daemon needs to authenticate a processes + * that is related to @subject, the methods + * polkit_agent_listener_initiate_authentication() and + * polkit_agent_listener_initiate_authentication_finish() will be + * invoked on @listener. + * + * Note that registration of an authentication agent can fail; for + * example another authentication agent may already be registered for + * @subject. + * + * Note that the calling thread is blocked until a reply is received. + * + * Returns: (transfer full): %NULL if @error is set, otherwise a + * registration handle that can be used with + * polkit_agent_listener_unregister(). + */ +gpointer +polkit_agent_listener_register (PolkitAgentListener *listener, + PolkitAgentRegisterFlags flags, + PolkitSubject *subject, + const gchar *object_path, + GCancellable *cancellable, + GError **error) +{ + return polkit_agent_listener_register_with_options (listener, flags, subject, object_path, NULL, cancellable, error); +} + +/** * polkit_agent_listener_unregister: * @registration_handle: A handle obtained from polkit_agent_listener_register(). * diff --git a/src/polkitagent/polkitagentlistener.h b/src/polkitagent/polkitagentlistener.h index 191b265..c3cbcfb 100644 --- a/src/polkitagent/polkitagentlistener.h +++ b/src/polkitagent/polkitagentlistener.h @@ -134,6 +134,14 @@ gpointer polkit_agent_listener_register (PolkitAgentList GCancellable *cancellable, GError **error); +gpointer polkit_agent_listener_register_with_options (PolkitAgentListener *listener, + PolkitAgentRegisterFlags flags, + PolkitSubject *subject, + const gchar *object_path, + GVariant *options, + GCancellable *cancellable, + GError **error); + void polkit_agent_listener_unregister (gpointer registration_handle); G_END_DECLS diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c index 44b7493..fd4f161 100644 --- a/src/polkitbackend/polkitbackendauthority.c +++ b/src/polkitbackend/polkitbackendauthority.c @@ -268,6 +268,7 @@ polkit_backend_authority_check_authorization_finish (PolkitBackendAuthority *au * @subject: The subject the authentication agent wants to register for. * @locale: The locale of the authentication agent. * @object_path: The object path for the authentication agent. + * @options: A #GVariant with options or %NULL. * @error: Return location for error or %NULL. * * Registers an authentication agent. @@ -280,6 +281,7 @@ polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority PolkitSubject *subject, const gchar *locale, const gchar *object_path, + GVariant *options, GError **error) { PolkitBackendAuthorityClass *klass; @@ -296,7 +298,7 @@ polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority } else { - return klass->register_authentication_agent (authority, caller, subject, locale, object_path, error); + return klass->register_authentication_agent (authority, caller, subject, locale, object_path, options, error); } } @@ -571,6 +573,12 @@ static const gchar *server_introspection_data = " <arg type='s' name='locale' direction='in'/>" " <arg type='s' name='object_path' direction='in'/>" " </method>" + " <method name='RegisterAuthenticationAgentWithOptions'>" + " <arg type='(sa{sv})' name='subject' direction='in'/>" + " <arg type='s' name='locale' direction='in'/>" + " <arg type='s' name='object_path' direction='in'/>" + " <arg type='a{sv}' name='options' direction='in'/>" + " </method>" " <method name='UnregisterAuthenticationAgent'>" " <arg type='(sa{sv})' name='subject' direction='in'/>" " <arg type='s' name='object_path' direction='in'/>" @@ -873,6 +881,62 @@ server_handle_register_authentication_agent (Server *server, subject, locale, object_path, + NULL, + &error)) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + goto out; + } + + g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); + + out: + if (subject != NULL) + g_object_unref (subject); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +server_handle_register_authentication_agent_with_options (Server *server, + GVariant *parameters, + PolkitSubject *caller, + GDBusMethodInvocation *invocation) +{ + GVariant *subject_gvariant; + GError *error; + PolkitSubject *subject; + const gchar *locale; + const gchar *object_path; + GVariant *options; + + subject = NULL; + + g_variant_get (parameters, + "(@(sa{sv})&s&s@a{sv})", + &subject_gvariant, + &locale, + &object_path, + &options); + + error = NULL; + subject = polkit_subject_new_for_gvariant (subject_gvariant, &error); + if (subject == NULL) + { + g_prefix_error (&error, "Error getting subject: "); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + goto out; + } + + error = NULL; + if (!polkit_backend_authority_register_authentication_agent (server->authority, + caller, + subject, + locale, + object_path, + options, &error)) { g_dbus_method_invocation_return_gerror (invocation, error); @@ -883,6 +947,8 @@ server_handle_register_authentication_agent (Server *server, g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); out: + if (options != NULL) + g_variant_unref (options); if (subject != NULL) g_object_unref (subject); } @@ -1150,6 +1216,8 @@ server_handle_method_call (GDBusConnection *connection, server_handle_cancel_check_authorization (server, parameters, caller, invocation); else if (g_strcmp0 (method_name, "RegisterAuthenticationAgent") == 0) server_handle_register_authentication_agent (server, parameters, caller, invocation); + else if (g_strcmp0 (method_name, "RegisterAuthenticationAgentWithOptions") == 0) + server_handle_register_authentication_agent_with_options (server, parameters, caller, invocation); else if (g_strcmp0 (method_name, "UnregisterAuthenticationAgent") == 0) server_handle_unregister_authentication_agent (server, parameters, caller, invocation); else if (g_strcmp0 (method_name, "AuthenticationAgentResponse") == 0) diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h index bfc0480..a564054 100644 --- a/src/polkitbackend/polkitbackendauthority.h +++ b/src/polkitbackend/polkitbackendauthority.h @@ -143,6 +143,7 @@ struct _PolkitBackendAuthorityClass PolkitSubject *subject, const gchar *locale, const gchar *object_path, + GVariant *options, GError **error); gboolean (*unregister_authentication_agent) (PolkitBackendAuthority *authority, @@ -244,6 +245,7 @@ gboolean polkit_backend_authority_register_authentication_agent (PolkitBackendAu PolkitSubject *subject, const gchar *locale, const gchar *object_path, + GVariant *options, GError **error); gboolean polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index f523782..b237e9d 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -156,6 +156,7 @@ static gboolean polkit_backend_interactive_authority_register_authentication_age PolkitSubject *subject, const gchar *locale, const gchar *object_path, + GVariant *options, GError **error); static gboolean polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, @@ -431,6 +432,7 @@ struct AuthenticationAgent PolkitSubject *scope; gchar *locale; + GVariant *registration_options; gchar *object_path; gchar *unique_system_bus_name; @@ -1541,11 +1543,12 @@ authentication_agent_unref (AuthenticationAgent *agent) { if (agent->proxy != NULL) g_object_unref (agent->proxy); - g_object_unref (agent->scope); g_free (agent->locale); g_free (agent->object_path); g_free (agent->unique_system_bus_name); + if (agent->registration_options != NULL) + g_variant_unref (agent->registration_options); g_free (agent); } } @@ -1554,7 +1557,8 @@ static AuthenticationAgent * authentication_agent_new (PolkitSubject *scope, const gchar *unique_system_bus_name, const gchar *locale, - const gchar *object_path) + const gchar *object_path, + GVariant *registration_options) { AuthenticationAgent *agent; GError *error; @@ -1566,6 +1570,7 @@ authentication_agent_new (PolkitSubject *scope, agent->object_path = g_strdup (object_path); agent->unique_system_bus_name = g_strdup (unique_system_bus_name); agent->locale = g_strdup (locale); + agent->registration_options = registration_options != NULL ? g_variant_ref (registration_options) : NULL; error = NULL; agent->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, @@ -1592,19 +1597,16 @@ get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authori PolkitSubject *subject) { PolkitBackendInteractiveAuthorityPrivate *priv; - PolkitSubject *session_for_subject; - AuthenticationAgent *agent; + PolkitSubject *session_for_subject = NULL; + AuthenticationAgent *agent = NULL; + AuthenticationAgent *agent_fallback = NULL; + gboolean fallback = FALSE; priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority); - agent = NULL; - session_for_subject = NULL; - agent = g_hash_table_lookup (priv->hash_scope_to_authentication_agent, subject); - if (agent != NULL) - goto out; - if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + if (agent == NULL && POLKIT_IS_SYSTEM_BUS_NAME (subject)) { PolkitSubject *process; process = polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), @@ -1613,15 +1615,27 @@ get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authori if (process != NULL) { agent = g_hash_table_lookup (priv->hash_scope_to_authentication_agent, process); - if (agent != NULL) - { - g_object_unref (process); - goto out; - } g_object_unref (process); } } + if (agent != NULL) + { + /* We have an agent! Now see if we should use this as a fallback only */ + if (agent->registration_options != NULL && + g_variant_lookup (agent->registration_options, "fallback", "b", &fallback) && + fallback) + { + agent_fallback = agent; + agent = NULL; + } + else + { + /* Nope, use it */ + goto out; + } + } + /* Now, we should also cover the case where @subject is a * UnixProcess but the agent is a SystemBusName. However, this can't * happen because we only allow registering agents for UnixProcess @@ -1636,6 +1650,10 @@ get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authori agent = g_hash_table_lookup (priv->hash_scope_to_authentication_agent, session_for_subject); + /* use fallback, if available */ + if (agent == NULL && agent_fallback != NULL) + agent = agent_fallback; + out: if (session_for_subject != NULL) g_object_unref (session_for_subject); @@ -2194,6 +2212,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken PolkitSubject *subject, const gchar *locale, const gchar *object_path, + GVariant *options, GError **error) { PolkitBackendInteractiveAuthority *interactive_authority; @@ -2302,7 +2321,8 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken agent = authentication_agent_new (subject, polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), locale, - object_path); + object_path, + options); g_hash_table_insert (priv->hash_scope_to_authentication_agent, g_object_ref (subject), diff --git a/src/programs/pkttyagent.c b/src/programs/pkttyagent.c index 1c170f4..488ca8b 100644 --- a/src/programs/pkttyagent.c +++ b/src/programs/pkttyagent.c @@ -52,15 +52,18 @@ main (int argc, char *argv[]) { gboolean opt_show_help = FALSE; gboolean opt_show_version = FALSE; + gboolean opt_fallback = FALSE; PolkitAuthority *authority = NULL; PolkitSubject *subject = NULL; gpointer local_agent_handle = NULL; PolkitAgentListener *listener = NULL; + GVariant *options = NULL; GError *error; GMainLoop *loop = NULL; guint n; guint ret = 126; gint notify_fd = -1; + GVariantBuilder builder; g_type_init (); @@ -74,6 +77,10 @@ main (int argc, char *argv[]) { opt_show_version = TRUE; } + else if (g_strcmp0 (argv[n], "--fallback") == 0) + { + opt_fallback = TRUE; + } else if (g_strcmp0 (argv[n], "--notify-fd") == 0) { n++; @@ -180,6 +187,13 @@ main (int argc, char *argv[]) goto out; } + if (opt_fallback) + { + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", "fallback", g_variant_new_boolean (TRUE)); + options = g_variant_builder_end (&builder); + } + error = NULL; /* this will fail if we can't find a controlling terminal */ listener = polkit_agent_text_listener_new (NULL, &error); @@ -191,12 +205,14 @@ main (int argc, char *argv[]) ret = 127; goto out; } - local_agent_handle = polkit_agent_listener_register (listener, - POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD, - subject, - NULL, /* object_path */ - NULL, /* GCancellable */ - &error); + local_agent_handle = polkit_agent_listener_register_with_options (listener, + POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD, + subject, + NULL, /* object_path */ + options, + NULL, /* GCancellable */ + &error); + options = NULL; /* consumed */ g_object_unref (listener); if (local_agent_handle == NULL) { @@ -225,6 +241,9 @@ main (int argc, char *argv[]) if (local_agent_handle != NULL) polkit_agent_listener_unregister (local_agent_handle); + if (options != NULL) + g_variant_unref (options); + if (subject != NULL) g_object_unref (subject); |