void nm_auth_chain_set_data_ulong (NMAuthChain *self, const char *tag, gulong data) { gulong *ptr; g_return_if_fail (self != NULL); g_return_if_fail (tag != NULL); ptr = g_malloc (sizeof (*ptr)); *ptr = data; nm_auth_chain_set_data (self, tag, ptr, g_free); }
static void pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) { AuthCall *call = user_data; GError *error = NULL; gboolean is_authorized, is_challenge; nm_auth_manager_polkit_authority_check_authorization_finish (NM_AUTH_MANAGER (object), result, &is_authorized, &is_challenge, &error); /* If the call is already canceled do nothing */ if (!call->cancellable) { nm_log_dbg (LOGD_CORE, "callback already cancelled"); g_clear_error (&error); auth_call_free (call); return; } if (error) { nm_log_warn (LOGD_CORE, "error requesting auth for %s: %s", call->permission, error->message); if (!call->chain->error) { call->chain->error = error; error = NULL; } else g_clear_error (&error); } else { guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; if (is_authorized) { /* Caller has the permission */ call_result = NM_AUTH_CALL_RESULT_YES; } else if (is_challenge) { /* Caller could authenticate to get the permission */ call_result = NM_AUTH_CALL_RESULT_AUTH; } else call_result = NM_AUTH_CALL_RESULT_NO; nm_auth_chain_set_data (call->chain, call->permission, GUINT_TO_POINTER (call_result), NULL); } auth_call_complete (call); }
void nm_auth_chain_add_call (NMAuthChain *self, const char *permission, gboolean allow_interaction) { AuthCall *call; NMAuthManager *auth_manager = nm_auth_manager_get (); g_return_if_fail (self != NULL); g_return_if_fail (permission && *permission); g_return_if_fail (self->subject); g_return_if_fail (nm_auth_subject_is_unix_process (self->subject) || nm_auth_subject_is_internal (self->subject)); g_return_if_fail (!self->idle_id && !self->done); call = auth_call_new (self, permission); self->calls = g_slist_append (self->calls, call); if ( nm_auth_subject_is_internal (self->subject) || nm_auth_subject_get_unix_process_uid (self->subject) == 0 || !nm_auth_manager_get_polkit_enabled (auth_manager)) { /* Root user or non-polkit always gets the permission */ nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); } 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); #else if (!call->chain->error) { call->chain->error = g_error_new_literal (DBUS_GERROR, DBUS_GERROR_FAILED, "Polkit support is disabled at compile time"); } call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); #endif } }
static void pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) { AuthCall *call = user_data; PolkitAuthorizationResult *pk_result; GError *error = NULL; pk_result = polkit_authority_check_authorization_finish ((PolkitAuthority *) object, result, &error); /* If the call is already canceled do nothing */ if (!call->cancellable) { g_clear_error (&error); g_clear_object (&pk_result); auth_call_free (call); return; } if (error) { if (!call->chain->error) call->chain->error = g_error_copy (error); nm_log_warn (LOGD_CORE, "error requesting auth for %s: (%d) %s", call->permission, error->code, error->message); g_clear_error (&error); } else { guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; if (polkit_authorization_result_get_is_authorized (pk_result)) { /* Caller has the permission */ call_result = NM_AUTH_CALL_RESULT_YES; } else if (polkit_authorization_result_get_is_challenge (pk_result)) { /* Caller could authenticate to get the permission */ call_result = NM_AUTH_CALL_RESULT_AUTH; } else call_result = NM_AUTH_CALL_RESULT_NO; nm_auth_chain_set_data (call->chain, call->permission, GUINT_TO_POINTER (call_result), NULL); g_object_unref (pk_result); } auth_call_complete (call); }
gboolean nm_auth_chain_add_call (NMAuthChain *self, const char *permission, gboolean allow_interaction) { AuthCall *call; g_return_val_if_fail (self != NULL, FALSE); #if WITH_POLKIT /* Non-root always gets authenticated when using polkit */ if (self->user_uid > 0) return _add_call_polkit (self, permission, allow_interaction); #endif /* Root user or non-polkit always gets the permission */ call = auth_call_new (self, permission); nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); return TRUE; }