auth-manager: rework auth-manager's API
Don't use the GAsyncResult pattern for internal API of auth-manager. Instead, use a simpler API that has a more strict API and simpler use. - return a call-id handle when scheduling the authorization request. The request is always scheduled asynchronsously and thus call-id is never %NULL. - the call-id can be used to cancel the request. It can be used exactly once, and only before the callback is invoked. - the async keeps the auth-manager alive. It needs to do so, because when cancelling the request we might not yet be done: instead we might still need to issue a CancelCheckAuthorization call (which we need to handle as well). - the callback is always invoked exactly once. Currently NMAuthManager's API effectivly is only called by NMAuthChain. The point of this is to make NMAuthManager's API more consumable, and thus let users use it directly (instead of using the NMAuthChain layer). As well known, we don't do a good job during shutdown of NetworkManager to release all resources and cancel pending requests. This rework also makes it possible to actually get this right. See the comment in nm_auth_manager_force_shutdown(). But yes, it is still a bit complicated to do a controlled shutdown, because we cannot just synchronously complete. We need to issue CancelCheckAuthorization D-Bus calls, and give these requests time to complete. The new API introduced by this patch would make that easier.
This commit is contained in:
@@ -52,7 +52,7 @@ struct NMAuthChain {
|
||||
typedef struct {
|
||||
CList auth_call_lst;
|
||||
NMAuthChain *chain;
|
||||
GCancellable *cancellable;
|
||||
NMAuthManagerCallId *call_id;
|
||||
char *permission;
|
||||
guint call_idle_id;
|
||||
} AuthCall;
|
||||
@@ -72,8 +72,12 @@ _ASSERT_call (AuthCall *call)
|
||||
static void
|
||||
auth_call_free (AuthCall *call)
|
||||
{
|
||||
#if WITH_POLKIT
|
||||
if (call->call_id)
|
||||
nm_auth_manager_check_authorization_cancel (call->call_id);
|
||||
#endif
|
||||
|
||||
nm_clear_g_source (&call->call_idle_id);
|
||||
nm_clear_g_cancellable (&call->cancellable);
|
||||
c_list_unlink_stale (&call->auth_call_lst);
|
||||
g_free (call->permission);
|
||||
g_slice_free (AuthCall, call);
|
||||
@@ -253,26 +257,24 @@ auth_call_complete_idle_cb (gpointer user_data)
|
||||
|
||||
#if WITH_POLKIT
|
||||
static void
|
||||
pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||
pk_call_cb (NMAuthManager *auth_manager,
|
||||
NMAuthManagerCallId *call_id,
|
||||
gboolean is_authorized,
|
||||
gboolean is_challenge,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
AuthCall *call;
|
||||
gs_free_error GError *error = NULL;
|
||||
gboolean is_authorized = FALSE, is_challenge = FALSE;
|
||||
guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN;
|
||||
NMAuthCallResult call_result = NM_AUTH_CALL_RESULT_UNKNOWN;
|
||||
|
||||
nm_auth_manager_polkit_authority_check_authorization_finish (NM_AUTH_MANAGER (object),
|
||||
result,
|
||||
&is_authorized,
|
||||
&is_challenge,
|
||||
&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
nm_log_dbg (LOGD_CORE, "callback already cancelled");
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
}
|
||||
|
||||
call = user_data;
|
||||
|
||||
g_clear_object (&call->cancellable);
|
||||
nm_assert (call->call_id == call_id);
|
||||
|
||||
call->call_id = NULL;
|
||||
|
||||
if (error) {
|
||||
/* Don't ruin the chain. Just leave the result unknown. */
|
||||
@@ -323,14 +325,12 @@ nm_auth_chain_add_call (NMAuthChain *self,
|
||||
} else {
|
||||
/* Non-root always gets authenticated when using polkit */
|
||||
#if WITH_POLKIT
|
||||
call->cancellable = g_cancellable_new ();
|
||||
nm_auth_manager_polkit_authority_check_authorization (auth_manager,
|
||||
self->subject,
|
||||
permission,
|
||||
allow_interaction,
|
||||
call->cancellable,
|
||||
pk_call_cb,
|
||||
call);
|
||||
call->call_id = nm_auth_manager_check_authorization (auth_manager,
|
||||
self->subject,
|
||||
permission,
|
||||
allow_interaction,
|
||||
pk_call_cb,
|
||||
call);
|
||||
#else
|
||||
if (!call->chain->error) {
|
||||
call->chain->error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
|
Reference in New Issue
Block a user