1 /*
2  * Copyright (C) 2008 Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: David Zeuthen <davidz@redhat.com>
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25 
26 #include "polkitauthorizationresult.h"
27 #include "polkitcheckauthorizationflags.h"
28 #include "polkitauthority.h"
29 #include "polkiterror.h"
30 #include "polkitenumtypes.h"
31 #include "polkitsubject.h"
32 #include "polkitidentity.h"
33 #include "polkitdetails.h"
34 
35 #include "polkitprivate.h"
36 
37 /**
38  * SECTION:polkitauthority
39  * @title: PolkitAuthority
40  * @short_description: Authority
41  * @stability: Stable
42  *
43  * #PolkitAuthority is used for checking whether a given subject is
44  * authorized to perform a given action. Typically privileged system
45  * daemons or suid helpers will use this when handling requests from
46  * untrusted clients.
47  *
48  * User sessions can register an authentication agent with the
49  * authority. This is used for requests from untrusted clients where
50  * system policy requires that the user needs to acknowledge (through
51  * proving he is the user or the administrator) a given action. See
52  * #PolkitAgentListener and #PolkitAgentSession for details.
53  */
54 
55 /**
56  * PolkitAuthority:
57  *
58  * The #PolkitAuthority struct should not be accessed directly.
59  */
60 struct _PolkitAuthority
61 {
62   /*< private >*/
63   GObject parent_instance;
64 
65   gchar *name;
66   gchar *version;
67 
68   GDBusProxy *proxy;
69   guint cancellation_id_counter;
70 
71   gboolean initialized;
72   GError *initialization_error;
73 };
74 
75 struct _PolkitAuthorityClass
76 {
77   GObjectClass parent_class;
78 
79 };
80 
81 G_LOCK_DEFINE_STATIC (the_lock);
82 static PolkitAuthority *the_authority = NULL;
83 
84 enum
85 {
86   CHANGED_SIGNAL,
87   LAST_SIGNAL,
88 };
89 
90 enum
91 {
92   PROP_0,
93   PROP_OWNER,
94   PROP_BACKEND_NAME,
95   PROP_BACKEND_VERSION,
96   PROP_BACKEND_FEATURES
97 };
98 
99 static guint signals[LAST_SIGNAL] = {0};
100 
101 static void initable_iface_init       (GInitableIface *initable_iface);
102 static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
103 
G_DEFINE_TYPE_WITH_CODE(PolkitAuthority,polkit_authority,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,initable_iface_init)G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,async_initable_iface_init))104 G_DEFINE_TYPE_WITH_CODE (PolkitAuthority, polkit_authority, G_TYPE_OBJECT,
105                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
106                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init))
107 
108 static void
109 on_proxy_signal (GDBusProxy   *proxy,
110                  const gchar  *sender_name,
111                  const gchar  *signal_name,
112                  GVariant     *parameters,
113                  gpointer      user_data)
114 {
115   PolkitAuthority *authority = POLKIT_AUTHORITY (user_data);
116   if (g_strcmp0 (signal_name, "Changed") == 0)
117     {
118       g_signal_emit_by_name (authority, "changed");
119     }
120 }
121 
122 static void
on_notify_g_name_owner(GObject * object,GParamSpec * ppsec,gpointer user_data)123 on_notify_g_name_owner (GObject    *object,
124                         GParamSpec *ppsec,
125                         gpointer    user_data)
126 {
127   PolkitAuthority *authority = POLKIT_AUTHORITY (user_data);
128   g_object_notify (G_OBJECT (authority), "owner");
129 }
130 
131 static void
polkit_authority_init(PolkitAuthority * authority)132 polkit_authority_init (PolkitAuthority *authority)
133 {
134 }
135 
136 static void
polkit_authority_dispose(GObject * object)137 polkit_authority_dispose (GObject *object)
138 {
139   PolkitAuthority *authority = POLKIT_AUTHORITY (object);
140 
141   G_LOCK (the_lock);
142   if (authority == the_authority)
143     the_authority = NULL;
144   G_UNLOCK (the_lock);
145 
146   if (G_OBJECT_CLASS (polkit_authority_parent_class)->dispose != NULL)
147     G_OBJECT_CLASS (polkit_authority_parent_class)->dispose (object);
148 }
149 
150 static void
polkit_authority_finalize(GObject * object)151 polkit_authority_finalize (GObject *object)
152 {
153   PolkitAuthority *authority = POLKIT_AUTHORITY (object);
154 
155   if (authority->initialization_error != NULL)
156     g_error_free (authority->initialization_error);
157 
158   g_free (authority->name);
159   g_free (authority->version);
160   if (authority->proxy != NULL)
161     g_object_unref (authority->proxy);
162 
163   if (G_OBJECT_CLASS (polkit_authority_parent_class)->finalize != NULL)
164     G_OBJECT_CLASS (polkit_authority_parent_class)->finalize (object);
165 }
166 
167 static void
polkit_authority_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)168 polkit_authority_get_property (GObject    *object,
169                                guint       prop_id,
170                                GValue     *value,
171                                GParamSpec *pspec)
172 {
173   PolkitAuthority *authority = POLKIT_AUTHORITY (object);
174 
175   switch (prop_id)
176     {
177     case PROP_OWNER:
178       g_value_take_string (value, polkit_authority_get_owner (authority));
179       break;
180 
181     case PROP_BACKEND_NAME:
182       g_value_set_string (value, polkit_authority_get_backend_name (authority));
183       break;
184 
185     case PROP_BACKEND_VERSION:
186       g_value_set_string (value, polkit_authority_get_backend_version (authority));
187       break;
188 
189     case PROP_BACKEND_FEATURES:
190       g_value_set_flags (value, polkit_authority_get_backend_features (authority));
191       break;
192 
193     default:
194       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
195       break;
196     }
197 }
198 
199 static void
polkit_authority_class_init(PolkitAuthorityClass * klass)200 polkit_authority_class_init (PolkitAuthorityClass *klass)
201 {
202   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
203 
204   gobject_class->dispose      = polkit_authority_dispose;
205   gobject_class->finalize     = polkit_authority_finalize;
206   gobject_class->get_property = polkit_authority_get_property;
207 
208   /**
209    * PolkitAuthority:owner:
210    *
211    * The unique name of the owner of the org.freedesktop.PolicyKit1
212    * D-Bus service or %NULL if there is no owner. Connect to the
213    * #GObject::notify signal to track changes to this property.
214    */
215   g_object_class_install_property (gobject_class,
216                                    PROP_OWNER,
217                                    g_param_spec_string ("owner",
218                                                         "Owner",
219                                                         "Owner.",
220                                                         NULL,
221                                                         G_PARAM_READABLE |
222                                                         G_PARAM_STATIC_NAME |
223                                                         G_PARAM_STATIC_NICK |
224                                                         G_PARAM_STATIC_BLURB));
225 
226   /**
227    * PolkitAuthority:backend-name:
228    *
229    * The name of the currently used Authority backend.
230    */
231   g_object_class_install_property (gobject_class,
232                                    PROP_BACKEND_NAME,
233                                    g_param_spec_string ("backend-name",
234                                                         "Backend name",
235                                                         "The name of the currently used Authority backend.",
236                                                         NULL,
237                                                         G_PARAM_READABLE |
238                                                         G_PARAM_STATIC_NAME |
239                                                         G_PARAM_STATIC_NICK |
240                                                         G_PARAM_STATIC_BLURB));
241 
242   /**
243    * PolkitAuthority:version:
244    *
245    * The version of the currently used Authority backend.
246    */
247   g_object_class_install_property (gobject_class,
248                                    PROP_BACKEND_VERSION,
249                                    g_param_spec_string ("backend-version",
250                                                         "Backend version",
251                                                         "The version of the currently used Authority backend.",
252                                                         NULL,
253                                                         G_PARAM_READABLE |
254                                                         G_PARAM_STATIC_NAME |
255                                                         G_PARAM_STATIC_NICK |
256                                                         G_PARAM_STATIC_BLURB));
257 
258   /**
259    * PolkitAuthority:backend-features:
260    *
261    * The features of the currently used Authority backend.
262    */
263   g_object_class_install_property (gobject_class,
264                                    PROP_BACKEND_FEATURES,
265                                    g_param_spec_flags ("backend-features",
266                                                        "Backend features",
267                                                        "The features of the currently used Authority backend.",
268                                                        POLKIT_TYPE_AUTHORITY_FEATURES,
269                                                        POLKIT_AUTHORITY_FEATURES_NONE,
270                                                        G_PARAM_READABLE |
271                                                        G_PARAM_STATIC_NAME |
272                                                        G_PARAM_STATIC_NICK |
273                                                        G_PARAM_STATIC_BLURB));
274 
275   /**
276    * PolkitAuthority::changed:
277    * @authority: A #PolkitAuthority.
278    *
279    * Emitted when actions and/or authorizations change
280    */
281   signals[CHANGED_SIGNAL] = g_signal_new ("changed",
282                                           POLKIT_TYPE_AUTHORITY,
283                                           G_SIGNAL_RUN_LAST,
284                                           0,                      /* class offset     */
285                                           NULL,                   /* accumulator      */
286                                           NULL,                   /* accumulator data */
287                                           g_cclosure_marshal_VOID__VOID,
288                                           G_TYPE_NONE,
289                                           0);
290 }
291 
292 /* ---------------------------------------------------------------------------------------------------- */
293 
294 static gboolean
polkit_authority_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)295 polkit_authority_initable_init (GInitable     *initable,
296                                 GCancellable  *cancellable,
297                                 GError       **error)
298 {
299   PolkitAuthority *authority = POLKIT_AUTHORITY (initable);
300   gboolean ret;
301 
302   /* This method needs to be idempotent to work with the singleton
303    * pattern. See the docs for g_initable_init(). We implement this by
304    * locking.
305    */
306 
307   ret = FALSE;
308 
309   G_LOCK (the_lock);
310   if (authority->initialized)
311     {
312       if (authority->initialization_error == NULL)
313         ret = TRUE;
314       goto out;
315     }
316 
317   authority->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
318                                                     G_DBUS_PROXY_FLAGS_NONE,
319                                                     NULL, /* TODO: pass GDBusInterfaceInfo* */
320                                                     "org.freedesktop.PolicyKit1",            /* name */
321                                                     "/org/freedesktop/PolicyKit1/Authority", /* path */
322                                                     "org.freedesktop.PolicyKit1.Authority",  /* interface */
323                                                     cancellable,
324                                                     &authority->initialization_error);
325   if (authority->proxy == NULL)
326     {
327       g_prefix_error (&authority->initialization_error, "Error initializing authority: ");
328       goto out;
329     }
330   g_signal_connect (authority->proxy,
331                     "g-signal",
332                     G_CALLBACK (on_proxy_signal),
333                     authority);
334   g_signal_connect (authority->proxy,
335                     "notify::g-name-owner",
336                     G_CALLBACK (on_notify_g_name_owner),
337                     authority);
338 
339   ret = TRUE;
340 
341  out:
342   authority->initialized = TRUE;
343 
344   if (!ret)
345     {
346       g_assert (authority->initialization_error != NULL);
347       g_propagate_error (error, g_error_copy (authority->initialization_error));
348     }
349   G_UNLOCK (the_lock);
350   return ret;
351 }
352 
353 /* ---------------------------------------------------------------------------------------------------- */
354 
355 static void
initable_iface_init(GInitableIface * initable_iface)356 initable_iface_init (GInitableIface *initable_iface)
357 {
358   initable_iface->init = polkit_authority_initable_init;
359 }
360 
361 static void
async_initable_iface_init(GAsyncInitableIface * async_initable_iface)362 async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
363 {
364   /* for now, we use default implementation to run GInitable code in a
365    * thread - would probably be nice to have real async version to
366    * avoid the thread-overhead
367    */
368 }
369 
370 /* ---------------------------------------------------------------------------------------------------- */
371 
372 /* deprecated, see polkitauthority.h */
373 
374 /**
375  * polkit_authority_get:
376  *
377  * (deprecated)
378  *
379  * Returns: (transfer full): value
380  */
381 PolkitAuthority *
polkit_authority_get(void)382 polkit_authority_get (void)
383 {
384   GError *error;
385   PolkitAuthority *ret;
386 
387   error = NULL;
388   ret = polkit_authority_get_sync (NULL, /* GCancellable* */
389                                    &error);
390   if (ret == NULL)
391     {
392       g_warning ("polkit_authority_get: Error getting authority: %s",
393                  error->message);
394       g_error_free (error);
395     }
396 
397   return ret;
398 }
399 
400 /* ---------------------------------------------------------------------------------------------------- */
401 
402 static PolkitAuthority *
get_uninitialized_authority(GCancellable * cancellable,GError ** error)403 get_uninitialized_authority (GCancellable *cancellable,
404                              GError       **error)
405 {
406   static volatile GQuark error_quark = 0;
407 
408   G_LOCK (the_lock);
409   if (error_quark == 0)
410     error_quark = POLKIT_ERROR;
411 
412   if (the_authority != NULL)
413     {
414       g_object_ref (the_authority);
415       goto out;
416     }
417   the_authority = POLKIT_AUTHORITY (g_object_new (POLKIT_TYPE_AUTHORITY, NULL));
418  out:
419   G_UNLOCK (the_lock);
420   return the_authority;
421 }
422 
423 static void
authority_get_async_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)424 authority_get_async_cb (GObject      *source_object,
425                         GAsyncResult *res,
426                         gpointer      user_data)
427 {
428   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
429   GError *error;
430 
431   error = NULL;
432   if (!g_async_initable_init_finish (G_ASYNC_INITABLE (source_object),
433                                      res,
434                                      &error))
435     {
436       g_assert (error != NULL);
437       g_simple_async_result_set_from_error (simple, error);
438       g_error_free (error);
439       g_object_unref (source_object);
440     }
441   else
442     {
443       g_simple_async_result_set_op_res_gpointer (simple,
444                                                  source_object,
445                                                  g_object_unref);
446     }
447   g_simple_async_result_complete_in_idle (simple);
448   g_object_unref (simple);
449 }
450 
451 /**
452  * polkit_authority_get_async:
453  * @cancellable: (allow-none): A #GCancellable or %NULL.
454  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
455  * @user_data: The data to pass to @callback.
456  *
457  * Asynchronously gets a reference to the authority.
458  *
459  * This is an asynchronous failable function. When the result is
460  * ready, @callback will be invoked in the <link
461  * linkend="g-main-context-push-thread-default">thread-default main
462  * loop</link> of the thread you are calling this method from and you
463  * can use polkit_authority_get_finish() to get the result. See
464  * polkit_authority_get_sync() for the synchronous version.
465  */
466 void
polkit_authority_get_async(GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)467 polkit_authority_get_async  (GCancellable        *cancellable,
468                              GAsyncReadyCallback  callback,
469                              gpointer             user_data)
470 {
471   PolkitAuthority *authority;
472   GSimpleAsyncResult *simple;
473   GError *error;
474 
475   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
476 
477   simple = g_simple_async_result_new (NULL,
478                                       callback,
479                                       user_data,
480                                       polkit_authority_get_async);
481 
482   error = NULL;
483   authority = get_uninitialized_authority (cancellable, &error);
484   if (authority == NULL)
485     {
486       g_assert (error != NULL);
487       g_simple_async_result_set_from_error (simple, error);
488       g_error_free (error);
489       g_simple_async_result_complete_in_idle (simple);
490       g_object_unref (simple);
491     }
492   else
493     {
494       g_async_initable_init_async (G_ASYNC_INITABLE (authority),
495                                    G_PRIORITY_DEFAULT,
496                                    cancellable,
497                                    authority_get_async_cb,
498                                    simple);
499     }
500 }
501 
502 /**
503  * polkit_authority_get_finish:
504  * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to polkit_authority_get_async().
505  * @error: (allow-none): Return location for error or %NULL.
506  *
507  * Finishes an operation started with polkit_authority_get_async().
508  *
509  * Returns: (transfer full): A #PolkitAuthority. Free it with
510  * g_object_unref() when done with it.
511  */
512 PolkitAuthority *
polkit_authority_get_finish(GAsyncResult * res,GError ** error)513 polkit_authority_get_finish (GAsyncResult        *res,
514                              GError             **error)
515 {
516   GSimpleAsyncResult *simple;
517   GObject *object;
518   PolkitAuthority *ret;
519 
520   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
521   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
522 
523   simple = G_SIMPLE_ASYNC_RESULT (res);
524 
525   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_get_async);
526 
527   ret = NULL;
528 
529   if (g_simple_async_result_propagate_error (simple, error))
530     goto out;
531 
532   object = g_simple_async_result_get_op_res_gpointer (simple);
533   g_assert (object != NULL);
534   ret = g_object_ref (POLKIT_AUTHORITY (object));
535 
536  out:
537   return ret;
538 }
539 
540 /**
541  * polkit_authority_get_sync:
542  * @cancellable: (allow-none): A #GCancellable or %NULL.
543  * @error: (allow-none): Return location for error or %NULL.
544  *
545  * Synchronously gets a reference to the authority.
546  *
547  * This is a synchronous failable function - the calling thread is
548  * blocked until a reply is received. See polkit_authority_get_async()
549  * for the asynchronous version.
550  *
551  * Returns: (transfer full): A #PolkitAuthority. Free it with
552  * g_object_unref() when done with it.
553  */
554 PolkitAuthority *
polkit_authority_get_sync(GCancellable * cancellable,GError ** error)555 polkit_authority_get_sync (GCancellable        *cancellable,
556                            GError             **error)
557 {
558   PolkitAuthority *authority;
559 
560   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
561   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
562 
563   authority = get_uninitialized_authority (cancellable, error);
564   if (authority == NULL)
565     goto out;
566 
567   if (!g_initable_init (G_INITABLE (authority), cancellable, error))
568     {
569       g_object_unref (authority);
570       authority = NULL;
571     }
572 
573  out:
574   return authority;
575 }
576 
577 /* ---------------------------------------------------------------------------------------------------- */
578 
579 typedef struct
580 {
581   GAsyncResult *res;
582   GMainContext *context;
583   GMainLoop *loop;
584 } CallSyncData;
585 
586 static CallSyncData *
call_sync_new(void)587 call_sync_new (void)
588 {
589   CallSyncData *data;
590   data = g_new0 (CallSyncData, 1);
591   data->context = g_main_context_new ();
592   data->loop = g_main_loop_new (data->context, FALSE);
593   g_main_context_push_thread_default (data->context);
594   return data;
595 }
596 
597 static void
call_sync_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)598 call_sync_cb (GObject      *source_object,
599               GAsyncResult *res,
600               gpointer      user_data)
601 {
602   CallSyncData *data = user_data;
603   data->res = g_object_ref (res);
604   g_main_loop_quit (data->loop);
605 }
606 
607 static void
call_sync_block(CallSyncData * data)608 call_sync_block (CallSyncData *data)
609 {
610   g_main_loop_run (data->loop);
611 }
612 
613 static void
call_sync_free(CallSyncData * data)614 call_sync_free (CallSyncData *data)
615 {
616   g_main_context_pop_thread_default (data->context);
617   g_main_context_unref (data->context);
618   g_main_loop_unref (data->loop);
619   g_object_unref (data->res);
620   g_free (data);
621 }
622 
623 /* ---------------------------------------------------------------------------------------------------- */
624 
625 static void
generic_async_cb(GObject * source_obj,GAsyncResult * res,gpointer user_data)626 generic_async_cb (GObject      *source_obj,
627                   GAsyncResult *res,
628                   gpointer      user_data)
629 {
630   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
631   g_simple_async_result_set_op_res_gpointer (simple, g_object_ref (res), g_object_unref);
632   g_simple_async_result_complete (simple);
633   g_object_unref (simple);
634 }
635 
636 /* ---------------------------------------------------------------------------------------------------- */
637 
638 /**
639  * polkit_authority_enumerate_actions:
640  * @authority: A #PolkitAuthority.
641  * @cancellable: (allow-none): A #GCancellable or %NULL.
642  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
643  * @user_data: The data to pass to @callback.
644  *
645  * Asynchronously retrieves all registered actions.
646  *
647  * When the operation is finished, @callback will be invoked in the
648  * <link linkend="g-main-context-push-thread-default">thread-default
649  * main loop</link> of the thread you are calling this method
650  * from. You can then call polkit_authority_enumerate_actions_finish()
651  * to get the result of the operation.
652  **/
653 void
polkit_authority_enumerate_actions(PolkitAuthority * authority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)654 polkit_authority_enumerate_actions (PolkitAuthority     *authority,
655                                     GCancellable        *cancellable,
656                                     GAsyncReadyCallback  callback,
657                                     gpointer             user_data)
658 {
659   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
660   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
661   g_dbus_proxy_call (authority->proxy,
662                      "EnumerateActions",
663                      g_variant_new ("(s)",
664                                     ""), /* TODO: use system locale */
665                      G_DBUS_CALL_FLAGS_NONE,
666                      -1,
667                      cancellable,
668                      generic_async_cb,
669                      g_simple_async_result_new (G_OBJECT (authority),
670                                                 callback,
671                                                 user_data,
672                                                 polkit_authority_enumerate_actions));
673 }
674 
675 /**
676  * polkit_authority_enumerate_actions_finish:
677  * @authority: A #PolkitAuthority.
678  * @res: A #GAsyncResult obtained from the callback.
679  * @error: (allow-none): Return location for error or %NULL.
680  *
681  * Finishes retrieving all registered actions.
682  *
683  * Returns: (element-type Polkit.ActionDescription) (transfer full): A list of
684  * #PolkitActionDescription objects or %NULL if @error is set. The returned
685  * list should be freed with g_list_free() after each element have been freed
686  * with g_object_unref().
687  **/
688 GList *
polkit_authority_enumerate_actions_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)689 polkit_authority_enumerate_actions_finish (PolkitAuthority *authority,
690                                            GAsyncResult    *res,
691                                            GError         **error)
692 {
693   GList *ret;
694   GVariant *value;
695   GVariantIter iter;
696   GVariant *child;
697   GVariant *array;
698   GAsyncResult *_res;
699 
700   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
701   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
702   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
703 
704   ret = NULL;
705 
706   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_enumerate_actions);
707   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
708 
709   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
710   if (value == NULL)
711     goto out;
712 
713   array = g_variant_get_child_value (value, 0);
714   g_variant_iter_init (&iter, array);
715   while ((child = g_variant_iter_next_value (&iter)) != NULL)
716     {
717       ret = g_list_prepend (ret, polkit_action_description_new_for_gvariant (child));
718       g_variant_unref (child);
719     }
720   ret = g_list_reverse (ret);
721   g_variant_unref (array);
722   g_variant_unref (value);
723 
724  out:
725   return ret;
726 }
727 
728 /**
729  * polkit_authority_enumerate_actions_sync:
730  * @authority: A #PolkitAuthority.
731  * @cancellable: (allow-none): A #GCancellable or %NULL.
732  * @error: (allow-none): Return location for error or %NULL.
733  *
734  * Synchronously retrieves all registered actions - the calling thread
735  * is blocked until a reply is received. See
736  * polkit_authority_enumerate_actions() for the asynchronous version.
737  *
738  * Returns: (element-type Polkit.ActionDescription) (transfer full): A list of
739  * #PolkitActionDescription or %NULL if @error is set. The returned list should
740  * be freed with g_list_free() after each element have been freed with
741  * g_object_unref().
742  **/
743 GList *
polkit_authority_enumerate_actions_sync(PolkitAuthority * authority,GCancellable * cancellable,GError ** error)744 polkit_authority_enumerate_actions_sync (PolkitAuthority *authority,
745                                          GCancellable    *cancellable,
746                                          GError         **error)
747 {
748   GList *ret;
749   CallSyncData *data;
750 
751   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
752   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
753   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
754 
755   data = call_sync_new ();
756   polkit_authority_enumerate_actions (authority, cancellable, call_sync_cb, data);
757   call_sync_block (data);
758   ret = polkit_authority_enumerate_actions_finish (authority, data->res, error);
759   call_sync_free (data);
760 
761   return ret;
762 }
763 
764 /* ---------------------------------------------------------------------------------------------------- */
765 
766 typedef struct
767 {
768   PolkitAuthority *authority;
769   GSimpleAsyncResult *simple;
770   gchar *cancellation_id;
771 } CheckAuthData;
772 
773 static void
cancel_check_authorization_cb(GDBusProxy * proxy,GAsyncResult * res,gpointer user_data)774 cancel_check_authorization_cb (GDBusProxy    *proxy,
775                                GAsyncResult  *res,
776                                gpointer       user_data)
777 {
778   GVariant *value;
779   GError *error;
780 
781   error = NULL;
782   value = g_dbus_proxy_call_finish (proxy, res, &error);
783   if (value == NULL)
784     {
785       g_warning ("Error cancelling authorization check: %s", error->message);
786       g_error_free (error);
787     }
788   else
789     {
790       g_variant_unref (value);
791     }
792 }
793 
794 static void
check_authorization_cb(GDBusProxy * proxy,GAsyncResult * res,gpointer user_data)795 check_authorization_cb (GDBusProxy    *proxy,
796                         GAsyncResult  *res,
797                         gpointer       user_data)
798 {
799   CheckAuthData *data = user_data;
800   GVariant *value;
801   GError *error;
802 
803   error = NULL;
804   value = g_dbus_proxy_call_finish (proxy, res, &error);
805   if (value == NULL)
806     {
807       if (data->cancellation_id != NULL &&
808           (!g_dbus_error_is_remote_error (error) &&
809            error->domain == G_IO_ERROR &&
810            error->code == G_IO_ERROR_CANCELLED))
811         {
812           g_dbus_proxy_call (data->authority->proxy,
813                              "CancelCheckAuthorization",
814                              g_variant_new ("(s)", data->cancellation_id),
815                              G_DBUS_CALL_FLAGS_NONE,
816                              -1,
817                              NULL, /* GCancellable */
818                              (GAsyncReadyCallback) cancel_check_authorization_cb,
819                              NULL);
820         }
821       g_simple_async_result_set_from_error (data->simple, error);
822       g_error_free (error);
823     }
824   else
825     {
826       GVariant *result_value;
827       PolkitAuthorizationResult *result;
828       result_value = g_variant_get_child_value (value, 0);
829       result = polkit_authorization_result_new_for_gvariant (result_value);
830       g_variant_unref (result_value);
831       g_variant_unref (value);
832       g_simple_async_result_set_op_res_gpointer (data->simple, result, g_object_unref);
833     }
834 
835   g_simple_async_result_complete (data->simple);
836 
837   g_object_unref (data->authority);
838   g_object_unref (data->simple);
839   g_free (data->cancellation_id);
840   g_free (data);
841 }
842 
843 /**
844  * polkit_authority_check_authorization:
845  * @authority: A #PolkitAuthority.
846  * @subject: A #PolkitSubject.
847  * @action_id: The action to check for.
848  * @details: (allow-none): Details about the action or %NULL.
849  * @flags: A set of #PolkitCheckAuthorizationFlags.
850  * @cancellable: (allow-none): A #GCancellable or %NULL.
851  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
852  * @user_data: The data to pass to @callback.
853  *
854  * Asynchronously checks if @subject is authorized to perform the action represented
855  * by @action_id.
856  *
857  * Note that %POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION
858  * <emphasis>SHOULD</emphasis> be passed <emphasis>ONLY</emphasis> if
859  * the event that triggered the authorization check is stemming from
860  * an user action, e.g. the user pressing a button or attaching a
861  * device.
862  *
863  * When the operation is finished, @callback will be invoked in the
864  * <link linkend="g-main-context-push-thread-default">thread-default
865  * main loop</link> of the thread you are calling this method
866  * from. You can then call
867  * polkit_authority_check_authorization_finish() to get the result of
868  * the operation.
869  *
870  * Known keys in @details include <literal>polkit.message</literal>
871  * and <literal>polkit.gettext_domain</literal> that can be used to
872  * override the message shown to the user. See the documentation for
873  * the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization">D-Bus method</link> for more details.
874  *
875  * If @details is non-empty then the request will fail with
876  * #POLKIT_ERROR_FAILED unless the process doing the check itsef is
877  * sufficiently authorized (e.g. running as uid 0).
878  **/
879 void
polkit_authority_check_authorization(PolkitAuthority * authority,PolkitSubject * subject,const gchar * action_id,PolkitDetails * details,PolkitCheckAuthorizationFlags flags,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)880 polkit_authority_check_authorization (PolkitAuthority               *authority,
881                                       PolkitSubject                 *subject,
882                                       const gchar                   *action_id,
883                                       PolkitDetails                 *details,
884                                       PolkitCheckAuthorizationFlags  flags,
885                                       GCancellable                  *cancellable,
886                                       GAsyncReadyCallback            callback,
887                                       gpointer                       user_data)
888 {
889   CheckAuthData *data;
890 
891   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
892   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
893   g_return_if_fail (action_id != NULL);
894   g_return_if_fail (details == NULL || POLKIT_IS_DETAILS (details));
895   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
896 
897   data = g_new0 (CheckAuthData, 1);
898   data->authority = g_object_ref (authority);
899   data->simple = g_simple_async_result_new (G_OBJECT (authority),
900                                             callback,
901                                             user_data,
902                                             polkit_authority_check_authorization);
903   G_LOCK (the_lock);
904   if (cancellable != NULL)
905     data->cancellation_id = g_strdup_printf ("cancellation-id-%d", authority->cancellation_id_counter++);
906   G_UNLOCK (the_lock);
907 
908   g_dbus_proxy_call (authority->proxy,
909                      "CheckAuthorization",
910                      g_variant_new ("(@(sa{sv})s@a{ss}us)",
911                                     polkit_subject_to_gvariant (subject), /* A floating value */
912                                     action_id,
913                                     polkit_details_to_gvariant (details), /* A floating value */
914                                     flags,
915                                     data->cancellation_id != NULL ? data->cancellation_id : ""),
916                      G_DBUS_CALL_FLAGS_NONE,
917                      G_MAXINT, /* no timeout */
918                      cancellable,
919                      (GAsyncReadyCallback) check_authorization_cb,
920                      data);
921 }
922 
923 /**
924  * polkit_authority_check_authorization_finish:
925  * @authority: A #PolkitAuthority.
926  * @res: A #GAsyncResult obtained from the callback.
927  * @error: (allow-none): Return location for error or %NULL.
928  *
929  * Finishes checking if a subject is authorized for an action.
930  *
931  * Returns: (transfer full): A #PolkitAuthorizationResult or %NULL if
932  * @error is set. Free with g_object_unref().
933  **/
934 PolkitAuthorizationResult *
polkit_authority_check_authorization_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)935 polkit_authority_check_authorization_finish (PolkitAuthority          *authority,
936                                              GAsyncResult             *res,
937                                              GError                  **error)
938 {
939   PolkitAuthorizationResult *ret;
940 
941   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
942   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
943   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
944 
945   ret = NULL;
946 
947   if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
948     goto out;
949 
950   ret = g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
951 
952  out:
953   return ret;
954 }
955 
956 /**
957  * polkit_authority_check_authorization_sync:
958  * @authority: A #PolkitAuthority.
959  * @subject: A #PolkitSubject.
960  * @action_id: The action to check for.
961  * @details: (allow-none): Details about the action or %NULL.
962  * @flags: A set of #PolkitCheckAuthorizationFlags.
963  * @cancellable: (allow-none): A #GCancellable or %NULL.
964  * @error: (allow-none): Return location for error or %NULL.
965  *
966  * Checks if @subject is authorized to perform the action represented
967  * by @action_id.
968  *
969  * Note that %POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION
970  * <emphasis>SHOULD</emphasis> be passed <emphasis>ONLY</emphasis> if
971  * the event that triggered the authorization check is stemming from
972  * an user action, e.g. the user pressing a button or attaching a
973  * device.
974  *
975  * Note the calling thread is blocked until a reply is received. You
976  * should therefore <emphasis>NEVER</emphasis> do this from a GUI
977  * thread or a daemon service thread when using the
978  * %POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION flag. This
979  * is because it may potentially take minutes (or even hours) for the
980  * operation to complete because it involves waiting for the user to
981  * authenticate.
982  *
983  * Known keys in @details include <literal>polkit.message</literal>
984  * and <literal>polkit.gettext_domain</literal> that can be used to
985  * override the message shown to the user. See the documentation for
986  * the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.CheckAuthorization">D-Bus method</link> for more details.
987  *
988  * Returns: (transfer full): A #PolkitAuthorizationResult or %NULL if @error is set. Free with g_object_unref().
989  */
990 PolkitAuthorizationResult *
polkit_authority_check_authorization_sync(PolkitAuthority * authority,PolkitSubject * subject,const gchar * action_id,PolkitDetails * details,PolkitCheckAuthorizationFlags flags,GCancellable * cancellable,GError ** error)991 polkit_authority_check_authorization_sync (PolkitAuthority               *authority,
992                                            PolkitSubject                 *subject,
993                                            const gchar                   *action_id,
994                                            PolkitDetails                 *details,
995                                            PolkitCheckAuthorizationFlags  flags,
996                                            GCancellable                  *cancellable,
997                                            GError                       **error)
998 {
999   PolkitAuthorizationResult *ret;
1000   CallSyncData *data;
1001 
1002   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
1003   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), NULL);
1004   g_return_val_if_fail (action_id != NULL, NULL);
1005   g_return_val_if_fail (details == NULL || POLKIT_IS_DETAILS (details), NULL);
1006   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1007   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1008 
1009   data = call_sync_new ();
1010   polkit_authority_check_authorization (authority, subject, action_id, details, flags, cancellable, call_sync_cb, data);
1011   call_sync_block (data);
1012   ret = polkit_authority_check_authorization_finish (authority, data->res, error);
1013   call_sync_free (data);
1014 
1015   return ret;
1016 }
1017 
1018 /* ---------------------------------------------------------------------------------------------------- */
1019 
1020 /**
1021  * polkit_authority_register_authentication_agent:
1022  * @authority: A #PolkitAuthority.
1023  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1024  * @locale: The locale of the authentication agent.
1025  * @object_path: The object path for the authentication agent.
1026  * @cancellable: (allow-none): A #GCancellable or %NULL.
1027  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1028  * @user_data: The data to pass to @callback.
1029  *
1030  * Asynchronously registers an authentication agent.
1031  *
1032  * Note that this should be called by the same effective UID which will be
1033  * the real UID using the #PolkitAgentSession API or otherwise calling
1034  * polkit_authority_authentication_agent_response().
1035  *
1036  * When the operation is finished, @callback will be invoked in the
1037  * <link linkend="g-main-context-push-thread-default">thread-default
1038  * main loop</link> of the thread you are calling this method
1039  * from. You can then call
1040  * polkit_authority_register_authentication_agent_finish() to get the
1041  * result of the operation.
1042  **/
1043 void
polkit_authority_register_authentication_agent(PolkitAuthority * authority,PolkitSubject * subject,const gchar * locale,const gchar * object_path,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1044 polkit_authority_register_authentication_agent (PolkitAuthority      *authority,
1045                                                 PolkitSubject        *subject,
1046                                                 const gchar          *locale,
1047                                                 const gchar          *object_path,
1048                                                 GCancellable         *cancellable,
1049                                                 GAsyncReadyCallback   callback,
1050                                                 gpointer              user_data)
1051 {
1052   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1053   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
1054   g_return_if_fail (locale != NULL);
1055   g_return_if_fail (g_variant_is_object_path (object_path));
1056   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1057 
1058   g_dbus_proxy_call (authority->proxy,
1059                      "RegisterAuthenticationAgent",
1060                      g_variant_new ("(@(sa{sv})ss)",
1061                                     polkit_subject_to_gvariant (subject), /* A floating value */
1062                                     locale,
1063                                     object_path),
1064                      G_DBUS_CALL_FLAGS_NONE,
1065                      -1,
1066                      cancellable,
1067                      generic_async_cb,
1068                      g_simple_async_result_new (G_OBJECT (authority),
1069                                                 callback,
1070                                                 user_data,
1071                                                 polkit_authority_register_authentication_agent));
1072 }
1073 
1074 /**
1075  * polkit_authority_register_authentication_agent_finish:
1076  * @authority: A #PolkitAuthority.
1077  * @res: A #GAsyncResult obtained from the callback.
1078  * @error: (allow-none): Return location for error or %NULL.
1079  *
1080  * Finishes registering an authentication agent.
1081  *
1082  * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set.
1083  **/
1084 gboolean
polkit_authority_register_authentication_agent_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1085 polkit_authority_register_authentication_agent_finish (PolkitAuthority *authority,
1086                                                        GAsyncResult    *res,
1087                                                        GError         **error)
1088 {
1089   gboolean ret;
1090   GVariant *value;
1091   GAsyncResult *_res;
1092 
1093   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1094   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1095   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1096 
1097   ret = FALSE;
1098 
1099   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_register_authentication_agent);
1100   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1101 
1102   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1103   if (value == NULL)
1104     goto out;
1105   ret = TRUE;
1106   g_variant_unref (value);
1107 
1108  out:
1109   return ret;
1110 }
1111 
1112 
1113 /**
1114  * polkit_authority_register_authentication_agent_sync:
1115  * @authority: A #PolkitAuthority.
1116  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1117  * @locale: The locale of the authentication agent.
1118  * @object_path: The object path for the authentication agent.
1119  * @cancellable: (allow-none): A #GCancellable or %NULL.
1120  * @error: (allow-none): Return location for error or %NULL.
1121  *
1122  * Registers an authentication agent.
1123  *
1124  * Note that this should be called by the same effective UID which will be
1125  * the real UID using the #PolkitAgentSession API or otherwise calling
1126  * polkit_authority_authentication_agent_response().
1127  *
1128  * The calling thread is blocked
1129  * until a reply is received. See
1130  * polkit_authority_register_authentication_agent() for the
1131  * asynchronous version.
1132  *
1133  * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set.
1134  **/
1135 gboolean
polkit_authority_register_authentication_agent_sync(PolkitAuthority * authority,PolkitSubject * subject,const gchar * locale,const gchar * object_path,GCancellable * cancellable,GError ** error)1136 polkit_authority_register_authentication_agent_sync (PolkitAuthority     *authority,
1137                                                      PolkitSubject       *subject,
1138                                                      const gchar         *locale,
1139                                                      const gchar         *object_path,
1140                                                      GCancellable        *cancellable,
1141                                                      GError             **error)
1142 {
1143   gboolean ret;
1144   CallSyncData *data;
1145 
1146   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1147   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
1148   g_return_val_if_fail (locale != NULL, FALSE);
1149   g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
1150   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1151   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1152 
1153   data = call_sync_new ();
1154   polkit_authority_register_authentication_agent (authority, subject, locale, object_path, cancellable, call_sync_cb, data);
1155   call_sync_block (data);
1156   ret = polkit_authority_register_authentication_agent_finish (authority, data->res, error);
1157   call_sync_free (data);
1158 
1159   return ret;
1160 }
1161 
1162 /* ---------------------------------------------------------------------------------------------------- */
1163 
1164 /**
1165  * polkit_authority_register_authentication_agent_with_options:
1166  * @authority: A #PolkitAuthority.
1167  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1168  * @locale: The locale of the authentication agent.
1169  * @object_path: The object path for the authentication agent.
1170  * @options: (allow-none): A #GVariant with options or %NULL.
1171  * @cancellable: (allow-none): A #GCancellable or %NULL.
1172  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1173  * @user_data: The data to pass to @callback.
1174  *
1175  * Asynchronously registers an authentication agent.
1176  *
1177  * Note that this should be called by the same effective UID which will be
1178  * the real UID using the #PolkitAgentSession API or otherwise calling
1179  * polkit_authority_authentication_agent_response().
1180  *
1181  * When the operation is finished, @callback will be invoked in the
1182  * <link linkend="g-main-context-push-thread-default">thread-default
1183  * main loop</link> of the thread you are calling this method
1184  * from. You can then call
1185  * polkit_authority_register_authentication_agent_with_options_finish() to get the
1186  * result of the operation.
1187  **/
1188 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)1189 polkit_authority_register_authentication_agent_with_options (PolkitAuthority      *authority,
1190                                                              PolkitSubject        *subject,
1191                                                              const gchar          *locale,
1192                                                              const gchar          *object_path,
1193                                                              GVariant             *options,
1194                                                              GCancellable         *cancellable,
1195                                                              GAsyncReadyCallback   callback,
1196                                                              gpointer              user_data)
1197 {
1198   GVariant *subject_value;
1199 
1200   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1201   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
1202   g_return_if_fail (locale != NULL);
1203   g_return_if_fail (g_variant_is_object_path (object_path));
1204   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1205 
1206   subject_value = polkit_subject_to_gvariant (subject);
1207   g_variant_ref_sink (subject_value);
1208   if (options != NULL)
1209     {
1210       g_dbus_proxy_call (authority->proxy,
1211                          "RegisterAuthenticationAgentWithOptions",
1212                          g_variant_new ("(@(sa{sv})ss@a{sv})",
1213                                         subject_value,
1214                                         locale,
1215                                         object_path,
1216                                         options),
1217                          G_DBUS_CALL_FLAGS_NONE,
1218                          -1,
1219                          cancellable,
1220                          generic_async_cb,
1221                          g_simple_async_result_new (G_OBJECT (authority),
1222                                                     callback,
1223                                                     user_data,
1224                                                     polkit_authority_register_authentication_agent_with_options));
1225     }
1226   else
1227     {
1228       g_dbus_proxy_call (authority->proxy,
1229                          "RegisterAuthenticationAgent",
1230                          g_variant_new ("(@(sa{sv})ss)",
1231                                         subject_value,
1232                                         locale,
1233                                         object_path),
1234                          G_DBUS_CALL_FLAGS_NONE,
1235                          -1,
1236                          cancellable,
1237                          generic_async_cb,
1238                          g_simple_async_result_new (G_OBJECT (authority),
1239                                                     callback,
1240                                                     user_data,
1241                                                     polkit_authority_register_authentication_agent_with_options));
1242     }
1243   g_variant_unref (subject_value);
1244 }
1245 
1246 /**
1247  * polkit_authority_register_authentication_agent_with_options_finish:
1248  * @authority: A #PolkitAuthority.
1249  * @res: A #GAsyncResult obtained from the callback.
1250  * @error: (allow-none): Return location for error or %NULL.
1251  *
1252  * Finishes registering an authentication agent.
1253  *
1254  * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set.
1255  **/
1256 gboolean
polkit_authority_register_authentication_agent_with_options_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1257 polkit_authority_register_authentication_agent_with_options_finish (PolkitAuthority *authority,
1258                                                                     GAsyncResult    *res,
1259                                                                     GError         **error)
1260 {
1261   gboolean ret;
1262   GVariant *value;
1263   GAsyncResult *_res;
1264 
1265   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1266   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1267   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1268 
1269   ret = FALSE;
1270 
1271   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_register_authentication_agent_with_options);
1272   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1273 
1274   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1275   if (value == NULL)
1276     goto out;
1277   ret = TRUE;
1278   g_variant_unref (value);
1279 
1280  out:
1281   return ret;
1282 }
1283 
1284 
1285 /**
1286  * polkit_authority_register_authentication_agent_with_options_sync:
1287  * @authority: A #PolkitAuthority.
1288  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1289  * @locale: The locale of the authentication agent.
1290  * @object_path: The object path for the authentication agent.
1291  * @options: (allow-none): A #GVariant with options or %NULL.
1292  * @cancellable: (allow-none): A #GCancellable or %NULL.
1293  * @error: (allow-none): Return location for error or %NULL.
1294  *
1295  * Registers an authentication agent.
1296  *
1297  * Note that this should be called by the same effective UID which will be
1298  * the real UID using the #PolkitAgentSession API or otherwise calling
1299  * polkit_authority_authentication_agent_response().
1300  *
1301  * The calling thread is blocked
1302  * until a reply is received. See
1303  * polkit_authority_register_authentication_agent_with_options() for the
1304  * asynchronous version.
1305  *
1306  * Returns: %TRUE if the authentication agent was successfully registered, %FALSE if @error is set.
1307  **/
1308 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)1309 polkit_authority_register_authentication_agent_with_options_sync (PolkitAuthority     *authority,
1310                                                                   PolkitSubject       *subject,
1311                                                                   const gchar         *locale,
1312                                                                   const gchar         *object_path,
1313                                                                   GVariant            *options,
1314                                                                   GCancellable        *cancellable,
1315                                                                   GError             **error)
1316 {
1317   gboolean ret;
1318   CallSyncData *data;
1319 
1320   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1321   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
1322   g_return_val_if_fail (locale != NULL, FALSE);
1323   g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
1324   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1325   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1326 
1327   data = call_sync_new ();
1328   polkit_authority_register_authentication_agent_with_options (authority, subject, locale, object_path, options, cancellable, call_sync_cb, data);
1329   call_sync_block (data);
1330   ret = polkit_authority_register_authentication_agent_with_options_finish (authority, data->res, error);
1331   call_sync_free (data);
1332 
1333   return ret;
1334 }
1335 
1336 /* ---------------------------------------------------------------------------------------------------- */
1337 
1338 /**
1339  * polkit_authority_unregister_authentication_agent:
1340  * @authority: A #PolkitAuthority.
1341  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1342  * @object_path: The object path for the authentication agent.
1343  * @cancellable: (allow-none): A #GCancellable or %NULL.
1344  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1345  * @user_data: The data to pass to @callback.
1346  *
1347  * Asynchronously unregisters an authentication agent.
1348  *
1349  * When the operation is finished, @callback will be invoked in the
1350  * <link linkend="g-main-context-push-thread-default">thread-default
1351  * main loop</link> of the thread you are calling this method
1352  * from. You can then call
1353  * polkit_authority_unregister_authentication_agent_finish() to get
1354  * the result of the operation.
1355  **/
1356 void
polkit_authority_unregister_authentication_agent(PolkitAuthority * authority,PolkitSubject * subject,const gchar * object_path,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1357 polkit_authority_unregister_authentication_agent (PolkitAuthority      *authority,
1358                                                   PolkitSubject        *subject,
1359                                                   const gchar          *object_path,
1360                                                   GCancellable         *cancellable,
1361                                                   GAsyncReadyCallback   callback,
1362                                                   gpointer              user_data)
1363 {
1364   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1365   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
1366   g_return_if_fail (g_variant_is_object_path (object_path));
1367   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1368 
1369   g_dbus_proxy_call (authority->proxy,
1370                      "UnregisterAuthenticationAgent",
1371                      g_variant_new ("(@(sa{sv})s)",
1372                                     polkit_subject_to_gvariant (subject), /* A floating value */
1373                                     object_path),
1374                      G_DBUS_CALL_FLAGS_NONE,
1375                      -1,
1376                      cancellable,
1377                      generic_async_cb,
1378                      g_simple_async_result_new (G_OBJECT (authority),
1379                                                 callback,
1380                                                 user_data,
1381                                                 polkit_authority_unregister_authentication_agent));
1382 }
1383 
1384 /**
1385  * polkit_authority_unregister_authentication_agent_finish:
1386  * @authority: A #PolkitAuthority.
1387  * @res: A #GAsyncResult obtained from the callback.
1388  * @error: (allow-none): Return location for error or %NULL.
1389  *
1390  * Finishes unregistering an authentication agent.
1391  *
1392  * Returns: %TRUE if the authentication agent was successfully unregistered, %FALSE if @error is set.
1393  **/
1394 gboolean
polkit_authority_unregister_authentication_agent_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1395 polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *authority,
1396                                                          GAsyncResult    *res,
1397                                                          GError         **error)
1398 {
1399   gboolean ret;
1400   GVariant *value;
1401   GAsyncResult *_res;
1402 
1403   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1404   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1405   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1406 
1407   ret = FALSE;
1408 
1409   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_unregister_authentication_agent);
1410   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1411 
1412   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1413   if (value == NULL)
1414     goto out;
1415   ret = TRUE;
1416   g_variant_unref (value);
1417 
1418  out:
1419   return ret;
1420 }
1421 
1422 
1423 /**
1424  * polkit_authority_unregister_authentication_agent_sync:
1425  * @authority: A #PolkitAuthority.
1426  * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
1427  * @object_path: The object path for the authentication agent.
1428  * @cancellable: (allow-none): A #GCancellable or %NULL.
1429  * @error: (allow-none): Return location for error or %NULL.
1430  *
1431  * Unregisters an authentication agent. The calling thread is blocked
1432  * until a reply is received. See
1433  * polkit_authority_unregister_authentication_agent() for the
1434  * asynchronous version.
1435  *
1436  * Returns: %TRUE if the authentication agent was successfully unregistered, %FALSE if @error is set.
1437  **/
1438 gboolean
polkit_authority_unregister_authentication_agent_sync(PolkitAuthority * authority,PolkitSubject * subject,const gchar * object_path,GCancellable * cancellable,GError ** error)1439 polkit_authority_unregister_authentication_agent_sync (PolkitAuthority     *authority,
1440                                                        PolkitSubject       *subject,
1441                                                        const gchar         *object_path,
1442                                                        GCancellable        *cancellable,
1443                                                        GError             **error)
1444 {
1445   gboolean ret;
1446   CallSyncData *data;
1447 
1448   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1449   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
1450   g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
1451   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1452   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1453 
1454   data = call_sync_new ();
1455   polkit_authority_unregister_authentication_agent (authority, subject, object_path, cancellable, call_sync_cb, data);
1456   call_sync_block (data);
1457   ret = polkit_authority_unregister_authentication_agent_finish (authority, data->res, error);
1458   call_sync_free (data);
1459 
1460   return ret;
1461 }
1462 
1463 /* ---------------------------------------------------------------------------------------------------- */
1464 
1465 /**
1466  * polkit_authority_authentication_agent_response:
1467  * @authority: A #PolkitAuthority.
1468  * @cookie: The cookie passed to the authentication agent from the authority.
1469  * @identity: The identity that was authenticated.
1470  * @cancellable: (allow-none): A #GCancellable or %NULL.
1471  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1472  * @user_data: The data to pass to @callback.
1473  *
1474  * Asynchronously provide response that @identity successfully authenticated
1475  * for the authentication request identified by @cookie.
1476  *
1477  * This function is only used by the privileged bits of an authentication agent.
1478  * It will fail if the caller is not sufficiently privileged (typically uid 0).
1479  *
1480  * When the operation is finished, @callback will be invoked in the
1481  * <link linkend="g-main-context-push-thread-default">thread-default
1482  * main loop</link> of the thread you are calling this method
1483  * from. You can then call
1484  * polkit_authority_authentication_agent_response_finish() to get the
1485  * result of the operation.
1486  **/
1487 void
polkit_authority_authentication_agent_response(PolkitAuthority * authority,const gchar * cookie,PolkitIdentity * identity,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1488 polkit_authority_authentication_agent_response (PolkitAuthority      *authority,
1489                                                 const gchar          *cookie,
1490                                                 PolkitIdentity       *identity,
1491                                                 GCancellable         *cancellable,
1492                                                 GAsyncReadyCallback   callback,
1493                                                 gpointer              user_data)
1494 {
1495   /* Note that in reality, this API is only accessible to root, and
1496    * only called from the setuid helper `polkit-agent-helper-1`.
1497    *
1498    * However, because this is currently public API, we avoid
1499    * triggering warnings from ABI diff type programs by just grabbing
1500    * the real uid of the caller here.
1501    */
1502   uid_t uid = getuid ();
1503 
1504   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1505   g_return_if_fail (cookie != NULL);
1506   g_return_if_fail (POLKIT_IS_IDENTITY (identity));
1507   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1508 
1509   g_dbus_proxy_call (authority->proxy,
1510                      "AuthenticationAgentResponse2",
1511                      g_variant_new ("(us@(sa{sv}))",
1512                                     (guint32)uid,
1513                                     cookie,
1514                                     polkit_identity_to_gvariant (identity)), /* A floating value */
1515                      G_DBUS_CALL_FLAGS_NONE,
1516                      -1,
1517                      cancellable,
1518                      generic_async_cb,
1519                      g_simple_async_result_new (G_OBJECT (authority),
1520                                                 callback,
1521                                                 user_data,
1522                                                 polkit_authority_authentication_agent_response));
1523 }
1524 
1525 /**
1526  * polkit_authority_authentication_agent_response_finish:
1527  * @authority: A #PolkitAuthority.
1528  * @res: A #GAsyncResult obtained from the callback.
1529  * @error: (allow-none): Return location for error or %NULL.
1530  *
1531  * Finishes providing response from an authentication agent.
1532  *
1533  * Returns: %TRUE if @authority acknowledged the call, %FALSE if @error is set.
1534  **/
1535 gboolean
polkit_authority_authentication_agent_response_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1536 polkit_authority_authentication_agent_response_finish (PolkitAuthority *authority,
1537                                                        GAsyncResult    *res,
1538                                                        GError         **error)
1539 {
1540   gboolean ret;
1541   GVariant *value;
1542   GAsyncResult *_res;
1543 
1544   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1545   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1546   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1547 
1548   ret = FALSE;
1549 
1550   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_authentication_agent_response);
1551   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1552 
1553   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1554   if (value == NULL)
1555     goto out;
1556   ret = TRUE;
1557   g_variant_unref (value);
1558 
1559  out:
1560   return ret;
1561 }
1562 
1563 
1564 /**
1565  * polkit_authority_authentication_agent_response_sync:
1566  * @authority: A #PolkitAuthority.
1567  * @cookie: The cookie passed to the authentication agent from the authority.
1568  * @identity: The identity that was authenticated.
1569  * @cancellable: (allow-none): A #GCancellable or %NULL.
1570  * @error: (allow-none): Return location for error or %NULL.
1571  *
1572  * Provide response that @identity successfully authenticated for the
1573  * authentication request identified by @cookie. See polkit_authority_authentication_agent_response()
1574  * for limitations on who is allowed is to call this method.
1575  *
1576  * The calling thread is blocked until a reply is received. See
1577  * polkit_authority_authentication_agent_response() for the
1578  * asynchronous version.
1579  *
1580  * Returns: %TRUE if @authority acknowledged the call, %FALSE if @error is set.
1581  **/
1582 gboolean
polkit_authority_authentication_agent_response_sync(PolkitAuthority * authority,const gchar * cookie,PolkitIdentity * identity,GCancellable * cancellable,GError ** error)1583 polkit_authority_authentication_agent_response_sync (PolkitAuthority     *authority,
1584                                                      const gchar         *cookie,
1585                                                      PolkitIdentity      *identity,
1586                                                      GCancellable        *cancellable,
1587                                                      GError             **error)
1588 {
1589   gboolean ret;
1590   CallSyncData *data;
1591 
1592   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1593   g_return_val_if_fail (cookie != NULL, FALSE);
1594   g_return_val_if_fail (POLKIT_IS_IDENTITY (identity), FALSE);
1595   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1596   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1597 
1598   data = call_sync_new ();
1599   polkit_authority_authentication_agent_response (authority, cookie, identity, cancellable, call_sync_cb, data);
1600   call_sync_block (data);
1601   ret = polkit_authority_authentication_agent_response_finish (authority, data->res, error);
1602   call_sync_free (data);
1603 
1604   return ret;
1605 }
1606 
1607 /* ---------------------------------------------------------------------------------------------------- */
1608 
1609 /**
1610  * polkit_authority_enumerate_temporary_authorizations:
1611  * @authority: A #PolkitAuthority.
1612  * @subject: A #PolkitSubject, typically a #PolkitUnixSession.
1613  * @cancellable: (allow-none): A #GCancellable or %NULL.
1614  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1615  * @user_data: The data to pass to @callback.
1616  *
1617  * Asynchronously gets all temporary authorizations for @subject.
1618  *
1619  * When the operation is finished, @callback will be invoked in the
1620  * <link linkend="g-main-context-push-thread-default">thread-default
1621  * main loop</link> of the thread you are calling this method
1622  * from. You can then call
1623  * polkit_authority_enumerate_temporary_authorizations_finish() to get
1624  * the result of the operation.
1625  **/
1626 void
polkit_authority_enumerate_temporary_authorizations(PolkitAuthority * authority,PolkitSubject * subject,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1627 polkit_authority_enumerate_temporary_authorizations (PolkitAuthority     *authority,
1628                                                      PolkitSubject       *subject,
1629                                                      GCancellable        *cancellable,
1630                                                      GAsyncReadyCallback  callback,
1631                                                      gpointer             user_data)
1632 {
1633   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1634   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
1635   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1636 
1637   g_dbus_proxy_call (authority->proxy,
1638                      "EnumerateTemporaryAuthorizations",
1639                      g_variant_new ("(@(sa{sv}))",
1640                                     polkit_subject_to_gvariant (subject)), /* A floating value */
1641                      G_DBUS_CALL_FLAGS_NONE,
1642                      -1,
1643                      cancellable,
1644                      generic_async_cb,
1645                      g_simple_async_result_new (G_OBJECT (authority),
1646                                                 callback,
1647                                                 user_data,
1648                                                 polkit_authority_enumerate_temporary_authorizations));
1649 }
1650 
1651 /**
1652  * polkit_authority_enumerate_temporary_authorizations_finish:
1653  * @authority: A #PolkitAuthority.
1654  * @res: A #GAsyncResult obtained from the callback.
1655  * @error: (allow-none): Return location for error or %NULL.
1656  *
1657  * Finishes retrieving all registered actions.
1658  *
1659  * Returns: (element-type Polkit.TemporaryAuthorization) (transfer full): A
1660  * list of #PolkitTemporaryAuthorization objects or %NULL if @error is set. The
1661  * returned list should be freed with g_list_free() after each element have
1662  * been freed with g_object_unref().
1663  **/
1664 GList *
polkit_authority_enumerate_temporary_authorizations_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1665 polkit_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *authority,
1666                                                             GAsyncResult    *res,
1667                                                             GError         **error)
1668 {
1669   GList *ret;
1670   GVariant *value;
1671   GVariantIter iter;
1672   GVariant *child;
1673   GVariant *array;
1674   GAsyncResult *_res;
1675 
1676   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
1677   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
1678   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1679 
1680   ret = NULL;
1681 
1682   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_enumerate_temporary_authorizations);
1683   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1684 
1685   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1686   if (value == NULL)
1687     goto out;
1688 
1689   array = g_variant_get_child_value (value, 0);
1690   g_variant_iter_init (&iter, array);
1691   while ((child = g_variant_iter_next_value (&iter)) != NULL)
1692     {
1693       PolkitTemporaryAuthorization *auth;
1694       auth = polkit_temporary_authorization_new_for_gvariant (child, error);
1695       g_variant_unref (child);
1696       if (auth == NULL)
1697         {
1698           g_prefix_error (error, "Error serializing return value of EnumerateTemporaryAuthorizations: ");
1699           g_list_foreach (ret, (GFunc) g_object_unref, NULL);
1700           g_list_free (ret);
1701           ret = NULL;
1702           goto out_array;
1703         }
1704       ret = g_list_prepend (ret, auth);
1705     }
1706   ret = g_list_reverse (ret);
1707  out_array:
1708   g_variant_unref (array);
1709   g_variant_unref (value);
1710 
1711  out:
1712   return ret;
1713 }
1714 
1715 /**
1716  * polkit_authority_enumerate_temporary_authorizations_sync:
1717  * @authority: A #PolkitAuthority.
1718  * @subject: A #PolkitSubject, typically a #PolkitUnixSession.
1719  * @cancellable: (allow-none): A #GCancellable or %NULL.
1720  * @error: (allow-none): Return location for error or %NULL.
1721  *
1722  * Synchronousky gets all temporary authorizations for @subject.
1723  *
1724  * The calling thread is blocked until a reply is received. See
1725  * polkit_authority_enumerate_temporary_authorizations() for the
1726  * asynchronous version.
1727  *
1728  * Returns: (element-type Polkit.TemporaryAuthorization) (transfer full): A
1729  * list of #PolkitTemporaryAuthorization objects or %NULL if @error is set. The
1730  * returned list should be freed with g_list_free() after each element have
1731  * been freed with g_object_unref().
1732  **/
1733 GList *
polkit_authority_enumerate_temporary_authorizations_sync(PolkitAuthority * authority,PolkitSubject * subject,GCancellable * cancellable,GError ** error)1734 polkit_authority_enumerate_temporary_authorizations_sync (PolkitAuthority     *authority,
1735                                                           PolkitSubject       *subject,
1736                                                           GCancellable        *cancellable,
1737                                                           GError             **error)
1738 {
1739   GList *ret;
1740   CallSyncData *data;
1741 
1742   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
1743   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), NULL);
1744   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1745   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1746 
1747   data = call_sync_new ();
1748   polkit_authority_enumerate_temporary_authorizations (authority, subject, cancellable, call_sync_cb, data);
1749   call_sync_block (data);
1750   ret = polkit_authority_enumerate_temporary_authorizations_finish (authority, data->res, error);
1751   call_sync_free (data);
1752 
1753   return ret;
1754 }
1755 
1756 /* ---------------------------------------------------------------------------------------------------- */
1757 
1758 /**
1759  * polkit_authority_revoke_temporary_authorizations:
1760  * @authority: A #PolkitAuthority.
1761  * @subject: The subject to revoke authorizations from, typically a #PolkitUnixSession.
1762  * @cancellable: (allow-none): A #GCancellable or %NULL.
1763  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1764  * @user_data: The data to pass to @callback.
1765  *
1766  * Asynchronously revokes all temporary authorizations for @subject.
1767  *
1768  * When the operation is finished, @callback will be invoked in the
1769  * <link linkend="g-main-context-push-thread-default">thread-default
1770  * main loop</link> of the thread you are calling this method
1771  * from. You can then call
1772  * polkit_authority_revoke_temporary_authorizations_finish() to get
1773  * the result of the operation.
1774  **/
1775 void
polkit_authority_revoke_temporary_authorizations(PolkitAuthority * authority,PolkitSubject * subject,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1776 polkit_authority_revoke_temporary_authorizations (PolkitAuthority     *authority,
1777                                                   PolkitSubject       *subject,
1778                                                   GCancellable        *cancellable,
1779                                                   GAsyncReadyCallback  callback,
1780                                                   gpointer             user_data)
1781 {
1782   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1783   g_return_if_fail (POLKIT_IS_SUBJECT (subject));
1784   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1785 
1786   g_dbus_proxy_call (authority->proxy,
1787                      "RevokeTemporaryAuthorizations",
1788                      g_variant_new ("(@(sa{sv}))",
1789                                     polkit_subject_to_gvariant (subject)), /* A floating value */
1790                      G_DBUS_CALL_FLAGS_NONE,
1791                      -1,
1792                      cancellable,
1793                      generic_async_cb,
1794                      g_simple_async_result_new (G_OBJECT (authority),
1795                                                 callback,
1796                                                 user_data,
1797                                                 polkit_authority_revoke_temporary_authorizations));
1798 }
1799 
1800 /**
1801  * polkit_authority_revoke_temporary_authorizations_finish:
1802  * @authority: A #PolkitAuthority.
1803  * @res: A #GAsyncResult obtained from the callback.
1804  * @error: (allow-none): Return location for error or %NULL.
1805  *
1806  * Finishes revoking temporary authorizations.
1807  *
1808  * Returns: %TRUE if all the temporary authorizations was revoked, %FALSE if error is set.
1809  **/
1810 gboolean
polkit_authority_revoke_temporary_authorizations_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1811 polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *authority,
1812                                                          GAsyncResult    *res,
1813                                                          GError         **error)
1814 {
1815   gboolean ret;
1816   GVariant *value;
1817   GAsyncResult *_res;
1818 
1819   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1820   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1821   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1822 
1823   ret = FALSE;
1824 
1825   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_revoke_temporary_authorizations);
1826   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1827 
1828   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1829   if (value == NULL)
1830     goto out;
1831   ret = TRUE;
1832   g_variant_unref (value);
1833 
1834  out:
1835   return ret;
1836 }
1837 
1838 /**
1839  * polkit_authority_revoke_temporary_authorizations_sync:
1840  * @authority: A #PolkitAuthority.
1841  * @subject: The subject to revoke authorizations from, typically a #PolkitUnixSession.
1842  * @cancellable: (allow-none): A #GCancellable or %NULL.
1843  * @error: (allow-none): Return location for error or %NULL.
1844  *
1845  * Synchronously revokes all temporary authorization from @subject.
1846  *
1847  * The calling thread is blocked until a reply is received. See
1848  * polkit_authority_revoke_temporary_authorizations() for the
1849  * asynchronous version.
1850  *
1851  * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
1852  **/
1853 gboolean
polkit_authority_revoke_temporary_authorizations_sync(PolkitAuthority * authority,PolkitSubject * subject,GCancellable * cancellable,GError ** error)1854 polkit_authority_revoke_temporary_authorizations_sync (PolkitAuthority     *authority,
1855                                                        PolkitSubject       *subject,
1856                                                        GCancellable        *cancellable,
1857                                                        GError             **error)
1858 {
1859   gboolean ret;
1860   CallSyncData *data;
1861 
1862   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1863   g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
1864   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1865   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1866 
1867   data = call_sync_new ();
1868   polkit_authority_revoke_temporary_authorizations (authority, subject, cancellable, call_sync_cb, data);
1869   call_sync_block (data);
1870   ret = polkit_authority_revoke_temporary_authorizations_finish (authority, data->res, error);
1871   call_sync_free (data);
1872 
1873   return ret;
1874 }
1875 
1876 /* ---------------------------------------------------------------------------------------------------- */
1877 
1878 /**
1879  * polkit_authority_revoke_temporary_authorization_by_id:
1880  * @authority: A #PolkitAuthority.
1881  * @id: The opaque identifier for the temporary authorization.
1882  * @cancellable: (allow-none): A #GCancellable or %NULL.
1883  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
1884  * @user_data: The data to pass to @callback.
1885  *
1886  * Asynchronously revoke a temporary authorization.
1887  *
1888  * When the operation is finished, @callback will be invoked in the
1889  * <link linkend="g-main-context-push-thread-default">thread-default
1890  * main loop</link> of the thread you are calling this method
1891  * from. You can then call
1892  * polkit_authority_revoke_temporary_authorization_by_id_finish() to
1893  * get the result of the operation.
1894  */
1895 void
polkit_authority_revoke_temporary_authorization_by_id(PolkitAuthority * authority,const gchar * id,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1896 polkit_authority_revoke_temporary_authorization_by_id (PolkitAuthority     *authority,
1897                                                        const gchar         *id,
1898                                                        GCancellable        *cancellable,
1899                                                        GAsyncReadyCallback  callback,
1900                                                        gpointer             user_data)
1901 {
1902   g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
1903   g_return_if_fail (id != NULL);
1904   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1905 
1906   g_dbus_proxy_call (authority->proxy,
1907                      "RevokeTemporaryAuthorizationById",
1908                      g_variant_new ("(s)",
1909                                     id),
1910                      G_DBUS_CALL_FLAGS_NONE,
1911                      -1,
1912                      cancellable,
1913                      generic_async_cb,
1914                      g_simple_async_result_new (G_OBJECT (authority),
1915                                                 callback,
1916                                                 user_data,
1917                                                 polkit_authority_revoke_temporary_authorization_by_id));
1918 }
1919 
1920 /**
1921  * polkit_authority_revoke_temporary_authorization_by_id_finish:
1922  * @authority: A #PolkitAuthority.
1923  * @res: A #GAsyncResult obtained from the callback.
1924  * @error: (allow-none): Return location for error or %NULL.
1925  *
1926  * Finishes revoking a temporary authorization by id.
1927  *
1928  * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
1929  **/
1930 gboolean
polkit_authority_revoke_temporary_authorization_by_id_finish(PolkitAuthority * authority,GAsyncResult * res,GError ** error)1931 polkit_authority_revoke_temporary_authorization_by_id_finish (PolkitAuthority *authority,
1932                                                               GAsyncResult    *res,
1933                                                               GError         **error)
1934 {
1935   gboolean ret;
1936   GVariant *value;
1937   GAsyncResult *_res;
1938 
1939   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1940   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1941   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1942 
1943   ret = FALSE;
1944 
1945   g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_revoke_temporary_authorization_by_id);
1946   _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
1947 
1948   value = g_dbus_proxy_call_finish (authority->proxy, _res, error);
1949   if (value == NULL)
1950     goto out;
1951   ret = TRUE;
1952   g_variant_unref (value);
1953 
1954  out:
1955   return ret;
1956 }
1957 
1958 /**
1959  * polkit_authority_revoke_temporary_authorization_by_id_sync:
1960  * @authority: A #PolkitAuthority.
1961  * @id: The opaque identifier for the temporary authorization.
1962  * @cancellable: (allow-none): A #GCancellable or %NULL.
1963  * @error: (allow-none): Return location for error or %NULL.
1964  *
1965  * Synchronously revokes a temporary authorization.
1966  *
1967  * The calling thread is blocked until a reply is received. See
1968  * polkit_authority_revoke_temporary_authorization_by_id() for the
1969  * asynchronous version.
1970  *
1971  * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
1972  **/
1973 gboolean
polkit_authority_revoke_temporary_authorization_by_id_sync(PolkitAuthority * authority,const gchar * id,GCancellable * cancellable,GError ** error)1974 polkit_authority_revoke_temporary_authorization_by_id_sync (PolkitAuthority     *authority,
1975                                                             const gchar         *id,
1976                                                             GCancellable        *cancellable,
1977                                                             GError             **error)
1978 {
1979   gboolean ret;
1980   CallSyncData *data;
1981 
1982   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), FALSE);
1983   g_return_val_if_fail (id != NULL, FALSE);
1984   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1985   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1986 
1987   data = call_sync_new ();
1988   polkit_authority_revoke_temporary_authorization_by_id (authority, id, cancellable, call_sync_cb, data);
1989   call_sync_block (data);
1990   ret = polkit_authority_revoke_temporary_authorization_by_id_finish (authority, data->res, error);
1991   call_sync_free (data);
1992 
1993   return ret;
1994 }
1995 
1996 /* ---------------------------------------------------------------------------------------------------- */
1997 
1998 /**
1999  * polkit_authority_get_owner:
2000  * @authority: A #PolkitAuthority.
2001  *
2002  * The unique name on the system message bus of the owner of the name
2003  * <literal>org.freedesktop.PolicyKit1</literal> or %NULL if no-one
2004  * currently owns the name. You may connect to the #GObject::notify
2005  * signal to track changes to the #PolkitAuthority:owner property.
2006  *
2007  * Returns: (allow-none): %NULL or a string that should be freed with g_free().
2008  **/
2009 gchar *
polkit_authority_get_owner(PolkitAuthority * authority)2010 polkit_authority_get_owner (PolkitAuthority *authority)
2011 {
2012   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
2013   return g_dbus_proxy_get_name_owner (authority->proxy);
2014 }
2015 
2016 /**
2017  * polkit_authority_get_backend_name:
2018  * @authority: A #PolkitAuthority.
2019  *
2020  * Gets the name of the authority backend.
2021  *
2022  * Returns: The name of the backend.
2023  */
2024 const gchar *
polkit_authority_get_backend_name(PolkitAuthority * authority)2025 polkit_authority_get_backend_name (PolkitAuthority *authority)
2026 {
2027   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
2028   if (authority->name == NULL)
2029     {
2030       GVariant *value;
2031       value = g_dbus_proxy_get_cached_property (authority->proxy, "BackendName");
2032       authority->name = g_variant_dup_string (value, NULL);
2033       g_variant_unref (value);
2034     }
2035   return authority->name;
2036 }
2037 
2038 /**
2039  * polkit_authority_get_backend_version:
2040  * @authority: A #PolkitAuthority.
2041  *
2042  * Gets the version of the authority backend.
2043  *
2044  * Returns: The version string for the backend.
2045  */
2046 const gchar *
polkit_authority_get_backend_version(PolkitAuthority * authority)2047 polkit_authority_get_backend_version (PolkitAuthority *authority)
2048 {
2049   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), NULL);
2050   if (authority->version == NULL)
2051     {
2052       GVariant *value;
2053       value = g_dbus_proxy_get_cached_property (authority->proxy, "BackendVersion");
2054       authority->version = g_variant_dup_string (value, NULL);
2055       g_variant_unref (value);
2056     }
2057   return authority->version;
2058 }
2059 
2060 /**
2061  * polkit_authority_get_backend_features:
2062  * @authority: A #PolkitAuthority.
2063  *
2064  * Gets the features supported by the authority backend.
2065  *
2066  * Returns: Flags from #PolkitAuthorityFeatures.
2067  */
2068 PolkitAuthorityFeatures
polkit_authority_get_backend_features(PolkitAuthority * authority)2069 polkit_authority_get_backend_features (PolkitAuthority *authority)
2070 {
2071   PolkitAuthorityFeatures ret;
2072   GVariant *value;
2073 
2074   g_return_val_if_fail (POLKIT_IS_AUTHORITY (authority), 0);
2075 
2076   value = g_dbus_proxy_get_cached_property (authority->proxy, "BackendFeatures");
2077   ret = (PolkitAuthorityFeatures) g_variant_get_uint32 (value);
2078   g_variant_unref (value);
2079 
2080   return ret;
2081 }
2082