diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index e6e7d568..2c8aba57 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -60,6 +60,8 @@ GType flatpak_deploy_get_type (void); #define FLATPAK_CLI_UPDATE_INTERVAL_MS 300 +typedef struct _PolkitSubject PolkitSubject; + typedef struct { FlatpakDecomposed *ref; @@ -1022,9 +1024,8 @@ char ** flatpak_dir_get_default_locale_languages (Fla char ** flatpak_dir_get_locales (FlatpakDir *self); char ** flatpak_dir_get_locale_languages (FlatpakDir *self); char ** flatpak_dir_get_locale_subpaths (FlatpakDir *self); -void flatpak_dir_set_source_pid (FlatpakDir *self, - pid_t pid); -pid_t flatpak_dir_get_source_pid (FlatpakDir *self); +void flatpak_dir_set_subject (FlatpakDir *self, + PolkitSubject *subject); gboolean flatpak_dir_delete_mirror_refs (FlatpakDir *self, gboolean dry_run, GCancellable *cancellable, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 12aca23e..9a0cc84a 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -249,7 +249,7 @@ struct FlatpakDir GFile *cache_dir; gboolean no_system_helper; gboolean no_interaction; - pid_t source_pid; + PolkitSubject *subject; GDBusConnection *system_helper_bus; @@ -3216,6 +3216,7 @@ flatpak_dir_finalize (GObject *object) g_clear_pointer (&self->remote_filters, g_hash_table_unref); g_clear_pointer (&self->masked, g_regex_unref); g_clear_pointer (&self->pinned, g_regex_unref); + g_clear_object (&self->subject); G_OBJECT_CLASS (flatpak_dir_parent_class)->finalize (object); } @@ -9107,9 +9108,8 @@ flatpak_dir_check_parental_controls (FlatpakDir *self, /* Assume that root is allowed to install any ref and shouldn't have any * parental controls restrictions applied to them. Note that this branch * must not be taken if this code is running within the system-helper, as that - * runs as root but on behalf of another process. If running within the - * system-helper, self->source_pid is non-zero. */ - if (self->source_pid == 0 && getuid () == 0) + * runs as root but on behalf of another process. */ + if (!self->subject && getuid () == 0) { g_info ("Skipping parental controls check for %s due to running as root", ref); return TRUE; @@ -9141,13 +9141,25 @@ flatpak_dir_check_parental_controls (FlatpakDir *self, return FALSE; } - if (self->user || self->source_pid == 0) - subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); - else - subject = polkit_unix_process_new_for_owner (self->source_pid, 0, -1); + if (self->subject) + { + g_autoptr(PolkitSubject) process_subject = NULL; + + subject = g_object_ref (self->subject); + /* This internally uses dbus GetConnectionCredentials which ensures we + * get the right UID. We should *not* use it for authorization via the + * PID though! */ + process_subject = + polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), + cancellable, NULL); + subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (process_subject)); + } + else + { + subject_uid = getuid (); + subject = polkit_unix_process_new_for_owner (getpid (), 0, subject_uid); + } - /* Get the parental controls for the invoking user. */ - subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); if (subject_uid == -1) { g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED, @@ -9155,6 +9167,8 @@ flatpak_dir_check_parental_controls (FlatpakDir *self, return FALSE; } + g_assert (subject != NULL); + manager = mct_manager_new (dbus_connection); manager_flags = MCT_MANAGER_GET_VALUE_FLAGS_NONE; if (!flatpak_dir_get_no_interaction (self)) @@ -17016,16 +17030,10 @@ flatpak_dir_get_locale_subpaths (FlatpakDir *self) } void -flatpak_dir_set_source_pid (FlatpakDir *self, - pid_t pid) +flatpak_dir_set_subject (FlatpakDir *self, + PolkitSubject *subject) { - self->source_pid = pid; -} - -pid_t -flatpak_dir_get_source_pid (FlatpakDir *self) -{ - return self->source_pid; + g_set_object (&self->subject, subject); } static void @@ -17045,7 +17053,7 @@ static void { #ifdef HAVE_LIBSYSTEMD const char *installation = source ? source : flatpak_dir_get_name_cached (self); - pid_t source_pid = flatpak_dir_get_source_pid (self); + const char *subject = self->subject ? polkit_subject_to_string (self->subject) : "(none)"; char message[1024]; int len; va_list args; @@ -17061,7 +17069,7 @@ static void */ sd_journal_send ("MESSAGE_ID=" FLATPAK_MESSAGE_ID, "PRIORITY=5", - "OBJECT_PID=%d", source_pid, + "SUBJECT=%s", subject, "CODE_FILE=%s", file, "CODE_LINE=%d", line, "CODE_FUNC=%s", func, diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index 00063783..ff70bad6 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -226,56 +226,6 @@ schedule_idle_callback (void) G_UNLOCK (idle); } -#define DBUS_NAME_DBUS "org.freedesktop.DBus" -#define DBUS_INTERFACE_DBUS DBUS_NAME_DBUS -#define DBUS_PATH_DBUS "/org/freedesktop/DBus" - -static int -get_sender_pid (GDBusMethodInvocation *invocation) -{ - g_autoptr(GDBusMessage) msg = NULL; - g_autoptr(GDBusMessage) reply = NULL; - GDBusConnection *connection; - const char *sender; - GVariant *body; - g_autoptr(GVariantIter) iter = NULL; - const char *key; - g_autoptr(GVariant) value = NULL; - - connection = g_dbus_method_invocation_get_connection (invocation); - sender = g_dbus_method_invocation_get_sender (invocation); - - msg = g_dbus_message_new_method_call (DBUS_NAME_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetConnectionCredentials"); - g_dbus_message_set_body (msg, g_variant_new ("(s)", sender)); - - reply = g_dbus_connection_send_message_with_reply_sync (connection, msg, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, - 30000, - NULL, - NULL, - NULL); - if (reply == NULL) - return 0; - - if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR) - return 0; - - body = g_dbus_message_get_body (reply); - - g_variant_get (body, "(a{sv})", &iter); - while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) - { - if (strcmp (key, "ProcessID") == 0) - return g_variant_get_uint32 (value); - } - value = NULL; /* g_variant_iter_loop freed it */ - - return 0; -} - static FlatpakDir * dir_get_system (const char *installation, GDBusMethodInvocation *invocation, @@ -283,7 +233,8 @@ dir_get_system (const char *installation, GError **error) { FlatpakDir *system = NULL; - pid_t source_pid = invocation ? get_sender_pid (invocation) : 0; + const char *sender; + g_autoptr(AutoPolkitSubject) subject = NULL; if (installation != NULL && *installation != '\0') system = flatpak_dir_get_system_by_id (installation, NULL, error); @@ -294,7 +245,10 @@ dir_get_system (const char *installation, if (system == NULL) return NULL; - flatpak_dir_set_source_pid (system, source_pid); + sender = g_dbus_method_invocation_get_sender (invocation); + subject = polkit_system_bus_name_new (sender); + + flatpak_dir_set_subject (system, subject); flatpak_dir_set_no_system_helper (system, TRUE); flatpak_dir_set_no_interaction (system, no_interaction);