diff -pruN 22.08.8-1/debian/accountsservice.install 22.08.8-1ubuntu1/debian/accountsservice.install
--- 22.08.8-1/debian/accountsservice.install	2022-05-26 17:39:09.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/accountsservice.install	2022-05-27 07:22:02.000000000 +0000
@@ -2,6 +2,7 @@ lib
 usr/libexec
 usr/share/accountsservice/user-templates
 usr/share/dbus-1
+usr/share/language-tools
 usr/share/locale
 usr/share/polkit-1
 var
diff -pruN 22.08.8-1/debian/changelog 22.08.8-1ubuntu1/debian/changelog
--- 22.08.8-1/debian/changelog	2022-05-26 22:07:53.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/changelog	2022-05-27 08:45:46.000000000 +0000
@@ -1,3 +1,39 @@
+accountsservice (22.08.8-1ubuntu1) kinetic; urgency=medium
+
+  * Merge with Debian, remaining Ubuntu changes:
+  * debian/control:
+    - Add build-depends on dh-translations
+  * debian/rules:
+    - Build with translations to update POT file.
+    - set -Dextra_admin_groups to add admin users to the same groups
+      than user-setup is using for the initial account
+    - We use custom.conf, not daemon.conf
+  * debian/libaccountsservice0.symbols:
+    - Add symbols added from patches.
+  * debian/accountsservice.install:
+    - Install language-tools scripts.
+  * debian/patches/0001-formats-locale-property.patch:
+    - Addition of FormatsLocale property and SetFormatsLocale method.
+  * debian/patches/0005-gdm_config_file_path.patch:
+    - Disabled, as we are using custom.conf.
+  * debian/patches/0009-language-tools.patch,
+    debian/patches/0010-set-language.patch:
+    - Save user language and regional formats settings to
+      ~/.pam_environment.
+  * debian/patches/0011-add-background-file-support.patch:
+    - Add support for a BackgroundFile property, similar to IconFile.
+  * debian/patches/0012-add-keyboard-layout-support.patch:
+    - Add XKeyboardLayouts property to report a user's keyboard layouts.
+  * debian/patches/0013-add-has-message-support.patch:
+    - Add XHasMessages property to report if a user had unread messages.
+  * debian/patches/0016-add-input-sources-support.patch:
+    - Store input sources in the user object.
+  * debian/patches/0021-support-extrausers.patch:
+    - In addition to watching /etc/{passwd,shadow,group}, also watch
+      those same files in /var/lib/extrausers/, if they exist.
+
+ -- Gunnar Hjalmarsson <gunnarhj@ubuntu.com>  Fri, 27 May 2022 10:45:46 +0200
+
 accountsservice (22.08.8-1) unstable; urgency=medium
 
   * Team upload
@@ -12,6 +48,60 @@ accountsservice (22.08.8-1) unstable; ur
 
  -- Gunnar Hjalmarsson <gunnarhj@debian.org>  Fri, 27 May 2022 00:07:53 +0200
 
+accountsservice (22.07.5-2ubuntu2) kinetic; urgency=medium
+
+  [ Marc Deslauriers ]
+  * SECURITY UPDATE: accountsservice incorrect privilege dropping
+    (LP: #1974250)
+    - debian/patches/0009-language-tools.patch: updated to not reset
+      effective uid, and migrate root-owned .pam_environment file.
+    - This change was originally known as CVE-2020-16126 and got reverted
+      by mistake in 0.6.55-3ubuntu1.
+    - CVE-2022-1804
+  * Fix FTBFS with a newer python-dbusmock package:
+    - debian/patches/adduser_invocation.patch: fix invocation of AddUser in
+      tests/dbusmock/accounts_service.py.
+    - debian/patches/setlocked_signature.patch: fix the signature for the
+      SetLocked call in tests/dbusmock/accounts_service.py.
+
+ -- Gunnar Hjalmarsson <gunnarhj@ubuntu.com>  Tue, 24 May 2022 19:53:07 +0200
+
+accountsservice (22.07.5-2ubuntu1) jammy; urgency=medium
+
+  * Merge with Debian, remaining Ubuntu changes:
+  * debian/control:
+    - Add build-depends on dh-translations
+  * debian/rules:
+    - Build with translations to update POT file.
+    - set -Dextra_admin_groups to add admin users to the same groups than
+      user-setup is using for the initial account
+    - We use custom.conf, not daemon.conf
+  * debian/libaccountsservice0.symbols:
+    - Add symbols added from patches.
+  * debian/patches/0001-formats-locale-property.patch:
+    - Addition of FormatsLocale property and SetFormatsLocale method.
+  * debian/patches/0005-gdm_config_file_path.patch:
+    - Disabled, as we are using custom.conf.
+  * debian/patches/0010-set-language.patch:
+    - Save user language and regional formats settings to ~/.pam_environment.
+  * debian/patches/0011-add-background-file-support.patch:
+    - Add support for a BackgroundFile property, similar to IconFile.
+  * debian/patches/0012-add-keyboard-layout-support.patch:
+    - Add XKeyboardLayouts property to report a user's keyboard layouts.
+  * debian/patches/0013-add-has-message-support.patch:
+    - Add XHasMessages property to report if a user had unread messages.
+  * debian/patches/0016-add-input-sources-support.patch:
+    - Store input sources in the user object.
+  * debian/patches/0021-support-extrausers.patch:
+    - In addition to watching /etc/{passwd,shadow,group}, also watch those
+      same files in /var/lib/extrausers/, if they exist.
+  * debian/patches/gitlab_change_types.patch:
+    - fix changing account types failing on missing groups
+  * debian/patches/gitlab_shared_tmp.patch:
+    - don't use a private tmp since API clients sometime store files there
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Tue, 22 Feb 2022 16:27:56 +0100
+
 accountsservice (22.07.5-2) unstable; urgency=medium
 
   * d/p/0002-create-and-manage-groups-like-on-a-debian-system.patch:
diff -pruN 22.08.8-1/debian/control 22.08.8-1ubuntu1/debian/control
--- 22.08.8-1/debian/control	2022-05-26 21:56:53.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/control	2022-05-27 07:04:58.000000000 +0000
@@ -1,9 +1,11 @@
 Source: accountsservice
 Section: admin
 Priority: optional
-Maintainer: Debian freedesktop.org maintainers <pkg-freedesktop-maintainers@lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Debian freedesktop.org maintainers <pkg-freedesktop-maintainers@lists.alioth.debian.org>
 Uploaders: Emilio Pozuelo Monfort <pochu@debian.org>
 Build-Depends: debhelper-compat (= 13),
+               dh-translations,
                gobject-introspection (>= 0.9.12-4~),
                intltool,
                libdbus-1-dev (>= 1.9.18),
@@ -21,8 +23,10 @@ Build-Depends: debhelper-compat (= 13),
 Build-Depends-Indep: gtk-doc-tools <!nodoc>, libglib2.0-doc <!nodoc>
 Standards-Version: 4.6.1
 Homepage: https://www.freedesktop.org/wiki/Software/AccountsService/
-Vcs-Git: https://salsa.debian.org/freedesktop-team/accountsservice.git
-Vcs-Browser: https://salsa.debian.org/freedesktop-team/accountsservice
+Vcs-Git: https://salsa.debian.org/freedesktop-team/accountsservice.git -b ubuntu
+Vcs-Browser: https://salsa.debian.org/freedesktop-team/accountsservice/tree/ubuntu
+XS-Debian-Vcs-Git: https://salsa.debian.org/freedesktop-team/accountsservice.git
+XS-Debian-Vcs-Browser: https://salsa.debian.org/freedesktop-team/accountsservice
 
 Package: accountsservice
 Architecture: any
diff -pruN 22.08.8-1/debian/gbp.conf 22.08.8-1ubuntu1/debian/gbp.conf
--- 22.08.8-1/debian/gbp.conf	2022-05-26 14:50:28.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/gbp.conf	2022-05-27 07:04:03.000000000 +0000
@@ -1,3 +1,5 @@
 [DEFAULT]
 pristine-tar = True
+debian-branch = ubuntu
 compression = xz
+debian-tag = ubuntu/%(version)s
diff -pruN 22.08.8-1/debian/libaccountsservice0.symbols 22.08.8-1ubuntu1/debian/libaccountsservice0.symbols
--- 22.08.8-1/debian/libaccountsservice0.symbols	2022-05-26 21:28:38.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/libaccountsservice0.symbols	2022-05-27 07:04:58.000000000 +0000
@@ -61,15 +61,24 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_call_set_automatic_login@Base 0.6.18
  accounts_user_call_set_automatic_login_finish@Base 0.6.18
  accounts_user_call_set_automatic_login_sync@Base 0.6.18
+ accounts_user_call_set_background_file@Base 0.6.29
+ accounts_user_call_set_background_file_finish@Base 0.6.29
+ accounts_user_call_set_background_file_sync@Base 0.6.29
  accounts_user_call_set_email@Base 0.6.18
  accounts_user_call_set_email_finish@Base 0.6.18
  accounts_user_call_set_email_sync@Base 0.6.18
+ accounts_user_call_set_formats_locale@Base 0.6.29
+ accounts_user_call_set_formats_locale_finish@Base 0.6.29
+ accounts_user_call_set_formats_locale_sync@Base 0.6.29
  accounts_user_call_set_home_directory@Base 0.6.18
  accounts_user_call_set_home_directory_finish@Base 0.6.18
  accounts_user_call_set_home_directory_sync@Base 0.6.18
  accounts_user_call_set_icon_file@Base 0.6.18
  accounts_user_call_set_icon_file_finish@Base 0.6.18
  accounts_user_call_set_icon_file_sync@Base 0.6.18
+ accounts_user_call_set_input_sources@Base 0.6.40
+ accounts_user_call_set_input_sources_finish@Base 0.6.40
+ accounts_user_call_set_input_sources_sync@Base 0.6.40
  accounts_user_call_set_language@Base 0.6.18
  accounts_user_call_set_language_finish@Base 0.6.18
  accounts_user_call_set_language_sync@Base 0.6.18
@@ -109,15 +118,24 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_call_set_user_name@Base 0.6.18
  accounts_user_call_set_user_name_finish@Base 0.6.18
  accounts_user_call_set_user_name_sync@Base 0.6.18
+ accounts_user_call_set_xhas_messages@Base 0.6.29
+ accounts_user_call_set_xhas_messages_finish@Base 0.6.29
+ accounts_user_call_set_xhas_messages_sync@Base 0.6.29
+ accounts_user_call_set_xkeyboard_layouts@Base 0.6.29
+ accounts_user_call_set_xkeyboard_layouts_finish@Base 0.6.29
+ accounts_user_call_set_xkeyboard_layouts_sync@Base 0.6.29
  accounts_user_call_set_xsession@Base 0.6.18
  accounts_user_call_set_xsession_finish@Base 0.6.18
  accounts_user_call_set_xsession_sync@Base 0.6.18
  accounts_user_complete_get_password_expiration_policy@Base 0.6.45
  accounts_user_complete_set_account_type@Base 0.6.18
  accounts_user_complete_set_automatic_login@Base 0.6.18
+ accounts_user_complete_set_background_file@Base 0.6.29
  accounts_user_complete_set_email@Base 0.6.18
+ accounts_user_complete_set_formats_locale@Base 0.6.29
  accounts_user_complete_set_home_directory@Base 0.6.18
  accounts_user_complete_set_icon_file@Base 0.6.18
+ accounts_user_complete_set_input_sources@Base 0.6.40
  accounts_user_complete_set_language@Base 0.6.18
  accounts_user_complete_set_location@Base 0.6.18
  accounts_user_complete_set_locked@Base 0.6.18
@@ -131,10 +149,15 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_complete_set_shell@Base 0.6.18
  accounts_user_complete_set_user_expiration_policy@Base 22.08.8
  accounts_user_complete_set_user_name@Base 0.6.18
+ accounts_user_complete_set_xhas_messages@Base 0.6.29
+ accounts_user_complete_set_xkeyboard_layouts@Base 0.6.29
  accounts_user_complete_set_xsession@Base 0.6.18
+ accounts_user_dup_background_file@Base 0.6.29
  accounts_user_dup_email@Base 0.6.18
+ accounts_user_dup_formats_locale@Base 0.6.29
  accounts_user_dup_home_directory@Base 0.6.18
  accounts_user_dup_icon_file@Base 0.6.18
+ accounts_user_dup_input_sources@Base 0.6.40
  accounts_user_dup_language@Base 0.6.18
  accounts_user_dup_location@Base 0.6.18
  accounts_user_dup_login_history@Base 0.6.29
@@ -144,13 +167,17 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_dup_session_type@Base 0.6.55
  accounts_user_dup_shell@Base 0.6.18
  accounts_user_dup_user_name@Base 0.6.18
+ accounts_user_dup_xkeyboard_layouts@Base 0.6.29
  accounts_user_dup_xsession@Base 0.6.18
  accounts_user_emit_changed@Base 0.6.18
  accounts_user_get_account_type@Base 0.6.18
  accounts_user_get_automatic_login@Base 0.6.18
+ accounts_user_get_background_file@Base 0.6.29
  accounts_user_get_email@Base 0.6.18
+ accounts_user_get_formats_locale@Base 0.6.29
  accounts_user_get_home_directory@Base 0.6.18
  accounts_user_get_icon_file@Base 0.6.18
+ accounts_user_get_input_sources@Base 0.6.40
  accounts_user_get_language@Base 0.6.18
  accounts_user_get_local_account@Base 0.6.24
  accounts_user_get_location@Base 0.6.18
@@ -169,6 +196,8 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_get_type@Base 0.6.18
  accounts_user_get_uid@Base 0.6.18
  accounts_user_get_user_name@Base 0.6.18
+ accounts_user_get_xhas_messages@Base 0.6.29
+ accounts_user_get_xkeyboard_layouts@Base 0.6.29
  accounts_user_get_xsession@Base 0.6.18
  accounts_user_interface_info@Base 0.6.18
  accounts_user_override_properties@Base 0.6.18
@@ -181,9 +210,12 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_proxy_new_sync@Base 0.6.18
  accounts_user_set_account_type@Base 0.6.18
  accounts_user_set_automatic_login@Base 0.6.18
+ accounts_user_set_background_file@Base 0.6.29
  accounts_user_set_email@Base 0.6.18
+ accounts_user_set_formats_locale@Base 0.6.29
  accounts_user_set_home_directory@Base 0.6.18
  accounts_user_set_icon_file@Base 0.6.18
+ accounts_user_set_input_sources@Base 0.6.40
  accounts_user_set_language@Base 0.6.18
  accounts_user_set_local_account@Base 0.6.24
  accounts_user_set_location@Base 0.6.18
@@ -201,6 +233,8 @@ libaccountsservice.so.0 libaccountsservi
  accounts_user_set_system_account@Base 0.6.18
  accounts_user_set_uid@Base 0.6.18
  accounts_user_set_user_name@Base 0.6.18
+ accounts_user_set_xhas_messages@Base 0.6.29
+ accounts_user_set_xkeyboard_layouts@Base 0.6.29
  accounts_user_set_xsession@Base 0.6.18
  accounts_user_skeleton_get_type@Base 0.6.18
  accounts_user_skeleton_new@Base 0.6.18
@@ -208,9 +242,12 @@ libaccountsservice.so.0 libaccountsservi
  act_user_collate@Base 0.6.8
  act_user_get_account_type@Base 0.6.8
  act_user_get_automatic_login@Base 0.6.8
+ act_user_get_background_file@Base 0.6.29
  act_user_get_email@Base 0.6.8
+ act_user_get_formats_locale@Base 0.6.29
  act_user_get_home_dir@Base 0.6.8
  act_user_get_icon_file@Base 0.6.8
+ act_user_get_input_sources@Base 0.6.40
  act_user_get_language@Base 0.6.8
  act_user_get_location@Base 0.6.8
  act_user_get_locked@Base 0.6.8
@@ -232,6 +269,8 @@ libaccountsservice.so.0 libaccountsservi
  act_user_get_type@Base 0.6.8
  act_user_get_uid@Base 0.6.8
  act_user_get_user_name@Base 0.6.8
+ act_user_get_x_has_messages@Base 0.6.29
+ act_user_get_x_keyboard_layouts@Base 0.6.29
  act_user_get_x_session@Base 0.6.8
  act_user_is_loaded@Base 0.6.8
  act_user_is_local_account@Base 0.6.24
@@ -265,8 +304,11 @@ libaccountsservice.so.0 libaccountsservi
  act_user_password_mode_get_type@Base 0.6.8
  act_user_set_account_type@Base 0.6.8
  act_user_set_automatic_login@Base 0.6.8
+ act_user_set_background_file@Base 0.6.29
  act_user_set_email@Base 0.6.8
+ act_user_set_formats_locale@Base 0.6.29
  act_user_set_icon_file@Base 0.6.8
+ act_user_set_input_sources@Base 0.6.40
  act_user_set_language@Base 0.6.8
  act_user_set_location@Base 0.6.8
  act_user_set_locked@Base 0.6.8
@@ -279,4 +321,6 @@ libaccountsservice.so.0 libaccountsservi
  act_user_set_session_type@Base 0.6.55
  act_user_set_user_expiration_policy@Base 22.08.8
  act_user_set_user_name@Base 0.6.8
+ act_user_set_x_has_messages@Base 0.6.29
+ act_user_set_x_keyboard_layouts@Base 0.6.29
  act_user_set_x_session@Base 0.6.8
diff -pruN 22.08.8-1/debian/patches/0001-formats-locale-property.patch 22.08.8-1ubuntu1/debian/patches/0001-formats-locale-property.patch
--- 22.08.8-1/debian/patches/0001-formats-locale-property.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0001-formats-locale-property.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,276 @@
+From 8fe53c3b9b65ddb720336ff6ff85ffd8a63819ca Mon Sep 17 00:00:00 2001
+From: Gunnar Hjalmarsson <ubuntu@gunnar.cc>
+Date: Thu, 21 Dec 2017 15:03:24 +1300
+Subject: [PATCH 01/12] Addition of FormatsLocale property and SetFormatsLocale
+ method
+
+---
+ data/org.freedesktop.Accounts.User.xml | 45 ++++++++++++++++++++
+ src/libaccountsservice/act-user.c      | 55 ++++++++++++++++++++++++
+ src/libaccountsservice/act-user.h      |  3 ++
+ src/user.c                             | 59 ++++++++++++++++++++++++++
+ 4 files changed, 162 insertions(+)
+
+Index: accountsservice/data/org.freedesktop.Accounts.User.xml
+===================================================================
+--- accountsservice.orig/data/org.freedesktop.Accounts.User.xml
++++ accountsservice/data/org.freedesktop.Accounts.User.xml
+@@ -150,6 +150,41 @@
+     </doc:doc>
+   </method>
+ 
++  <method name="SetFormatsLocale">
++    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++    <arg name="formats_locale" direction="in" type="s">
++      <doc:doc>
++        <doc:summary>
++          The new regional formats, as a locale specification like "de_DE.UTF-8".
++        </doc:summary>
++      </doc:doc>
++    </arg>
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          Sets the users regional formats.
++        </doc:para>
++      </doc:description>
++      <doc:permission>
++        The caller needs one of the following PolicyKit authorizations:
++        <doc:list>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
++            <doc:definition>To change his own language</doc:definition>
++          </doc:item>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
++            <doc:definition>To change the language of another user</doc:definition>
++          </doc:item>
++        </doc:list>
++      </doc:permission>
++      <doc:errors>
++        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
++        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
++      </doc:errors>
++    </doc:doc>
++  </method>
++
+   <method name="SetXSession">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+     <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_x_session"/>
+@@ -769,6 +804,16 @@
+         </doc:para>
+       </doc:description>
+     </doc:doc>
++  </property>
++
++  <property name="FormatsLocale" type="s" access="read">
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          The users regional formats, as a locale specification like "de_DE.UTF-8".
++        </doc:para>
++      </doc:description>
++    </doc:doc>
+   </property>
+ 
+   <property name="XSession" type="s" access="read">
+Index: accountsservice/src/libaccountsservice/act-user.c
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.c
++++ accountsservice/src/libaccountsservice/act-user.c
+@@ -91,6 +91,7 @@ enum {
+         PROP_LOGIN_HISTORY,
+         PROP_ICON_FILE,
+         PROP_LANGUAGE,
++        PROP_FORMATS_LOCALE,
+         PROP_X_SESSION,
+         PROP_IS_LOADED
+ };
+@@ -397,6 +398,13 @@ act_user_class_init (ActUserClass *class
+                                                               NULL,
+                                                               G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+         g_object_class_install_property (gobject_class,
++                                         PROP_FORMATS_LOCALE,
++                                         g_param_spec_string ("formats_locale",
++                                                              "Regional Formats",
++                                                              "User's regional formats.",
++                                                              NULL,
++                                                              G_PARAM_READABLE));
++        g_object_class_install_property (gobject_class,
+                                          PROP_X_SESSION,
+                                          g_param_spec_string ("x-session",
+                                                               "X session",
+@@ -1039,6 +1047,25 @@ act_user_get_language (ActUser *user)
+ }
+ 
+ /**
++ * act_user_get_formats_locale:
++ * @user: a #ActUser
++ *
++ * Returns the path to the configured formats locale of @user.
++ *
++ * Returns: (transfer none): a path to an icon
++ */
++const char *
++act_user_get_formats_locale (ActUser *user)
++{
++        g_return_val_if_fail (ACT_IS_USER (user), NULL);
++
++        if (user->accounts_proxy == NULL)
++                return NULL;
++
++        return accounts_user_get_formats_locale (user->accounts_proxy);
++}
++
++/**
+  * act_user_get_x_session:
+  * @user: a #ActUser
+  *
+@@ -1323,6 +1350,36 @@ act_user_get_password_expiration_policy
+                 return;
+         }
+ }
++
++/**
++ * act_user_set_formats_locale:
++ * @user: the user object to alter.
++ * @formats_locale: a locale (e.g. en_US.utf8)
++ *
++ * Assigns a new formats locale for @user.
++ *
++ * Note this function is synchronous and ignores errors.
++ **/
++void
++act_user_set_formats_locale (ActUser    *user,
++                             const char *formats_locale)
++{
++        g_autoptr(GError) error = NULL;
++
++        g_return_if_fail (ACT_IS_USER (user));
++        g_return_if_fail (formats_locale != NULL);
++        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
++
++        if (!accounts_user_call_set_formats_locale_sync (user->accounts_proxy,
++                                                         formats_locale,
++                                                         G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
++                                                        -1,
++                                                         NULL,
++                                                         &error)) {
++                g_warning ("SetFormatsLocale call failed: %s", error->message);
++                return;
++        }
++}
+ 
+ /**
+  * act_user_set_email:
+Index: accountsservice/src/libaccountsservice/act-user.h
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.h
++++ accountsservice/src/libaccountsservice/act-user.h
+@@ -72,6 +72,7 @@ gboolean       act_user_is_local_account
+ gboolean       act_user_is_nonexistent            (ActUser   *user);
+ const char    *act_user_get_icon_file             (ActUser   *user);
+ const char    *act_user_get_language              (ActUser   *user);
++const char    *act_user_get_formats_locale        (ActUser   *user);
+ const char    *act_user_get_x_session             (ActUser   *user);
+ const char    *act_user_get_session               (ActUser   *user);
+ const char    *act_user_get_session_type          (ActUser   *user);
+@@ -93,6 +94,8 @@ void           act_user_set_email
+                                                    const char *email);
+ void           act_user_set_language              (ActUser    *user,
+                                                    const char *language);
++void           act_user_set_formats_locale        (ActUser    *user,
++                                                   const char *formats_locale);
+ void           act_user_set_x_session             (ActUser    *user,
+                                                    const char *x_session);
+ void           act_user_set_session               (ActUser    *user,
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -524,6 +524,12 @@ user_update_from_keyfile (User     *user
+                 g_clear_pointer (&s, g_free);
+         }
+ 
++        s = g_key_file_get_string (keyfile, "User", "FormatsLocale", NULL);
++        if (s != NULL) {
++                accounts_user_set_formats_locale (ACCOUNTS_USER (user), s);
++                g_clear_pointer (&s, g_free);
++        }
++
+         s = g_key_file_get_string (keyfile, "User", "XSession", NULL);
+         if (s != NULL) {
+                 accounts_user_set_xsession (ACCOUNTS_USER (user), s);
+@@ -632,6 +638,9 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_session_type (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "SessionType", accounts_user_get_session_type (ACCOUNTS_USER (user)));
+ 
++        if (accounts_user_get_formats_locale (ACCOUNTS_USER (user)))
++                g_key_file_set_string (keyfile, "User", "FormatsLocale", accounts_user_get_formats_locale (ACCOUNTS_USER (user)));
++
+         if (accounts_user_get_xsession (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "XSession", accounts_user_get_xsession (ACCOUNTS_USER (user)));
+ 
+@@ -1453,6 +1462,54 @@ user_set_session_type (AccountsUser
+ }
+ 
+ static void
++user_change_formats_locale_authorized_cb (Daemon                *daemon,
++                                          User                  *user,
++                                          GDBusMethodInvocation *context,
++                                          gpointer               user_data)
++
++{
++        const gchar *formats_locale = user_data;
++
++        if (g_strcmp0 (accounts_user_get_formats_locale (ACCOUNTS_USER (user)), formats_locale) != 0) {
++                accounts_user_set_formats_locale (ACCOUNTS_USER (user), formats_locale);
++
++                save_extra_data (user);
++        }
++
++        accounts_user_complete_set_formats_locale (ACCOUNTS_USER (user), context);
++}
++
++static gboolean
++user_set_formats_locale (AccountsUser          *auser,
++                         GDBusMethodInvocation *context,
++                         const gchar           *formats_locale)
++{
++        User *user = (User*)auser;
++        int uid;
++        const gchar *action_id;
++
++        if (!get_caller_uid (context, &uid)) {
++                throw_error (context, ERROR_FAILED, "identifying caller failed");
++                return FALSE;
++        }
++
++        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
++                action_id = "org.freedesktop.accounts.change-own-user-data";
++        else
++                action_id = "org.freedesktop.accounts.user-administration";
++
++        daemon_local_check_auth (user->daemon,
++                                 user,
++                                 action_id,
++                                 user_change_formats_locale_authorized_cb,
++                                 context,
++                                 g_strdup (formats_locale),
++                                 (GDestroyNotify) g_free);
++
++        return TRUE;
++}
++
++static void
+ user_change_x_session_authorized_cb (Daemon                *daemon,
+                                      User                  *user,
+                                      GDBusMethodInvocation *context,
+@@ -2408,6 +2465,7 @@ user_accounts_user_iface_init (AccountsU
+         iface->handle_set_account_type = user_set_account_type;
+         iface->handle_set_automatic_login = user_set_automatic_login;
+         iface->handle_set_email = user_set_email;
++        iface->handle_set_formats_locale = user_set_formats_locale;
+         iface->handle_set_home_directory = user_set_home_directory;
+         iface->handle_set_icon_file = user_set_icon_file;
+         iface->handle_set_language = user_set_language;
diff -pruN 22.08.8-1/debian/patches/0007-add-lightdm-support.patch 22.08.8-1ubuntu1/debian/patches/0007-add-lightdm-support.patch
--- 22.08.8-1/debian/patches/0007-add-lightdm-support.patch	2022-05-26 14:50:28.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0007-add-lightdm-support.patch	2022-05-27 07:04:03.000000000 +0000
@@ -10,7 +10,7 @@ Index: accountsservice/src/daemon.c
 ===================================================================
 --- accountsservice.orig/src/daemon.c
 +++ accountsservice/src/daemon.c
-@@ -1515,11 +1515,11 @@
+@@ -1521,11 +1521,11 @@ daemon_local_check_auth (Daemon
          g_object_unref (subject);
  }
  
@@ -27,7 +27,7 @@ Index: accountsservice/src/daemon.c
  {
          g_autoptr(GKeyFile) keyfile = NULL;
          GError *local_error = NULL;
-@@ -1555,16 +1555,71 @@
+@@ -1561,16 +1561,71 @@ load_autologin (Daemon      *daemon,
  }
  
  static gboolean
@@ -102,7 +102,7 @@ Index: accountsservice/src/daemon.c
          keyfile = g_key_file_new ();
          if (!g_key_file_load_from_file (keyfile,
                                          PATH_GDM_CUSTOM,
-@@ -1586,6 +1641,53 @@
+@@ -1592,6 +1647,53 @@ save_autologin (Daemon      *daemon,
          return result;
  }
  
diff -pruN 22.08.8-1/debian/patches/0009-language-tools.patch 22.08.8-1ubuntu1/debian/patches/0009-language-tools.patch
--- 22.08.8-1/debian/patches/0009-language-tools.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0009-language-tools.patch	2022-05-27 07:33:11.000000000 +0000
@@ -0,0 +1,547 @@
+From: Gunnar Hjalmarsson <gunnarhj@ubuntu.com>
+Date: Thu, 21 Dec 2017 15:09:24 +1300
+Subject: [PATCH 05/12] Help files for dealing with language/locale settings.
+
+Updated: 2022-05-19
+
+---
+ data/langtools/Makefile.am         | 17 ++++++++
+ data/langtools/language-options    | 84 ++++++++++++++++++++++++++++++++++++++
+ data/langtools/language-validate   | 82 +++++++++++++++++++++++++++++++++++++
+ data/langtools/language2locale     | 70 +++++++++++++++++++++++++++++++
+ data/langtools/locale2papersize    | 18 ++++++++
+ data/langtools/main-countries      | 28 +++++++++++++
+ data/langtools/meson.build         | 25 ++++++++++++
+ data/langtools/save-to-pam-env     | 40 ++++++++++++++++++
+ data/langtools/set-language-helper | 27 ++++++++++++
+ data/langtools/update-langlist     | 48 ++++++++++++++++++++++
+ data/meson.build                   |  2 +
+ 11 files changed, 441 insertions(+)
+ create mode 100644 data/langtools/Makefile.am
+ create mode 100755 data/langtools/language-options
+ create mode 100755 data/langtools/language-validate
+ create mode 100755 data/langtools/language2locale
+ create mode 100755 data/langtools/locale2papersize
+ create mode 100644 data/langtools/main-countries
+ create mode 100644 data/langtools/meson.build
+ create mode 100755 data/langtools/save-to-pam-env
+ create mode 100755 data/langtools/set-language-helper
+ create mode 100755 data/langtools/update-langlist
+
+diff --git a/data/langtools/Makefile.am b/data/langtools/Makefile.am
+new file mode 100644
+index 0000000..ca345e0
+--- /dev/null
++++ b/data/langtools/Makefile.am
+@@ -0,0 +1,17 @@
++langtoolsdir = ${datadir}/language-tools
++
++install-data-hook:
++	if test '!' -d $(DESTDIR)$(langtoolsdir); then \
++		$(mkinstalldirs) $(DESTDIR)$(langtoolsdir); \
++		chmod 755 $(DESTDIR)$(langtoolsdir); \
++	fi
++
++	$(INSTALL_SCRIPT)  language-options          $(DESTDIR)$(langtoolsdir)/language-options
++	$(INSTALL_SCRIPT)  language-validate         $(DESTDIR)$(langtoolsdir)/language-validate
++	$(INSTALL_SCRIPT)  language2locale           $(DESTDIR)$(langtoolsdir)/language2locale
++	$(INSTALL_SCRIPT)  locale2papersize          $(DESTDIR)$(langtoolsdir)/locale2papersize
++	$(INSTALL_DATA)    main-countries            $(DESTDIR)$(langtoolsdir)/main-countries
++	$(INSTALL_SCRIPT)  save-to-pam-env           $(DESTDIR)$(langtoolsdir)/save-to-pam-env
++	$(INSTALL_SCRIPT)  set-language-helper       $(DESTDIR)$(langtoolsdir)/set-language-helper
++	$(INSTALL_SCRIPT)  update-langlist           $(DESTDIR)$(langtoolsdir)/update-langlist
++
+diff --git a/data/langtools/language-options b/data/langtools/language-options
+new file mode 100755
+index 0000000..b1cc1f3
+--- /dev/null
++++ b/data/langtools/language-options
+@@ -0,0 +1,84 @@
++#!/usr/bin/perl
++use strict;
++use warnings;
++
++my $langtoolsdir = '/usr/share/language-tools';
++
++# get the locales available on the system
++my @avail_locales = map { chomp; s/\.utf8//; $_ } qx( locale -a | grep -F .utf8 );
++
++# add items without country code to facilitate lookups
++my %extended_localelist;
++for my $loc (@avail_locales) {
++    ( my $lang = $loc ) =~ s/_[A-Z]+//;
++    @extended_localelist{$loc, $lang} = (1, 1);
++}
++
++# get the directory names in /usr/share/locale-langpack plus possible other
++# translation directory names in /usr/share/locale and /usr/local/share/locale
++my %translation_dirs;
++if ( opendir my ($dh), '/usr/share/locale-langpack' ) {
++    $translation_dirs{$_} = 1 for readdir $dh;
++}
++my %langpack_langcodes = map { s/[^a-z].+//; $_, 1 }
++                         grep !/^\./, keys %translation_dirs;
++for my $t_dir ('/usr/share/locale', '/usr/local/share/locale') {
++    if ( opendir my ($dh), $t_dir ) {
++        for ( readdir $dh ) {
++            for my $lang ( keys %langpack_langcodes ) {
++                if ( /^$lang[_@]/ ) {
++                    $translation_dirs{$_} = 1;
++                    last;
++                }
++            }
++        }
++    }
++}
++
++# Assume that 'en' is present even if the English language pack isn't installed
++if ( ! $translation_dirs{'en'} and "@avail_locales" =~ /\ben_US\b/ ) {
++    $translation_dirs{'en'} = 1;
++}
++
++# get the intersection of available translation_dirs and the extended locale list
++my %intersection;
++for ( keys %extended_localelist ) {
++    $intersection{$_} = 1 if $translation_dirs{$_};
++}
++
++# adjustments
++if ( open my $fh, '<', "$langtoolsdir/main-countries" ) {
++    # If country code items in a language exist:
++    # - Remove the item without country code, since gettext won't find a
++    #   translation under e.g. 'de_DE' if the first item in LANGUAGE is 'de'
++    #   (see https://launchpad.net/bugs/700213). 'en' is kept, though, since
++    #   it's always the last item in LANGUAGE per design.
++    # - Make sure that the main dialect of the language is represented among
++    #   the country code items (see https://launchpad.net/bugs/710148).
++    my %main;
++    while ( <$fh> ) {
++        next if /^\s*(?:#|$)/;
++        my ($k, $v) = split;
++        $main{$k} = $v;
++    }
++    my %count;
++    for ( keys %intersection ) {
++        next if /^en[^a-z]/;
++        ( my $not_country = $_ ) =~ s/_[A-Z]+//;
++        $count{$not_country} ++;
++    }
++    for my $langcode ( keys %count ) {
++        if ( $count{$langcode} > 1 ) {
++            delete $intersection{$langcode};
++            $intersection{ $main{$langcode} } = 1 if $main{$langcode};
++        }
++    }
++} else {
++    # not access to the language-to-main-dialect map
++    # => stick with a minimum of list manipulation
++    delete $intersection{'zh'};
++}
++
++# print the resulting list of language options
++print join("\n", sort keys %intersection) || 'en';
++
+diff --git a/data/langtools/language-validate b/data/langtools/language-validate
+new file mode 100755
+index 0000000..b87c132
+--- /dev/null
++++ b/data/langtools/language-validate
+@@ -0,0 +1,82 @@
++#!/bin/sh -pe
++
++lang=$1
++validated_language=
++
++test -n "$lang" || exit 1
++
++langtoolsdir=/usr/share/language-tools
++
++#
++# discard possible fallback languages
++#
++lang=${lang%%:*}
++
++#
++# remove possible encoding part
++#
++if [ $lang != ${lang%.utf8*} ]; then
++    lang=${lang%.*}${lang#*.utf8}
++elif [ $lang != ${lang%.UTF-8*} ]; then
++    lang=${lang%.*}${lang#*.UTF-8}
++fi
++
++#
++# make sure that the output is a valid language option
++#
++options=$( $langtoolsdir/language-options )
++
++# exact match
++for opt in $options; do
++    if [ $opt = $lang ]; then
++        validated_language=$lang
++        break
++    fi
++done
++
++if [ -z "$validated_language" ]; then
++    langcode=${lang%%[_@]*}
++
++    # try the "main" country code if any
++    main_country=
++    is_variant=false
++    while read line; do
++        if [ "${line%%[[:space:]]*}" = $langcode ]; then
++            main_country=${line##*[[:space:]]}
++            if [ $lang != ${lang#*@} ]; then
++                main_country=$main_country@${lang#*@}
++                is_variant=true
++            fi
++            break
++        fi
++    done < $langtoolsdir/main-countries
++    if [ -n "$main_country" ]; then
++        for opt in $options; do
++            if [ $main_country = $opt ]; then
++                validated_language=$main_country
++                break
++            fi
++        done
++    fi
++
++    # try out fitting language option without paying regard to
++    # country code
++    if [ -z "$validated_language" ]; then
++        for opt in $options; do
++            if [ "${opt%%[_@]*}" = $langcode -a $langcode != 'zh' ]; then
++                if $is_variant && [ $opt = ${opt#*@} ]; then
++                    continue
++                fi
++                validated_language=$opt
++                break
++            fi
++        done
++    fi
++fi
++
++if [ -z "$validated_language" ]; then
++    validated_language='en'
++fi
++
++echo $validated_language
++
+diff --git a/data/langtools/language2locale b/data/langtools/language2locale
+new file mode 100755
+index 0000000..874b357
+--- /dev/null
++++ b/data/langtools/language2locale
+@@ -0,0 +1,70 @@
++#!/bin/sh -pe
++#
++# - takes the first choice language in the LANGUAGE priority list as argument
++# - outputs locale name corresponding to that language
++
++lang=$1
++locale_name=
++
++test -n "$lang" || exit 1
++
++# remove codeset if any
++if [ "$lang" != "${lang%.*}" ]; then
++    lang=$( echo $lang | sed -r 's/([^.]+)[^@]+(.*)/\1\2/' )
++fi
++
++langtoolsdir=/usr/share/language-tools
++
++langcode=${lang%%[_@]*}
++locales=
++for loc in $( locale -a | grep -F .utf8 ); do
++    # skip locales for other languages
++    if [ $langcode = ${loc%%[._@]*} ]; then
++        loc=${loc%.*}${loc#*.utf8}
++        locales="$locales $loc"
++    fi
++done
++
++# exact match
++for loc in $locales; do
++    if [ $lang = $loc ]; then
++        locale_name=$( echo $loc | sed -r 's/([^@]+)/\1.UTF-8/' )
++        break
++    fi
++done
++
++if [ -z "$locale_name" -a $lang = ${lang%_[A-Z]*} ]; then
++
++    # try the "main" country code if any
++    main_country=
++    while read line; do
++        if [ "${line%%[[:space:]]*}" = $langcode ]; then
++            main_country=${line##*[[:space:]]}
++            if [ $lang != ${lang#*@} ]; then
++                main_country=$main_country@${lang#*@}
++            fi
++            break
++        fi
++    done < $langtoolsdir/main-countries
++    if [ -n "$main_country" ]; then
++        for loc in $locales; do
++            if [ $main_country = $loc ]; then
++                locale_name=$( echo $loc | sed -r 's/([^@]+)/\1.UTF-8/' )
++                break
++            fi
++        done
++    fi
++
++    # try out fitting locale with any country code
++    if [ -z "$locale_name" -a $langcode != 'zh' ]; then
++        for loc in $locales; do
++            if [ "${loc%%[_@]*}" = $langcode ]; then
++                locale_name=$( echo $loc | sed -r 's/([^@]+)/\1.UTF-8/' )
++                break
++            fi
++        done
++    fi
++fi
++
++echo $locale_name
++
+diff --git a/data/langtools/locale2papersize b/data/langtools/locale2papersize
+new file mode 100755
+index 0000000..3fcc13b
+--- /dev/null
++++ b/data/langtools/locale2papersize
+@@ -0,0 +1,18 @@
++#!/bin/sh -pe
++#
++# locale2papersize outputs the paper size "a4" or "letter" based on
++# the height and width in the locale that is passed as an argument.
++
++export LC_PAPER=$1
++
++height=$( locale height )
++width=$( locale width )
++
++if [ "$height" = 279 -a "$width" = 216 ]; then
++    size=letter
++else
++    size=a4
++fi
++
++echo $size
++
+diff --git a/data/langtools/main-countries b/data/langtools/main-countries
+new file mode 100644
+index 0000000..c6bbd32
+--- /dev/null
++++ b/data/langtools/main-countries
+@@ -0,0 +1,28 @@
++# If multiple country codes are present among the available locales for
++# a language, we may want to map the language code to the language's
++# main or origin country. The list below aims to serve that purpose.
++#
++aa	aa_ET
++ar	ar_EG
++bn	bn_BD
++ca	ca_ES
++de	de_DE
++el	el_GR
++en	en_US
++es	es_ES
++eu	eu_ES
++fr	fr_FR
++fy	fy_NL
++it	it_IT
++li	li_NL
++nl	nl_NL
++om	om_ET
++pa	pa_PK
++pt	pt_PT
++ru	ru_RU
++so	so_SO
++sr	sr_RS
++sv	sv_SE
++ti	ti_ER
++tr	tr_TR
++
+diff --git a/data/langtools/meson.build b/data/langtools/meson.build
+new file mode 100644
+index 0000000..ed024a7
+--- /dev/null
++++ b/data/langtools/meson.build
+@@ -0,0 +1,25 @@
++langtools_dir = join_paths(get_option('datadir'), 'language-tools')
++
++scripts = files(
++  'language-options',
++  'language-validate',
++  'language2locale',
++  'locale2papersize',
++  'save-to-pam-env',
++  'set-language-helper',
++  'update-langlist'
++)
++
++install_data(
++  scripts,
++  install_dir: langtools_dir,
++)
++
++data = files(
++  'main-countries'
++)
++
++install_data(
++  data,
++  install_dir: langtools_dir,
++)
+diff --git a/data/langtools/save-to-pam-env b/data/langtools/save-to-pam-env
+new file mode 100755
+index 0000000..2492957
+--- /dev/null
++++ b/data/langtools/save-to-pam-env
+@@ -0,0 +1,48 @@
++#!/bin/sh -pe
++#
++# updates the ~/.pam_environment config file
++
++homedir=$1
++locale_name=$2
++language_list=$3
++
++[ -n "$homedir" -a -n "$locale_name" ] || exit 1
++
++langtoolsdir=/usr/share/language-tools
++
++# Fix incorrect permissions caused by CVE-2022-1804
++if [ -f "$homedir/.pam_environment" -a ! -w "$homedir/.pam_environment" ]; then
++    temp=$(mktemp -u 'XXXXXXXX')
++    mv "$homedir/.pam_environment" "$homedir/.pam_environment.$temp"
++    cp "$homedir/.pam_environment.$temp" "$homedir/.pam_environment"
++    rm -f "$homedir/.pam_environment.$temp"
++fi
++
++# create ~/.pam_environment if it doesn't exist
++touch "$homedir/.pam_environment" || exit 1
++
++save_to_pam_env() {
++    var=$1; value=$2
++    if [ "$( grep -E "^$var(\s+DEFAULT|=)" .pam_environment )" ]; then
++        sed -r -i "s/^$var(\s+DEFAULT|=).*/$var\tDEFAULT=$value/" .pam_environment
++    else
++        echo "$var\tDEFAULT=$value" >> .pam_environment
++    fi
++}
++
++cd "$homedir"
++if [ -n "$language_list" ]; then
++    save_to_pam_env 'LANGUAGE' $language_list
++    save_to_pam_env 'LANG' $locale_name
++else
++    for var in 'LC_NUMERIC' 'LC_TIME' 'LC_MONETARY' 'LC_PAPER' 'LC_NAME' \
++               'LC_ADDRESS' 'LC_TELEPHONE' 'LC_MEASUREMENT' 'LC_IDENTIFICATION'; do
++        save_to_pam_env $var $locale_name
++    done
++    papersize=$( $langtoolsdir/locale2papersize $locale_name )
++    save_to_pam_env 'PAPERSIZE' $papersize
++    echo $locale_name
++fi
++
++exit 0
++
+diff --git a/data/langtools/set-language-helper b/data/langtools/set-language-helper
+new file mode 100755
+index 0000000..efbb394
+--- /dev/null
++++ b/data/langtools/set-language-helper
+@@ -0,0 +1,27 @@
++#!/bin/sh -pe
++
++homedir=$1
++language=$2
++validated_language=
++
++[ -n "$language" -a -n "$homedir" ] || exit 1
++
++langtoolsdir=/usr/share/language-tools
++
++validated_language=$( $langtoolsdir/language-validate $language )
++
++if ! dpkg -l language-selector-gnome > /dev/null 2>&1; then
++    renewed_langlist=$validated_language
++elif [ $language = "${language%:*}" ]; then
++    renewed_langlist=$( $langtoolsdir/update-langlist $validated_language "$homedir" )
++else
++    # $language contains a priority list
++    renewed_langlist=$validated_language:${language#*:}
++fi
++
++locale_name=$( $langtoolsdir/language2locale $validated_language )
++
++( $langtoolsdir/save-to-pam-env "$homedir" $locale_name $renewed_langlist ) || exit 1
++
++echo $validated_language
++
+diff --git a/data/langtools/update-langlist b/data/langtools/update-langlist
+new file mode 100755
+index 0000000..317a60b
+--- /dev/null
++++ b/data/langtools/update-langlist
+@@ -0,0 +1,48 @@
++#!/bin/sh -pe
++#
++# update-langlist maintains the LANGUAGE priority list. It does so in
++# a simplified manner, unlike the UI in language-selector-gnome for
++# setting the user language which provides full control.
++
++first_language=$1
++homedir=$2
++renewed_langlist=
++
++[ -n "$first_language" -a -n "$homedir" ] || exit 1
++
++get_old_langlist() {
++    if [ -r "$homedir/.pam_environment" ]; then
++        while read line; do
++            if [ "$( echo "${line%=*}" | sed -r 's/\s+DEFAULT$//' )" = 'LANGUAGE' ]; then
++                old_langlist=${line#*=}
++                break
++            fi
++        done < $homedir/.pam_environment
++    fi
++}
++
++old_langlist=
++english=true
++if [ ${first_language%%[_@]*} != 'en' ]; then
++    get_old_langlist
++    english=false
++fi
++
++if [ -n "$old_langlist" ] && ! $english; then
++    if expr $old_langlist : ".*:$first_language:" > /dev/null ; then
++        renewed_langlist=$( echo $old_langlist | sed -r "s/(.+:)($first_language:)/\2\1/" )
++    elif [ ${old_langlist%%:*} = $first_language ]; then
++        # no change
++        renewed_langlist=$old_langlist
++    else
++        renewed_langlist=$first_language:$old_langlist
++    fi
++else
++    # build fresh list with 'en' as the last element
++    # no other languages needed if English was selected
++    renewed_langlist=$first_language
++    [ $first_language != 'en' ] && renewed_langlist=$renewed_langlist:en
++fi
++
++echo $renewed_langlist
++
+diff --git a/data/meson.build b/data/meson.build
+index 4987937..58ee672 100644
+--- a/data/meson.build
++++ b/data/meson.build
+@@ -61,3 +61,5 @@ install_data(
+   'standard',
+   install_dir: join_paths(act_datadir, 'accountsservice', 'user-templates'),
+ )
++
++subdir('langtools')
diff -pruN 22.08.8-1/debian/patches/0010-set-language.patch 22.08.8-1ubuntu1/debian/patches/0010-set-language.patch
--- 22.08.8-1/debian/patches/0010-set-language.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0010-set-language.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,490 @@
+From a2646ae602a1eb01d260ee88f2ced0c6a51226ba Mon Sep 17 00:00:00 2001
+From: Gunnar Hjalmarsson <gunnarhj@ubuntu.com>
+Date: Fri, 09 Oct 2020 13:29:00 +0200
+Subject: [PATCH 06/12] Save user language and regional formats settings to
+ ~/.pam_environment.
+
+Updated: 2021-11-09
+
+---
+ src/user.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 384 insertions(+), 5 deletions(-)
+
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -27,6 +27,7 @@
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <fcntl.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+ #include <grp.h>
+@@ -620,6 +621,8 @@ user_update_system_account_property (Use
+         accounts_user_set_system_account (ACCOUNTS_USER (user), system);
+ }
+ 
++static gboolean is_in_pam_environment (User *user, const gchar *property);
++
+ static void
+ user_save_to_keyfile (User     *user,
+                       GKeyFile *keyfile)
+@@ -629,7 +632,7 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_email (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "Email", accounts_user_get_email (ACCOUNTS_USER (user)));
+ 
+-        if (accounts_user_get_language (ACCOUNTS_USER (user)))
++        if (accounts_user_get_language (ACCOUNTS_USER (user)) && is_in_pam_environment (user, "Language"))
+                 g_key_file_set_string (keyfile, "User", "Language", accounts_user_get_language (ACCOUNTS_USER (user)));
+ 
+         if (accounts_user_get_session (ACCOUNTS_USER (user)))
+@@ -638,7 +641,7 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_session_type (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "SessionType", accounts_user_get_session_type (ACCOUNTS_USER (user)));
+ 
+-        if (accounts_user_get_formats_locale (ACCOUNTS_USER (user)))
++        if (accounts_user_get_formats_locale (ACCOUNTS_USER (user)) && is_in_pam_environment (user, "FormatsLocale"))
+                 g_key_file_set_string (keyfile, "User", "FormatsLocale", accounts_user_get_formats_locale (ACCOUNTS_USER (user)));
+ 
+         if (accounts_user_get_xsession (ACCOUNTS_USER (user)))
+@@ -1037,6 +1040,8 @@ user_changed (User *user)
+         accounts_user_emit_changed (ACCOUNTS_USER (user));
+ }
+ 
++static gchar *user_get_fallback_value (User *user, const gchar *property);
++
+ User *
+ user_new (Daemon *daemon,
+           uid_t   uid)
+@@ -1047,6 +1052,9 @@ user_new (Daemon *daemon,
+         user->daemon = daemon;
+         accounts_user_set_uid (ACCOUNTS_USER (user), uid);
+ 
++        accounts_user_set_language (ACCOUNTS_USER (user), user_get_fallback_value (user, "Language"));
++        accounts_user_set_formats_locale (ACCOUNTS_USER (user), user_get_fallback_value (user, "FormatsLocale"));
++
+         return user;
+ }
+ 
+@@ -1315,6 +1323,357 @@ user_set_email (AccountsUser          *a
+         return TRUE;
+ }
+ 
++static gboolean
++user_drop_privileges_to_user (User *user)
++{
++        if (setresgid (-1, user->gid, -1) != 0) {
++                g_warning ("setresgid() failed");
++                return FALSE;
++        }
++        if (setresuid (-1, accounts_user_get_uid (ACCOUNTS_USER (user)), -1) != 0) {
++                g_warning ("setresuid() failed");
++                return FALSE;
++        }
++        return TRUE;
++}
++
++static void
++user_regain_privileges ()
++{
++        if (setresuid (0, 0, -1) != 0)
++                g_warning ("setresuid() failed");
++        if (setresgid (0, 0, -1) != 0)
++                g_warning ("setresgid() failed");
++}
++
++static gchar *
++user_locale_utf8_fix (const gchar *locale)
++{
++        if (locale == NULL || !g_strrstr (locale, ".utf8"))
++                return g_strdup (locale);
++
++        gchar **tokens = g_strsplit_set (locale, ".8", 3);
++        gchar *fixed_locale = g_strconcat (tokens[0], ".UTF-8", tokens[2], NULL);
++        g_strfreev (tokens);
++
++        return fixed_locale;
++}
++
++static gchar *
++user_language_validate (User        *user,
++                        const gchar *lang)
++{
++        gboolean     ret;
++        const gchar *program = "/usr/share/language-tools/language-validate";
++        gchar       *command = g_strconcat (program, " ", lang, NULL);
++        gchar       *validated_language;
++        GError      *error = NULL;
++
++        if (!user_drop_privileges_to_user (user))
++                return NULL;
++        ret = g_spawn_command_line_sync (command, &validated_language, NULL, NULL, &error);
++        user_regain_privileges ();
++
++        g_free (command);
++        if (!ret) {
++                g_warning ("Couldn't get validated language: %s", error->message);
++                g_error_free (error);
++                return NULL;
++        }
++        return g_strchomp (validated_language);
++}
++
++static gchar *
++user_locale_validate (User                  *user,
++                      const gchar           *locale,
++                      GDBusMethodInvocation *context)
++{
++        gchar    *validated_locale = NULL;
++        gchar    *tmp_locale = NULL;
++        gchar    *tmp_locale_utf8 = NULL;
++        gboolean  ret = FALSE;
++        gchar    *output = NULL;
++        GError   *error = NULL;
++        gboolean  found = FALSE;
++
++        if (locale == NULL || strlen (locale) < 2)
++                goto out;
++        tmp_locale = g_strdup (locale);
++        g_strchomp (tmp_locale);
++
++        /* When a new language has been installed, we want to be able to instantly
++           set a locale for that language to denote the regional formats. For that
++           reason we make use of 'locale -a' instead of calling setlocale(). */
++
++        if (!user_drop_privileges_to_user (user))
++                goto out;
++        ret = g_spawn_command_line_sync ("locale -a", &output, NULL, NULL, &error);
++        user_regain_privileges ();
++        if (!ret) {
++                throw_error (context, ERROR_FAILED, "Failed to run 'locale -a': %s", error->message);
++                g_clear_error (&error);
++                goto out;
++        }
++
++        /* Replace 'UTF-8' with 'utf8' since 'locale -a' outputs the latter. */
++        tmp_locale_utf8 = g_strdup (tmp_locale);
++        if (g_strrstr (tmp_locale_utf8, ".UTF-8")) {
++                gchar **tokens = g_strsplit_set (tmp_locale_utf8, ".8", 3);
++                g_free (tmp_locale_utf8);
++                tmp_locale_utf8 = g_strconcat (tokens[0], ".utf8", tokens[2], NULL);
++                g_strfreev (tokens);
++        }
++
++        gchar **tokens;
++        int i;
++        g_strchomp (output);
++        tokens = g_strsplit (output, "\n", -1);
++        for (i = 0; tokens[i]; i++) {
++                if (g_strcmp0 (tokens[i], "C") == 0 ||
++                    g_strcmp0 (tokens[i], "C.UTF-8") == 0 ||
++                    g_strcmp0 (tokens[i], "POSIX") == 0)
++                        continue;
++
++                if (g_strcmp0 (tokens[i], tmp_locale_utf8) == 0) {
++                        found = TRUE;
++                        break;
++                }
++        }
++        g_strfreev (tokens);
++
++        if (!found && g_strcmp0 (tmp_locale, "C.UTF-8") != 0) {
++                throw_error (context, ERROR_FAILED, "'%s' is not a valid locale name", tmp_locale);
++                goto out;
++        }
++        validated_locale = user_locale_utf8_fix (tmp_locale);
++
++out:
++        g_free (tmp_locale);
++        g_free (tmp_locale_utf8);
++        g_free (output);
++
++        return validated_locale;
++}
++
++static gchar *
++strip_quotes (const gchar *str)
++{
++        if ((g_str_has_prefix (str, "\"") && g_str_has_suffix (str, "\""))
++          || (g_str_has_prefix (str, "'") && g_str_has_suffix (str, "'")))
++                return g_strndup (str + 1, strlen (str) - 2);
++        else
++                return g_strdup (str);
++}
++
++static gchar *
++user_get_fallback_value (User        *user,
++                         const gchar *property)
++{
++        static gchar *system_language;
++        static gchar *system_formats_locale;
++
++        if (g_strcmp0 (property, "Language") == 0 && system_language)
++                return system_language;
++        if (g_strcmp0 (property, "FormatsLocale") == 0 && system_formats_locale)
++                return system_formats_locale;
++
++        gchar *fallback_value = NULL;
++        gchar *language = NULL;
++        gchar *lang = NULL;
++        gchar *lctime = NULL;
++
++        FILE  *fp;
++        if ((fp = fopen ("/etc/default/locale", "r"))) {
++                gchar line[50];
++                while ((fgets (line, 50, fp)) != NULL) {
++                        g_strchomp (line);
++                        if (g_str_has_prefix (line, "LANGUAGE="))
++                                language = strip_quotes (line + strlen ("LANGUAGE="));
++                        else if (g_str_has_prefix (line, "LANG="))
++                                lang = strip_quotes (line + strlen ("LANG="));
++                        else if (g_str_has_prefix (line, "LC_TIME="))
++                                lctime = strip_quotes (line + strlen ("LC_TIME="));
++                }
++                fclose (fp);
++        }
++
++        if (g_strcmp0 (property, "Language") == 0) {
++                gchar *tmp = NULL;
++                if (language)
++                        tmp = language;
++                else if (lang)
++                        tmp = lang;
++                system_language = user_language_validate (user, tmp);
++                fallback_value = system_language;
++        }
++
++        if (g_strcmp0 (property, "FormatsLocale") == 0) {
++                gchar *tmp = NULL;
++                if (lctime)
++                        tmp = lctime;
++                else if (lang)
++                        tmp = lang;
++                system_formats_locale = user_locale_utf8_fix (tmp);
++                fallback_value = system_formats_locale;
++        }
++
++        g_free (language);
++        g_free (lang);
++        g_free (lctime);
++
++        return fallback_value;
++}
++
++static gchar *
++user_update_environment (User                  *user,
++                         gchar                 *data,
++                         const gchar           *script,
++                         GDBusMethodInvocation *context)
++
++/* This function updates ~/.pam_environment by means of the help files in /usr/share/language-tools. */
++{
++        gchar        *program;
++        gchar        *validated_data = NULL;
++        gint          i;
++        const gchar  *allowed_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._+-:/ @";
++        gboolean      ret;
++        GError       *error = NULL;
++
++        if (data == NULL)
++               return NULL;
++
++        program = g_build_path ("/", "/usr/share/language-tools", script, NULL);
++        const gchar *command[] = { program, accounts_user_get_home_directory (ACCOUNTS_USER (user)), data, NULL };
++
++        /* test for odd characters in arguments */
++        for (i = 1; i <= 2; i++) {
++                if (strlen (command[i]) != strspn (command[i], allowed_chars)) {
++                        throw_error (context, ERROR_FAILED, "non-permitted character(s) in argument");
++                        goto out;
++                }
++        }
++
++        /* set applicable environment variables in ~/.pam_environment */
++        if (!user_drop_privileges_to_user (user))
++                goto out;
++        ret = g_spawn_sync ( NULL,
++                             (gchar **)command,
++                             NULL,
++                             G_SPAWN_STDERR_TO_DEV_NULL,
++                             NULL,
++                             NULL,
++                             &validated_data,
++                             NULL,
++                             NULL,
++                             &error );
++        user_regain_privileges ();
++        if (!ret) {
++                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", program, error->message);
++                g_error_free (error);
++                validated_data = NULL;
++                goto out;
++        }
++        if (validated_data == NULL || strlen (validated_data) <= 1) {
++                throw_error (context, ERROR_FAILED, "running '%s' failed: no output", program);
++                validated_data = NULL;
++                goto out;
++        }
++
++out:
++        g_free (program);
++        if (validated_data == NULL)
++                return NULL;
++
++        return g_strchomp (validated_data);
++}
++
++static gboolean
++user_HOME_available (User *user)
++{
++        /* run these tests as user to prevent incorrect
++           failures when HOME is on NFS */
++        user_drop_privileges_to_user (user);
++
++        GDir* homedir = g_dir_open (accounts_user_get_home_directory (ACCOUNTS_USER (user)), 0, NULL);
++
++        if (homedir == NULL) {  // HOME not found
++                user_regain_privileges ();
++                return FALSE;
++        } else {
++                do {
++                        const gchar *entry = g_dir_read_name (homedir);
++                        gchar *path_to_entry = g_build_path ("/", accounts_user_get_home_directory (ACCOUNTS_USER (user)), entry, NULL);
++                        if (g_file_test (path_to_entry, G_FILE_TEST_IS_SYMLINK)) {
++                                g_free (path_to_entry);
++                                continue;
++                        }
++                        if (g_strcmp0 (entry, NULL) == 0) {  // HOME contains only symlinks
++                                g_free (path_to_entry);
++                                g_dir_close (homedir);
++                                user_regain_privileges ();
++                                return FALSE;
++                        } else
++                                g_free (path_to_entry);
++                                break;
++                } while (TRUE);
++        }
++
++        g_dir_close (homedir);
++        user_regain_privileges ();
++
++        return TRUE;
++}
++
++static gboolean
++is_in_pam_environment (User        *user,
++                       const gchar *property)
++{
++        gboolean ret = FALSE;
++        const gchar *prefix;
++        FILE *fp;
++        g_autofree gchar *pam_env = NULL;
++        int lineno = 0;
++        int fd;
++
++        if (g_strcmp0 (property, "Language") == 0)
++                prefix = "LANG";
++        else if (g_strcmp0 (property, "FormatsLocale") == 0)
++                prefix = "LC_TIME";
++        else
++                return FALSE;
++
++        pam_env = g_build_path ("/", accounts_user_get_home_directory (ACCOUNTS_USER (user)), ".pam_environment", NULL);
++
++        if (!user_drop_privileges_to_user (user))
++                return FALSE;
++
++        fd = open (pam_env, O_RDONLY | O_NOFOLLOW);
++        if (fd < 0) {
++                user_regain_privileges ();
++                return FALSE;
++        }
++
++        if ((fp = fdopen (fd, "r"))) {
++                gchar line[50];
++                while ((fgets (line, 50, fp)) != NULL) {
++                        if (g_str_has_prefix (line, prefix)) {
++                                ret = TRUE;
++                                break;
++                        }
++                        /* Give up on large files */
++                        if (lineno > 50) {
++                                ret = FALSE;
++                                break;
++                        }
++                        lineno++;
++                }
++                fclose (fp);
++        }
++        user_regain_privileges ();
++
++        return ret;
++}
++
+ static void
+ user_change_language_authorized_cb (Daemon                *daemon,
+                                     User                  *user,
+@@ -1322,14 +1681,44 @@ user_change_language_authorized_cb (Daem
+                                     gpointer               data)
+ 
+ {
+-        gchar *language = data;
++        const gchar *language = data;
++
++        if (!user_HOME_available (user)) {
++
++                /* SetLanguage was probably called from a login greeter,
++                   and HOME not mounted and/or not decrypted.
++                   Hence don't save anything, or else accountsservice
++                   and ~/.pam_environment would become out of sync. */
++                throw_error (context, ERROR_FAILED, "not access to HOME yet so language not saved");
++                goto out;
++        }
+ 
+         if (g_strcmp0 (accounts_user_get_language (ACCOUNTS_USER (user)), language) != 0) {
+-                accounts_user_set_language (ACCOUNTS_USER (user), language);
++                g_autofree gchar *lang = user_update_environment (user,
++                                                                  (gchar *) language,
++                                                                  "set-language-helper",
++                                                                  context);
++                if (lang != NULL)
++                        accounts_user_set_language (ACCOUNTS_USER (user), lang);
++
++                if (!is_in_pam_environment (user, "FormatsLocale")) {
++
++                        /* set the user formats (certain LC_* variables) explicitly
++                           in order to prevent surprises when LANG is changed */
++                        gchar *fallback_locale = user_get_fallback_value (user, "FormatsLocale");
++                        g_autofree gchar *validated_locale = user_locale_validate (user, fallback_locale, context);
++                        g_autofree gchar *formats_locale = user_update_environment (user,
++                                                                                    validated_locale,
++                                                                                    "save-to-pam-env",
++                                                                                    context);
++                        if (formats_locale != NULL)
++                                accounts_user_set_formats_locale (ACCOUNTS_USER (user), formats_locale);
++                }
+ 
+                 save_extra_data (user);
+         }
+ 
++out:
+         accounts_user_complete_set_language (ACCOUNTS_USER (user), context);
+ }
+ 
+@@ -1471,7 +1860,13 @@ user_change_formats_locale_authorized_cb
+         const gchar *formats_locale = user_data;
+ 
+         if (g_strcmp0 (accounts_user_get_formats_locale (ACCOUNTS_USER (user)), formats_locale) != 0) {
+-                accounts_user_set_formats_locale (ACCOUNTS_USER (user), formats_locale);
++                g_autofree gchar *validated_locale = user_locale_validate (user, formats_locale, context);
++                g_autofree gchar *locale = user_update_environment (user,
++                                                                    validated_locale,
++                                                                    "save-to-pam-env",
++                                                                    context);
++                if (locale != NULL)
++                        accounts_user_set_formats_locale (ACCOUNTS_USER (user), locale);
+ 
+                 save_extra_data (user);
+         }
diff -pruN 22.08.8-1/debian/patches/0011-add-background-file-support.patch 22.08.8-1ubuntu1/debian/patches/0011-add-background-file-support.patch
--- 22.08.8-1/debian/patches/0011-add-background-file-support.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0011-add-background-file-support.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,298 @@
+From ace0d7e184ff7011a26eb9287f81ef2d884f09e3 Mon Sep 17 00:00:00 2001
+From: Michael Terry <michael.terry@ubuntu.com>
+Date: Thu, 21 Dec 2017 15:11:01 +1300
+Subject: [PATCH 07/12] Add support for a BackgroundFile property, similar to
+ IconFile
+
+---
+ data/org.freedesktop.Accounts.User.xml | 45 ++++++++++++++
+ src/libaccountsservice/act-user.c      | 55 +++++++++++++++++
+ src/libaccountsservice/act-user.h      |  3 +
+ src/user.c                             | 81 ++++++++++++++++++++++++++
+ 4 files changed, 184 insertions(+)
+
+Index: accountsservice/data/org.freedesktop.Accounts.User.xml
+===================================================================
+--- accountsservice.orig/data/org.freedesktop.Accounts.User.xml
++++ accountsservice/data/org.freedesktop.Accounts.User.xml
+@@ -414,6 +414,41 @@
+     </doc:doc>
+   </method>
+ 
++  <method name="SetBackgroundFile">
++    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++    <arg name="filename" direction="in" type="s">
++      <doc:doc>
++        <doc:summary>
++          The absolute filename of a png file to use as the users background.
++        </doc:summary>
++      </doc:doc>
++    </arg>
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          Sets the users background.
++        </doc:para>
++      </doc:description>
++      <doc:permission>
++        The caller needs one of the following PolicyKit authorizations:
++        <doc:list>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
++            <doc:definition>To change his own background</doc:definition>
++          </doc:item>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
++            <doc:definition>To change the background of another user</doc:definition>
++          </doc:item>
++        </doc:list>
++      </doc:permission>
++      <doc:errors>
++        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
++        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
++      </doc:errors>
++    </doc:doc>
++  </method>
++
+   <method name="SetIconFile">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+     <arg name="filename" direction="in" type="s">
+@@ -872,6 +907,16 @@
+         </doc:para>
+       </doc:description>
+     </doc:doc>
++  </property>
++
++  <property name="BackgroundFile" type="s" access="read">
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++           The filename of a png file containing the users background.
++        </doc:para>
++      </doc:description>
++    </doc:doc>
+   </property>
+ 
+   <property name="IconFile" type="s" access="read">
+Index: accountsservice/src/libaccountsservice/act-user.c
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.c
++++ accountsservice/src/libaccountsservice/act-user.c
+@@ -89,6 +89,7 @@ enum {
+         PROP_LOGIN_FREQUENCY,
+         PROP_LOGIN_TIME,
+         PROP_LOGIN_HISTORY,
++        PROP_BACKGROUND_FILE,
+         PROP_ICON_FILE,
+         PROP_LANGUAGE,
+         PROP_FORMATS_LOCALE,
+@@ -368,6 +369,13 @@ act_user_class_init (ActUserClass *class
+                                                                NULL,
+                                                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+         g_object_class_install_property (gobject_class,
++                                         PROP_BACKGROUND_FILE,
++                                         g_param_spec_string ("background-file",
++                                                              "Background File",
++                                                              "The path to a background for this user.",
++                                                              NULL,
++                                                              G_PARAM_READABLE));
++        g_object_class_install_property (gobject_class,
+                                          PROP_ICON_FILE,
+                                          g_param_spec_string ("icon-file",
+                                                               "Icon File",
+@@ -1007,6 +1015,25 @@ act_user_is_nonexistent (ActUser   *user
+ }
+ 
+ /**
++ * act_user_get_background_file:
++ * @user: a #ActUser
++ *
++ * Returns the path to the account background belonging to @user.
++ *
++ * Returns: (transfer none): a path to a background
++ */
++const char *
++act_user_get_background_file (ActUser *user)
++{
++        g_return_val_if_fail (ACT_IS_USER (user), NULL);
++
++        if (user->accounts_proxy == NULL)
++                return NULL;
++
++        return accounts_user_get_background_file (user->accounts_proxy);
++}
++
++/**
+  * act_user_get_icon_file:
+  * @user: a #ActUser
+  *
+@@ -1441,6 +1468,36 @@ act_user_set_language (ActUser    *user,
+                 return;
+         }
+ }
++
++/**
++ * act_user_set_background_file:
++ * @user: the user object to alter.
++ * @background_file: path to an background
++ *
++ * Assigns a new background for @user.
++ *
++ * Note this function is synchronous and ignores errors.
++ **/
++void
++act_user_set_background_file (ActUser    *user,
++                              const char *background_file)
++{
++        g_autoptr(GError) error = NULL;
++
++        g_return_if_fail (ACT_IS_USER (user));
++        g_return_if_fail (background_file != NULL);
++        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
++
++        if (!accounts_user_call_set_background_file_sync (user->accounts_proxy,
++                                                          background_file,
++                                                          G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
++                                                         -1,
++                                                          NULL,
++                                                          &error)) {
++                g_warning ("SetBackgroundFile call failed: %s", error->message);
++                return;
++        }
++}
+ 
+ /**
+  * act_user_set_x_session:
+Index: accountsservice/src/libaccountsservice/act-user.h
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.h
++++ accountsservice/src/libaccountsservice/act-user.h
+@@ -70,6 +70,7 @@ gboolean       act_user_get_automatic_lo
+ gboolean       act_user_is_system_account         (ActUser   *user);
+ gboolean       act_user_is_local_account          (ActUser   *user);
+ gboolean       act_user_is_nonexistent            (ActUser   *user);
++const char    *act_user_get_background_file       (ActUser   *user);
+ const char    *act_user_get_icon_file             (ActUser   *user);
+ const char    *act_user_get_language              (ActUser   *user);
+ const char    *act_user_get_formats_locale        (ActUser   *user);
+@@ -96,6 +97,8 @@ void           act_user_set_language
+                                                    const char *language);
+ void           act_user_set_formats_locale        (ActUser    *user,
+                                                    const char *formats_locale);
++void           act_user_set_background_file       (ActUser    *user,
++                                                   const char *background_file);
+ void           act_user_set_x_session             (ActUser    *user,
+                                                    const char *x_session);
+ void           act_user_set_session               (ActUser    *user,
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -570,6 +570,12 @@ user_update_from_keyfile (User     *user
+                 g_clear_pointer (&s, g_free);
+         }
+ 
++        s = g_key_file_get_string (keyfile, "User", "Background", NULL);
++        if (s != NULL) {
++                accounts_user_set_background_file (ACCOUNTS_USER (user), s);
++                g_clear_pointer (&s, g_free);
++        }
++
+         s = g_key_file_get_string (keyfile, "User", "Icon", NULL);
+         if (s != NULL) {
+                 accounts_user_set_icon_file (ACCOUNTS_USER (user), s);
+@@ -653,6 +659,9 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_password_hint (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
+ 
++        if (accounts_user_get_background_file (ACCOUNTS_USER (user)))
++                g_key_file_set_string (keyfile, "User", "Background", accounts_user_get_background_file (ACCOUNTS_USER (user)));
++
+         if (accounts_user_get_icon_file (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user)));
+ 
+@@ -2184,6 +2193,76 @@ become_user (gpointer data)
+ }
+ 
+ static void
++user_change_background_file_authorized_cb (Daemon                *daemon,
++                                           User                  *user,
++                                           GDBusMethodInvocation *context,
++                                           gpointer               data)
++{
++        g_autofree gchar *filename = NULL;
++        g_autoptr(GFile) file = NULL;
++        g_autoptr(GFileInfo) info = NULL;
++        GFileType type;
++
++        filename = g_strdup (data);
++
++        if (filename == NULL ||
++            *filename == '\0') {
++                g_free (filename);
++                filename = NULL;
++
++                goto background_saved;
++        }
++
++        file = g_file_new_for_path (filename);
++        info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE,
++                                  0, NULL, NULL);
++        type = g_file_info_get_file_type (info);
++
++        if (type != G_FILE_TYPE_REGULAR) {
++                g_debug ("not a regular file\n");
++                throw_error (context, ERROR_FAILED, "file '%s' is not a regular file", filename);
++                return;
++        }
++
++background_saved:
++        accounts_user_set_background_file (ACCOUNTS_USER (user), filename);
++
++        save_extra_data (user);
++
++        accounts_user_complete_set_background_file (ACCOUNTS_USER (user), context);
++}
++
++static gboolean
++user_set_background_file (AccountsUser          *auser,
++                          GDBusMethodInvocation *context,
++                          const gchar           *filename)
++{
++        User *user = (User*)auser;
++        int uid;
++        const gchar *action_id;
++
++        if (!get_caller_uid (context, &uid)) {
++                throw_error (context, ERROR_FAILED, "identifying caller failed");
++                return FALSE;
++        }
++
++        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
++                action_id = "org.freedesktop.accounts.change-own-user-data";
++        else
++                action_id = "org.freedesktop.accounts.user-administration";
++
++        daemon_local_check_auth (user->daemon,
++                                 user,
++                                 action_id,
++                                 user_change_background_file_authorized_cb,
++                                 context,
++                                 g_strdup (filename),
++                                 (GDestroyNotify)g_free);
++
++        return TRUE;
++}
++
++static void
+ user_change_icon_file_authorized_cb (Daemon                *daemon,
+                                      User                  *user,
+                                      GDBusMethodInvocation *context,
+@@ -2859,6 +2938,7 @@ user_accounts_user_iface_init (AccountsU
+ {
+         iface->handle_set_account_type = user_set_account_type;
+         iface->handle_set_automatic_login = user_set_automatic_login;
++        iface->handle_set_background_file = user_set_background_file;
+         iface->handle_set_email = user_set_email;
+         iface->handle_set_formats_locale = user_set_formats_locale;
+         iface->handle_set_home_directory = user_set_home_directory;
diff -pruN 22.08.8-1/debian/patches/0012-add-keyboard-layout-support.patch 22.08.8-1ubuntu1/debian/patches/0012-add-keyboard-layout-support.patch
--- 22.08.8-1/debian/patches/0012-add-keyboard-layout-support.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0012-add-keyboard-layout-support.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,279 @@
+From 5b94fee636146034fb2fbf314853bdb3380518fb Mon Sep 17 00:00:00 2001
+From: Michael Terry <michael.terry@ubuntu.com>
+Date: Thu, 21 Dec 2017 15:11:19 +1300
+Subject: [PATCH 08/12] Add XKeyboardLayouts property to report a user's
+ keyboard layouts, largely for LightDM's benefit.
+
+---
+ data/org.freedesktop.Accounts.User.xml | 45 +++++++++++++++++++++
+ src/libaccountsservice/act-user.c      | 55 ++++++++++++++++++++++++++
+ src/libaccountsservice/act-user.h      |  3 ++
+ src/user.c                             | 55 ++++++++++++++++++++++++++
+ 4 files changed, 158 insertions(+)
+
+Index: accountsservice/data/org.freedesktop.Accounts.User.xml
+===================================================================
+--- accountsservice.orig/data/org.freedesktop.Accounts.User.xml
++++ accountsservice/data/org.freedesktop.Accounts.User.xml
+@@ -414,6 +414,41 @@
+     </doc:doc>
+   </method>
+ 
++  <method name="SetXKeyboardLayouts">
++    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++    <arg name="layouts" direction="in" type="as">
++      <doc:doc>
++        <doc:summary>
++          The name of the keyboard layouts to use as the user's keyboard layout.  The first is the default.
++        </doc:summary>
++      </doc:doc>
++    </arg>
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          Sets the user's keyboard layouts.
++        </doc:para>
++      </doc:description>
++      <doc:permission>
++        The caller needs one of the following PolicyKit authorizations:
++        <doc:list>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
++            <doc:definition>To change his or her own keyboard layouts</doc:definition>
++          </doc:item>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
++            <doc:definition>To change the keyboard layouts of another user</doc:definition>
++          </doc:item>
++        </doc:list>
++      </doc:permission>
++      <doc:errors>
++        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
++        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
++      </doc:errors>
++    </doc:doc>
++  </method>
++
+   <method name="SetBackgroundFile">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+     <arg name="filename" direction="in" type="s">
+@@ -907,6 +942,16 @@
+         </doc:para>
+       </doc:description>
+     </doc:doc>
++  </property>
++
++  <property name="XKeyboardLayouts" type="as" access="read">
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++           The names of the user's keyboard layouts.
++        </doc:para>
++      </doc:description>
++    </doc:doc>
+   </property>
+ 
+   <property name="BackgroundFile" type="s" access="read">
+Index: accountsservice/src/libaccountsservice/act-user.c
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.c
++++ accountsservice/src/libaccountsservice/act-user.c
+@@ -89,6 +89,7 @@ enum {
+         PROP_LOGIN_FREQUENCY,
+         PROP_LOGIN_TIME,
+         PROP_LOGIN_HISTORY,
++        PROP_X_KEYBOARD_LAYOUTS,
+         PROP_BACKGROUND_FILE,
+         PROP_ICON_FILE,
+         PROP_LANGUAGE,
+@@ -369,6 +370,13 @@ act_user_class_init (ActUserClass *class
+                                                                NULL,
+                                                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+         g_object_class_install_property (gobject_class,
++                                         PROP_X_KEYBOARD_LAYOUTS,
++                                         g_param_spec_boxed ("xkeyboard-layouts",
++                                                             "Keyboard layouts",
++                                                             "The name of keyboard layouts for this user.",
++                                                             G_TYPE_STRV,
++                                                             G_PARAM_READABLE));
++        g_object_class_install_property (gobject_class,
+                                          PROP_BACKGROUND_FILE,
+                                          g_param_spec_string ("background-file",
+                                                               "Background File",
+@@ -1015,6 +1023,25 @@ act_user_is_nonexistent (ActUser   *user
+ }
+ 
+ /**
++ * act_user_get_x_keyboard_layouts:
++ * @user: a #ActUser
++ *
++ * Returns the name of the account keyboard layouts belonging to @user.
++ *
++ * Returns: (transfer none): names of keyboard layouts
++ */
++const char * const *
++act_user_get_x_keyboard_layouts (ActUser *user)
++{
++        g_return_val_if_fail (ACT_IS_USER (user), NULL);
++
++        if (user->accounts_proxy == NULL)
++                return NULL;
++
++        return accounts_user_get_xkeyboard_layouts (user->accounts_proxy);
++}
++
++/**
+  * act_user_get_background_file:
+  * @user: a #ActUser
+  *
+@@ -1377,6 +1404,36 @@ act_user_get_password_expiration_policy
+                 return;
+         }
+ }
++
++/**
++ * act_user_set_x_keyboard_layouts:
++ * @user: the user object to alter.
++ * @keyboard_layouts: names of keyboard layouts
++ *
++ * Assigns a new set of keyboard layouts for @user.
++ *
++ * Note this function is synchronous and ignores errors.
++ **/
++void
++act_user_set_x_keyboard_layouts (ActUser    *user,
++                                 const char * const *keyboard_layouts)
++{
++        g_autoptr(GError) error = NULL;
++
++        g_return_if_fail (ACT_IS_USER (user));
++        g_return_if_fail (keyboard_layouts != NULL);
++        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
++
++        if (!accounts_user_call_set_xkeyboard_layouts_sync (user->accounts_proxy,
++                                                            keyboard_layouts,
++                                                            G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
++                                                           -1,
++                                                            NULL,
++                                                            &error)) {
++                g_warning ("SetXKeyboardLayouts call failed: %s", error->message);
++                return;
++        }
++}
+ 
+ /**
+  * act_user_set_formats_locale:
+Index: accountsservice/src/libaccountsservice/act-user.h
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.h
++++ accountsservice/src/libaccountsservice/act-user.h
+@@ -69,6 +69,7 @@ gboolean       act_user_get_locked
+ gboolean       act_user_get_automatic_login       (ActUser   *user);
+ gboolean       act_user_is_system_account         (ActUser   *user);
+ gboolean       act_user_is_local_account          (ActUser   *user);
++const char * const *act_user_get_x_keyboard_layouts (ActUser *user);
+ gboolean       act_user_is_nonexistent            (ActUser   *user);
+ const char    *act_user_get_background_file       (ActUser   *user);
+ const char    *act_user_get_icon_file             (ActUser   *user);
+@@ -95,6 +96,8 @@ void           act_user_set_email
+                                                    const char *email);
+ void           act_user_set_language              (ActUser    *user,
+                                                    const char *language);
++void           act_user_set_x_keyboard_layouts    (ActUser    *user,
++                                                   const char * const *keyboard_layouts);
+ void           act_user_set_formats_locale        (ActUser    *user,
+                                                    const char *formats_locale);
+ void           act_user_set_background_file       (ActUser    *user,
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -518,6 +518,7 @@ user_update_from_keyfile (User     *user
+                           GKeyFile *keyfile)
+ {
+         gchar *s;
++        gchar **layouts;
+ 
+         s = g_key_file_get_string (keyfile, "User", "Language", NULL);
+         if (s != NULL) {
+@@ -570,6 +571,12 @@ user_update_from_keyfile (User     *user
+                 g_clear_pointer (&s, g_free);
+         }
+ 
++        layouts = g_key_file_get_string_list (keyfile, "User", "XKeyboardLayouts", NULL, NULL);
++        if (layouts != NULL) {
++                accounts_user_set_xkeyboard_layouts (ACCOUNTS_USER (user), (const gchar * const *) layouts);
++                g_strfreev (layouts);
++        }
++
+         s = g_key_file_get_string (keyfile, "User", "Background", NULL);
+         if (s != NULL) {
+                 accounts_user_set_background_file (ACCOUNTS_USER (user), s);
+@@ -659,6 +666,9 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_password_hint (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
+ 
++        if (accounts_user_get_xkeyboard_layouts (ACCOUNTS_USER (user)))
++                g_key_file_set_string_list (keyfile, "User", "XKeyboardLayouts", (const gchar * const *) accounts_user_get_xkeyboard_layouts (ACCOUNTS_USER (user)), g_strv_length ((gchar **) accounts_user_get_xkeyboard_layouts (ACCOUNTS_USER (user))));
++
+         if (accounts_user_get_background_file (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "Background", accounts_user_get_background_file (ACCOUNTS_USER (user)));
+ 
+@@ -2193,6 +2203,49 @@ become_user (gpointer data)
+ }
+ 
+ static void
++user_change_x_keyboard_layouts_authorized_cb (Daemon                *daemon,
++                                              User                  *user,
++                                              GDBusMethodInvocation *context,
++                                              gpointer               data)
++{
++        accounts_user_set_xkeyboard_layouts (ACCOUNTS_USER (user), data);
++
++        save_extra_data (user);
++
++        accounts_user_complete_set_xkeyboard_layouts (ACCOUNTS_USER (user), context);
++}
++
++static gboolean
++user_set_xkeyboard_layouts (AccountsUser          *auser,
++                            GDBusMethodInvocation *context,
++                            const gchar * const   *layouts)
++{
++        User *user = (User*)auser;
++        int uid;
++        const gchar *action_id;
++
++        if (!get_caller_uid (context, &uid)) {
++                throw_error (context, ERROR_FAILED, "identifying caller failed");
++                return FALSE;
++        }
++
++        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
++                action_id = "org.freedesktop.accounts.change-own-user-data";
++        else
++                action_id = "org.freedesktop.accounts.user-administration";
++
++        daemon_local_check_auth (user->daemon,
++                                 user,
++                                 action_id,
++                                 user_change_x_keyboard_layouts_authorized_cb,
++                                 context,
++                                 g_strdupv ((gchar **)layouts),
++                                 (GDestroyNotify)g_strfreev);
++
++        return TRUE;
++}
++
++static void
+ user_change_background_file_authorized_cb (Daemon                *daemon,
+                                            User                  *user,
+                                            GDBusMethodInvocation *context,
+@@ -2952,6 +3005,7 @@ user_accounts_user_iface_init (AccountsU
+         iface->handle_set_real_name = user_set_real_name;
+         iface->handle_set_shell = user_set_shell;
+         iface->handle_set_user_name = user_set_user_name;
++        iface->handle_set_xkeyboard_layouts = user_set_xkeyboard_layouts;
+         iface->handle_set_xsession = user_set_x_session;
+         iface->handle_set_session = user_set_session;
+         iface->handle_set_session_type = user_set_session_type;
diff -pruN 22.08.8-1/debian/patches/0013-add-has-message-support.patch 22.08.8-1ubuntu1/debian/patches/0013-add-has-message-support.patch
--- 22.08.8-1/debian/patches/0013-add-has-message-support.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0013-add-has-message-support.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,253 @@
+From d8a0af56bae46720e053a6ce25b2d5273d7233d3 Mon Sep 17 00:00:00 2001
+From: Michael Terry <michael.terry@ubuntu.com>
+Date: Thu, 21 Dec 2017 15:11:37 +1300
+Subject: [PATCH 09/12] Add XHasMessages property to report if a user had
+ unread messages, largely for LightDM's benefit.
+
+---
+ data/org.freedesktop.Accounts.User.xml | 45 +++++++++++++++++++++
+ src/libaccountsservice/act-user.c      | 55 ++++++++++++++++++++++++++
+ src/libaccountsservice/act-user.h      |  3 ++
+ src/user.c                             | 43 ++++++++++++++++++++
+ 4 files changed, 146 insertions(+)
+
+Index: accountsservice/data/org.freedesktop.Accounts.User.xml
+===================================================================
+--- accountsservice.orig/data/org.freedesktop.Accounts.User.xml
++++ accountsservice/data/org.freedesktop.Accounts.User.xml
+@@ -414,6 +414,41 @@
+     </doc:doc>
+   </method>
+ 
++  <method name="SetXHasMessages">
++    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++    <arg name="has_messages" direction="in" type="b">
++      <doc:doc>
++        <doc:summary>
++          Whether the user has messages waiting for them.
++        </doc:summary>
++      </doc:doc>
++    </arg>
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          Sets whether the user has messages waiting for them.
++        </doc:para>
++      </doc:description>
++      <doc:permission>
++        The caller needs one of the following PolicyKit authorizations:
++        <doc:list>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
++            <doc:definition>To change his or her own status</doc:definition>
++          </doc:item>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
++            <doc:definition>To change the status of another user</doc:definition>
++          </doc:item>
++        </doc:list>
++      </doc:permission>
++      <doc:errors>
++        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
++        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
++      </doc:errors>
++    </doc:doc>
++  </method>
++
+   <method name="SetXKeyboardLayouts">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+     <arg name="layouts" direction="in" type="as">
+@@ -942,6 +977,16 @@
+         </doc:para>
+       </doc:description>
+     </doc:doc>
++  </property>
++
++  <property name="XHasMessages" type="b" access="read">
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++           Whether the user has messages waiting for them.
++        </doc:para>
++      </doc:description>
++    </doc:doc>
+   </property>
+ 
+   <property name="XKeyboardLayouts" type="as" access="read">
+Index: accountsservice/src/libaccountsservice/act-user.c
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.c
++++ accountsservice/src/libaccountsservice/act-user.c
+@@ -89,6 +89,7 @@ enum {
+         PROP_LOGIN_FREQUENCY,
+         PROP_LOGIN_TIME,
+         PROP_LOGIN_HISTORY,
++        PROP_X_HAS_MESSAGES,
+         PROP_X_KEYBOARD_LAYOUTS,
+         PROP_BACKGROUND_FILE,
+         PROP_ICON_FILE,
+@@ -113,6 +114,7 @@ struct _ActUser {
+         GList          *our_sessions;
+         GList          *other_sessions;
+ 
++        guint           x_has_messages : 1;
+         guint           is_loaded : 1;
+         guint           nonexistent : 1;
+ };
+@@ -370,6 +372,13 @@ act_user_class_init (ActUserClass *class
+                                                                NULL,
+                                                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+         g_object_class_install_property (gobject_class,
++                                         PROP_X_HAS_MESSAGES,
++                                         g_param_spec_boolean ("xhas-messages",
++                                                             "Has Messages",
++                                                             "Whether the user has messages waiting.",
++                                                             FALSE,
++                                                             G_PARAM_READABLE));
++        g_object_class_install_property (gobject_class,
+                                          PROP_X_KEYBOARD_LAYOUTS,
+                                          g_param_spec_boxed ("xkeyboard-layouts",
+                                                              "Keyboard layouts",
+@@ -1023,6 +1032,25 @@ act_user_is_nonexistent (ActUser   *user
+ }
+ 
+ /**
++ * act_user_get_x_has_messages:
++ * @user: a #ActUser
++ *
++ * Returns whether @user has messages waiting for them.
++ *
++ * Returns: whether messages exist
++ */
++gboolean
++act_user_get_x_has_messages (ActUser *user)
++{
++        g_return_val_if_fail (ACT_IS_USER (user), FALSE);
++
++        if (user->accounts_proxy == NULL)
++                return FALSE;
++
++        return accounts_user_get_xhas_messages (user->accounts_proxy);
++}
++
++/**
+  * act_user_get_x_keyboard_layouts:
+  * @user: a #ActUser
+  *
+@@ -1404,6 +1432,35 @@ act_user_get_password_expiration_policy
+                 return;
+         }
+ }
++
++/**
++ * act_user_set_x_has_messages:
++ * @user: the user object to alter.
++ * @has_messages: whether the user has messages waiting
++ *
++ * Sets a new has-messages status for @user.
++ *
++ * Note this function is synchronous and ignores errors.
++ **/
++void
++act_user_set_x_has_messages (ActUser  *user,
++                             gboolean  has_messages)
++{
++        g_autoptr(GError) error = NULL;
++
++        g_return_if_fail (ACT_IS_USER (user));
++        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
++
++        if (!accounts_user_call_set_xhas_messages_sync (user->accounts_proxy,
++                                                        has_messages,
++                                                        G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
++                                                       -1,
++                                                        NULL,
++                                                        &error)) {
++                g_warning ("SetXHasMessages call failed: %s", error->message);
++                return;
++        }
++}
+ 
+ /**
+  * act_user_set_x_keyboard_layouts:
+Index: accountsservice/src/libaccountsservice/act-user.h
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.h
++++ accountsservice/src/libaccountsservice/act-user.h
+@@ -71,6 +71,7 @@ gboolean       act_user_is_system_accoun
+ gboolean       act_user_is_local_account          (ActUser   *user);
+ const char * const *act_user_get_x_keyboard_layouts (ActUser *user);
+ gboolean       act_user_is_nonexistent            (ActUser   *user);
++gboolean       act_user_get_x_has_messages        (ActUser   *user);
+ const char    *act_user_get_background_file       (ActUser   *user);
+ const char    *act_user_get_icon_file             (ActUser   *user);
+ const char    *act_user_get_language              (ActUser   *user);
+@@ -96,6 +97,8 @@ void           act_user_set_email
+                                                    const char *email);
+ void           act_user_set_language              (ActUser    *user,
+                                                    const char *language);
++void           act_user_set_x_has_messages        (ActUser    *user,
++                                                   gboolean    has_messages);
+ void           act_user_set_x_keyboard_layouts    (ActUser    *user,
+                                                    const char * const *keyboard_layouts);
+ void           act_user_set_formats_locale        (ActUser    *user,
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -2203,6 +2203,47 @@ become_user (gpointer data)
+ }
+ 
+ static void
++user_change_x_has_messages_authorized_cb (Daemon                *daemon,
++                                          User                  *user,
++                                          GDBusMethodInvocation *context,
++                                          gpointer               data)
++{
++        accounts_user_set_xhas_messages (ACCOUNTS_USER (user), GPOINTER_TO_INT (data));
++
++        accounts_user_complete_set_xhas_messages (ACCOUNTS_USER (user), context);
++}
++
++static gboolean
++user_set_xhas_messages (AccountsUser          *auser,
++                        GDBusMethodInvocation *context,
++                        gboolean               has_messages)
++{
++        User *user = (User*)auser;
++        int uid;
++        const gchar *action_id;
++
++        if (!get_caller_uid (context, &uid)) {
++                throw_error (context, ERROR_FAILED, "identifying caller failed");
++                return FALSE;
++        }
++
++        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
++                action_id = "org.freedesktop.accounts.change-own-user-data";
++        else
++                action_id = "org.freedesktop.accounts.user-administration";
++
++        daemon_local_check_auth (user->daemon,
++                                 user,
++                                 action_id,
++                                 user_change_x_has_messages_authorized_cb,
++                                 context,
++                                 GINT_TO_POINTER (has_messages),
++                                 NULL);
++
++        return TRUE;
++}
++
++static void
+ user_change_x_keyboard_layouts_authorized_cb (Daemon                *daemon,
+                                               User                  *user,
+                                               GDBusMethodInvocation *context,
+@@ -3005,6 +3046,7 @@ user_accounts_user_iface_init (AccountsU
+         iface->handle_set_real_name = user_set_real_name;
+         iface->handle_set_shell = user_set_shell;
+         iface->handle_set_user_name = user_set_user_name;
++        iface->handle_set_xhas_messages = user_set_xhas_messages;
+         iface->handle_set_xkeyboard_layouts = user_set_xkeyboard_layouts;
+         iface->handle_set_xsession = user_set_x_session;
+         iface->handle_set_session = user_set_session;
diff -pruN 22.08.8-1/debian/patches/0016-add-input-sources-support.patch 22.08.8-1ubuntu1/debian/patches/0016-add-input-sources-support.patch
--- 22.08.8-1/debian/patches/0016-add-input-sources-support.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0016-add-input-sources-support.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,402 @@
+From 273e6f0892ed7bc1cc31f74fc08423edc95a4ef4 Mon Sep 17 00:00:00 2001
+From: William Hua <william@attente.ca>
+Date: Fri, 26 Jul 2013 10:10:11 -0400
+Subject: [PATCH 10/12] Store input sources in user objects.
+
+---
+ data/org.freedesktop.Accounts.User.xml |  45 +++++++
+ src/libaccountsservice/act-user.c      |  56 ++++++++
+ src/libaccountsservice/act-user.h      |   3 +
+ src/user.c                             | 171 +++++++++++++++++++++++++
+ 4 files changed, 275 insertions(+)
+
+Index: accountsservice/data/org.freedesktop.Accounts.User.xml
+===================================================================
+--- accountsservice.orig/data/org.freedesktop.Accounts.User.xml
++++ accountsservice/data/org.freedesktop.Accounts.User.xml
+@@ -185,6 +185,41 @@
+     </doc:doc>
+   </method>
+ 
++  <method name="SetInputSources">
++    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++    <arg name="sources" direction="in" type="aa{ss}">
++      <doc:doc>
++        <doc:summary>
++          A list of input sources.
++        </doc:summary>
++      </doc:doc>
++    </arg>
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          Sets the user's input sources.
++        </doc:para>
++      </doc:description>
++      <doc:permission>
++        The caller needs one of the following PolicyKit authorizations:
++        <doc:list>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
++            <doc:definition>To change his own input sources</doc:definition>
++          </doc:item>
++          <doc:item>
++            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
++            <doc:definition>To change the input sources of another user</doc:definition>
++          </doc:item>
++        </doc:list>
++      </doc:permission>
++      <doc:errors>
++        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
++        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
++      </doc:errors>
++    </doc:doc>
++  </method>
++
+   <method name="SetXSession">
+     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+     <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_x_session"/>
+@@ -919,6 +954,16 @@
+         </doc:para>
+       </doc:description>
+     </doc:doc>
++  </property>
++
++  <property name="InputSources" type="aa{ss}" access="read">
++    <doc:doc>
++      <doc:description>
++        <doc:para>
++          The user's input sources.
++        </doc:para>
++      </doc:description>
++    </doc:doc>
+   </property>
+ 
+   <property name="XSession" type="s" access="read">
+Index: accountsservice/src/libaccountsservice/act-user.c
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.c
++++ accountsservice/src/libaccountsservice/act-user.c
+@@ -95,6 +95,7 @@ enum {
+         PROP_ICON_FILE,
+         PROP_LANGUAGE,
+         PROP_FORMATS_LOCALE,
++        PROP_INPUT_SOURCES,
+         PROP_X_SESSION,
+         PROP_IS_LOADED
+ };
+@@ -430,6 +431,14 @@ act_user_class_init (ActUserClass *class
+                                                               NULL,
+                                                               G_PARAM_READABLE));
+         g_object_class_install_property (gobject_class,
++                                         PROP_INPUT_SOURCES,
++                                         g_param_spec_variant ("input-sources",
++                                                               "Input sources",
++                                                               "User's input sources.",
++                                                               G_VARIANT_TYPE ("aa{ss}"),
++                                                               NULL,
++                                                               G_PARAM_READABLE));
++        g_object_class_install_property (gobject_class,
+                                          PROP_X_SESSION,
+                                          g_param_spec_string ("x-session",
+                                                               "X session",
+@@ -1148,6 +1157,25 @@ act_user_get_formats_locale (ActUser *us
+ }
+ 
+ /**
++ * act_user_get_input_sources:
++ * @user: a #ActUser
++ *
++ * Returns the input sources of @user.
++ *
++ * Returns: (transfer none): a list of input sources
++ */
++GVariant *
++act_user_get_input_sources (ActUser *user)
++{
++        g_return_val_if_fail (ACT_IS_USER (user), NULL);
++
++        if (user->accounts_proxy == NULL)
++                return NULL;
++
++        return accounts_user_get_input_sources (user->accounts_proxy);
++}
++
++/**
+  * act_user_get_x_session:
+  * @user: a #ActUser
+  *
+@@ -1551,6 +1579,36 @@ act_user_set_email (ActUser    *user,
+                 return;
+         }
+ }
++
++/**
++ * act_user_set_input_sources:
++ * @user: the user object to alter.
++ * @sources: a list of input sources
++ *
++ * Assigns new input sources for @user.
++ *
++ * Note this function is synchronous and ignores errors.
++ **/
++void
++act_user_set_input_sources (ActUser  *user,
++                            GVariant *sources)
++{
++        g_autoptr(GError) error = NULL;
++
++        g_return_if_fail (ACT_IS_USER (user));
++        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
++        g_return_if_fail (g_variant_is_of_type (sources, G_VARIANT_TYPE ("aa{ss}")));
++
++        if (!accounts_user_call_set_input_sources_sync (user->accounts_proxy,
++                                                        sources,
++                                                        G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
++                                                       -1,
++                                                        NULL,
++                                                        &error)) {
++                g_warning ("SetInputSources call failed: %s", error->message);
++                return;
++        }
++}
+ 
+ /**
+  * act_user_set_language:
+Index: accountsservice/src/libaccountsservice/act-user.h
+===================================================================
+--- accountsservice.orig/src/libaccountsservice/act-user.h
++++ accountsservice/src/libaccountsservice/act-user.h
+@@ -76,6 +76,7 @@ const char    *act_user_get_background_f
+ const char    *act_user_get_icon_file             (ActUser   *user);
+ const char    *act_user_get_language              (ActUser   *user);
+ const char    *act_user_get_formats_locale        (ActUser   *user);
++GVariant      *act_user_get_input_sources         (ActUser   *user);
+ const char    *act_user_get_x_session             (ActUser   *user);
+ const char    *act_user_get_session               (ActUser   *user);
+ const char    *act_user_get_session_type          (ActUser   *user);
+@@ -95,6 +96,8 @@ void           act_user_get_password_exp
+ 
+ void           act_user_set_email                 (ActUser    *user,
+                                                    const char *email);
++void           act_user_set_input_sources         (ActUser    *user,
++                                                   GVariant   *sources);
+ void           act_user_set_language              (ActUser    *user,
+                                                    const char *language);
+ void           act_user_set_x_has_messages        (ActUser    *user,
+Index: accountsservice/src/user.c
+===================================================================
+--- accountsservice.orig/src/user.c
++++ accountsservice/src/user.c
+@@ -396,6 +396,75 @@ user_update_from_template (User *user)
+         user->template_loaded = key_file_loaded;
+ }
+ 
++static gint
++intcmp (gconstpointer a,
++        gconstpointer b,
++        gpointer      user_data)
++{
++        return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b);
++}
++
++static GVariant *
++key_file_get_input_sources (GKeyFile *key_file)
++{
++        GVariantBuilder builder;
++        GSequence *indices;
++        GSequenceIter *indices_iter;
++        gchar **groups;
++        gchar **groups_iter;
++
++        indices = g_sequence_new (NULL);
++        groups = g_key_file_get_groups (key_file, NULL);
++
++        for (groups_iter = groups; *groups_iter; groups_iter++) {
++                if (g_str_has_prefix (*groups_iter, "InputSource") && (*groups_iter)[11]) {
++                        gchar *end;
++                        guint64 index;
++
++                        index = g_ascii_strtoull (*groups_iter + 11, &end, 0);
++
++                        if (!*end)
++                                g_sequence_insert_sorted (indices, GINT_TO_POINTER (index), intcmp, NULL);
++                }
++        }
++
++        g_strfreev (groups);
++
++        g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{ss}"));
++
++        indices_iter = g_sequence_get_begin_iter (indices);
++
++        while (!g_sequence_iter_is_end (indices_iter)) {
++                guint index;
++                gchar *group;
++                gchar **keys;
++                gchar **keys_iter;
++
++                g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{ss}"));
++
++                index = GPOINTER_TO_UINT (g_sequence_get (indices_iter));
++                group = g_strdup_printf ("InputSource%u", index);
++                keys = g_key_file_get_keys (key_file, group, NULL, NULL);
++
++                for (keys_iter = keys; *keys_iter; keys_iter++) {
++                        gchar *value = g_key_file_get_string (key_file, group, *keys_iter, NULL);
++                        g_variant_builder_add (&builder, "{ss}", *keys_iter, value);
++                        g_free (value);
++                }
++
++                g_strfreev (keys);
++                g_free (group);
++
++                g_variant_builder_close (&builder);
++
++                indices_iter = g_sequence_iter_next (indices_iter);
++        }
++
++        g_sequence_free (indices);
++
++        return g_variant_ref_sink (g_variant_builder_end (&builder));
++}
++
+ void
+ user_update_from_pwent (User          *user,
+                         struct passwd *pwent,
+@@ -532,6 +601,8 @@ user_update_from_keyfile (User     *user
+                 g_clear_pointer (&s, g_free);
+         }
+ 
++        accounts_user_set_input_sources (ACCOUNTS_USER (user), key_file_get_input_sources (keyfile));
++
+         s = g_key_file_get_string (keyfile, "User", "XSession", NULL);
+         if (s != NULL) {
+                 accounts_user_set_xsession (ACCOUNTS_USER (user), s);
+@@ -634,6 +705,51 @@ user_update_system_account_property (Use
+         accounts_user_set_system_account (ACCOUNTS_USER (user), system);
+ }
+ 
++static void
++key_file_set_input_sources (GKeyFile *key_file,
++                            GVariant *input_sources)
++{
++        gchar **groups;
++        gchar **groups_iter;
++        GVariantIter sources;
++        GVariantIter *source;
++        guint i;
++
++        /* Remove all groups matching regex "InputSource\d+". */
++
++        groups = g_key_file_get_groups (key_file, NULL);
++
++        for (groups_iter = groups; *groups_iter; groups_iter++) {
++                if (g_str_has_prefix (*groups_iter, "InputSource")) {
++                        for (i = 11; g_ascii_isdigit ((*groups_iter)[i]); i++);
++
++                        if (i > 11 && !(*groups_iter)[i])
++                                g_key_file_remove_group (key_file, *groups_iter, NULL);
++                }
++        }
++
++        g_strfreev (groups);
++
++        /* Write all input sources to key file. */
++
++        g_variant_iter_init (&sources, input_sources);
++
++        for (i = 0; g_variant_iter_next (&sources, "a{ss}", &source); i++) {
++                gchar *group;
++                const gchar *key;
++                const gchar *value;
++
++                group = g_strdup_printf ("InputSource%u", i);
++
++                while (g_variant_iter_next (source, "{&s&s}", &key, &value))
++                        g_key_file_set_string (key_file, group, key, value);
++
++                g_free (group);
++
++                g_variant_iter_free (source);
++        }
++}
++
+ static gboolean is_in_pam_environment (User *user, const gchar *property);
+ 
+ static void
+@@ -657,6 +773,9 @@ user_save_to_keyfile (User     *user,
+         if (accounts_user_get_formats_locale (ACCOUNTS_USER (user)) && is_in_pam_environment (user, "FormatsLocale"))
+                 g_key_file_set_string (keyfile, "User", "FormatsLocale", accounts_user_get_formats_locale (ACCOUNTS_USER (user)));
+ 
++        if (accounts_user_get_input_sources (ACCOUNTS_USER (user)))
++                key_file_set_input_sources (keyfile, accounts_user_get_input_sources (ACCOUNTS_USER (user)));
++
+         if (accounts_user_get_xsession (ACCOUNTS_USER (user)))
+                 g_key_file_set_string (keyfile, "User", "XSession", accounts_user_get_xsession (ACCOUNTS_USER (user)));
+ 
+@@ -1924,6 +2043,56 @@ user_set_formats_locale (AccountsUser
+ }
+ 
+ static void
++user_change_input_sources_authorized_cb (Daemon                *daemon,
++                                         User                  *user,
++                                         GDBusMethodInvocation *context,
++                                         gpointer               data)
++
++{
++        GVariant *sources = data;
++
++        if (sources != accounts_user_get_input_sources (ACCOUNTS_USER (user)) &&
++            (!sources || !accounts_user_get_input_sources (ACCOUNTS_USER (user)) ||
++             !g_variant_equal (sources, accounts_user_get_input_sources (ACCOUNTS_USER (user))))) {
++                accounts_user_set_input_sources (ACCOUNTS_USER (user), sources);
++
++                save_extra_data (user);
++        }
++
++        accounts_user_complete_set_input_sources (ACCOUNTS_USER (user), context);
++}
++
++static gboolean
++user_set_input_sources (AccountsUser          *auser,
++                        GDBusMethodInvocation *context,
++                        GVariant              *sources)
++{
++        User *user = (User*)auser;
++        int uid;
++        const gchar *action_id;
++
++        if (!get_caller_uid (context, &uid)) {
++                throw_error (context, ERROR_FAILED, "identifying caller failed");
++                return FALSE;
++        }
++
++        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
++                action_id = "org.freedesktop.accounts.change-own-user-data";
++        else
++                action_id = "org.freedesktop.accounts.user-administration";
++
++        daemon_local_check_auth (user->daemon,
++                                 user,
++                                 action_id,
++                                 user_change_input_sources_authorized_cb,
++                                 context,
++                                 sources ? g_variant_ref (sources) : NULL,
++                                 sources ? (GDestroyNotify) g_variant_unref : NULL);
++
++        return TRUE;
++}
++
++static void
+ user_change_x_session_authorized_cb (Daemon                *daemon,
+                                      User                  *user,
+                                      GDBusMethodInvocation *context,
+@@ -3038,6 +3207,7 @@ user_accounts_user_iface_init (AccountsU
+         iface->handle_set_home_directory = user_set_home_directory;
+         iface->handle_set_icon_file = user_set_icon_file;
+         iface->handle_set_language = user_set_language;
++        iface->handle_set_input_sources = user_set_input_sources;
+         iface->handle_set_location = user_set_location;
+         iface->handle_set_locked = user_set_locked;
+         iface->handle_set_password = user_set_password;
diff -pruN 22.08.8-1/debian/patches/0021-support-extrausers.patch 22.08.8-1ubuntu1/debian/patches/0021-support-extrausers.patch
--- 22.08.8-1/debian/patches/0021-support-extrausers.patch	1970-01-01 00:00:00.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/0021-support-extrausers.patch	2022-05-27 07:04:03.000000000 +0000
@@ -0,0 +1,51 @@
+From 16267efeb840ceaa7067e8d608146ea6c9d4184b Mon Sep 17 00:00:00 2001
+From: Michael Terry <michael.terry@ubuntu.com>
+Date: Thu, 21 Dec 2017 15:15:05 +1300
+Subject: [PATCH 12/12] In addition to watching /etc/{passwd,shadow,group},
+ also watch those same files in /var/lib/extrausers/, if they exist.
+
+---
+ src/daemon.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+Index: accountsservice/src/daemon.c
+===================================================================
+--- accountsservice.orig/src/daemon.c
++++ accountsservice/src/daemon.c
+@@ -54,6 +54,9 @@
+ #define PATH_PASSWD "/etc/passwd"
+ #define PATH_SHADOW "/etc/shadow"
+ #define PATH_GROUP "/etc/group"
++#define PATH_EXTRAUSERS_PASSWD "/var/lib/extrausers/passwd"
++#define PATH_EXTRAUSERS_SHADOW "/var/lib/extrausers/shadow"
++#define PATH_EXTRAUSERS_GROUP "/var/lib/extrausers/group"
+ 
+ enum {
+         PROP_0,
+@@ -72,6 +75,9 @@ typedef struct {
+         GFileMonitor *passwd_monitor;
+         GFileMonitor *shadow_monitor;
+         GFileMonitor *group_monitor;
++        GFileMonitor *extrausers_passwd_monitor;
++        GFileMonitor *extrausers_shadow_monitor;
++        GFileMonitor *extrausers_group_monitor;
+         GFileMonitor *gdm_monitor;
+         GFileMonitor *wtmp_monitor;
+ 
+@@ -741,6 +747,16 @@ daemon_init (Daemon *daemon)
+                                              PATH_GROUP,
+                                              on_users_monitor_changed);
+ 
++        priv->extrausers_passwd_monitor = setup_monitor (daemon,
++                                                         PATH_EXTRAUSERS_PASSWD,
++                                                         on_users_monitor_changed);
++        priv->extrausers_shadow_monitor = setup_monitor (daemon,
++                                                         PATH_EXTRAUSERS_SHADOW,
++                                                         on_users_monitor_changed);
++        priv->extrausers_group_monitor = setup_monitor (daemon,
++                                                        PATH_EXTRAUSERS_GROUP,
++                                                        on_users_monitor_changed);
++
+         priv->wtmp_monitor = setup_monitor (daemon,
+                                             wtmp_helper_get_path_for_monitor (),
+                                             on_users_monitor_changed);
diff -pruN 22.08.8-1/debian/patches/series 22.08.8-1ubuntu1/debian/patches/series
--- 22.08.8-1/debian/patches/series	2022-05-26 15:56:40.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/patches/series	2022-05-27 08:03:08.000000000 +0000
@@ -1,5 +1,13 @@
 tests-fix-the-signature-for-the-SetLocked-call.patch
 tests-fix-invocation-of-AddUser.patch
+0001-formats-locale-property.patch
 0002-create-and-manage-groups-like-on-a-debian-system.patch
-0005-gdm_config_file_path.patch
+#0005-gdm_config_file_path.patch
 0007-add-lightdm-support.patch
+0009-language-tools.patch
+0010-set-language.patch
+0011-add-background-file-support.patch
+0012-add-keyboard-layout-support.patch
+0013-add-has-message-support.patch
+0016-add-input-sources-support.patch
+0021-support-extrausers.patch
diff -pruN 22.08.8-1/debian/rules 22.08.8-1ubuntu1/debian/rules
--- 22.08.8-1/debian/rules	2022-05-26 14:50:28.000000000 +0000
+++ 22.08.8-1ubuntu1/debian/rules	2022-05-27 07:04:03.000000000 +0000
@@ -13,7 +13,7 @@ extra_meson_options += -Dgtk_doc=false
 endif
 
 %:
-	dh $@ --with=gir
+	dh $@ --with=gir,translations
 
 override_dh_makeshlibs:
 	dh_makeshlibs -V -- -c4
@@ -21,8 +21,9 @@ override_dh_makeshlibs:
 override_dh_auto_configure:
 	dh_auto_configure -- \
 		-Ddocbook=true \
-		-Dgdmconffile=/etc/gdm3/daemon.conf \
+		-Dgdmconffile=/etc/gdm3/custom.conf \
 		-Dadmin_group=sudo \
 		-Dsystemdsystemunitdir=/lib/systemd/system \
 		-Dintrospection=true \
+		-Dextra_admin_groups=adm,cdrom,dip,lpadmin,plugdev,sambashare,libvirtd,lxd \
 		$(extra_meson_options)
