Skip to content

Commit 361c4ee

Browse files
committed
bus-polkit: describe async. polkit verification
1 parent 0df66e4 commit 361c4ee

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/shared/bus-polkit.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,80 @@ static int process_polkit_response(
324324

325325
#endif
326326

327+
/* bus_verify_polkit_async() handles verification of D-Bus calls with polkit. Because the polkit API
328+
* is asynchronous, the whole thing is a bit complex and requires some support in the code that uses
329+
* it. It relies on sd-bus's support for interrupting the processing of a message.
330+
*
331+
* Requirements:
332+
*
333+
* * bus_verify_polkit_async() must be called before any changes to internal state.
334+
* * If bus_verify_polkit_async() has made a new polkit query (signaled by return value 0),
335+
* processing of the message should be interrupted. This is done by returning 1--which sd-bus
336+
* handles specially--and is usually accompanied by a comment. (The message will be queued for
337+
* processing again later when a reply from polkit is received.)
338+
* * The code needs to keep a hashmap, here called registry, in which bus_verify_polkit_async()
339+
* stores active queries. This hashmap's lifetime must be larger than the method handler's;
340+
* e.g., it can be a member of some "manager" object or a global variable.
341+
*
342+
* Return value:
343+
*
344+
* * 0 - a new polkit call has been made, which means the processing of the message should be
345+
* interrupted;
346+
* * 1 - the action has been allowed;
347+
* * -EACCES - the action has been denied;
348+
* * < 0 - an unspecified error.
349+
*
350+
* A step-by-step description of how it works:
351+
*
352+
* 1. A D-Bus method handler calls bus_verify_polkit_async(), passing it the D-Bus message being
353+
* processed and the polkit action to verify.
354+
* 2. bus_verify_polkit_async() checks the registry for the message and action combination. Let's
355+
* assume this is the first call, so it finds nothing.
356+
* 3. A new AsyncPolkitQuery object is created and an async. D-Bus call to polkit is made. The
357+
* function then returns 0. The method handler returns 1 to tell sd-bus that the processing of
358+
* the message has been interrupted.
359+
* 4. (Later) A reply from polkit is received and async_polkit_callback() is called.
360+
* 5. async_polkit_callback() reads the reply and stores result into the passed query.
361+
* 6. async_polkit_callback() enqueues the original message again.
362+
* 7. (Later) The same D-Bus method handler is called for the same message. It calls
363+
* bus_verify_polkit_async() again.
364+
* 8. bus_verify_polkit_async() checks the registry for the message and action combination. It finds
365+
* an existing query and returns its result.
366+
* 9. The method handler continues processing of the message.
367+
*
368+
* Memory handling:
369+
*
370+
* async_polkit_callback() registers a deferred call of async_polkit_defer() for the query, which
371+
* causes the query to be removed from the registry and freed. Deferred events are run with idle
372+
* priority, so this will happen after processing of the D-Bus message, when the query is no longer
373+
* needed.
374+
*
375+
* Schematically:
376+
*
377+
* (m - D-Bus message, a - polkit action, q - polkit query)
378+
*
379+
* -> foo_method(m)
380+
* -> bus_verify_polkit_async(m, a)
381+
* -> bus_call_method_async(q)
382+
* <- bus_verify_polkit_async(m, a) = 0
383+
* <- foo_method(m) = 1
384+
* ...
385+
* -> async_polkit_callback(q)
386+
* -> sd_event_add_defer(async_polkit_defer, q)
387+
* -> sd_bus_enqueue_for_read(m)
388+
* <- async_polkit_callback(q)
389+
* ...
390+
* -> foo_method(m)
391+
* -> bus_verify_polkit_async(m, a)
392+
* <- bus_verify_polkit_async(m, a) = 1/-EACCES/error
393+
* ...
394+
* <- foo_method(m)
395+
* ...
396+
* -> async_polkit_defer(q)
397+
* -> async_polkit_query_free(q)
398+
* <- async_polkit_defer(q)
399+
*/
400+
327401
int bus_verify_polkit_async(
328402
sd_bus_message *call,
329403
int capability,

0 commit comments

Comments
 (0)