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