Changing gdm/lightdm user login settings programaticallyJune 11, 2012
Recently, as part of the automated testing efforts at Linaro, I needed to
programmatically change the default X session for a user. It used to be the
case that editing
~/.dmrc was enough to achieve this. Display managers (DMs),
such as gdm and lightdm, would read the contents of the
~/.dmrc at login time
to decide which language and X session to use (among other settings). When a
user changed a setting through the GUI, the DM would write the new settings to
~/.dmrc (only after successfully logging in, of course).
However, all of this changed with the introduction of AccountsService. As the
name suggests, AccountsService provides a service for the management of user
accounts, and among other things, some of the login settings that were
previously configured in
~/.dmrc. It offers this functionality through the
org.freedesktop.Accounts DBus service on the system bus.
Modern Display Managers use AccountsService to manipulate user login settings,
falling back to
~/.dmrc only when the service is unavailable (at least in the
case of lightdm). What this means for the end-user is that editing
manually has no effect. For example, you can try changing the Session field in
~/.dmrc all you want, but next time you log in you will end up in the same
session and your
~/.dmrc changes will have been overwritten.
In order to actually change any settings we need to communicate with
AccountsService through DBus. The first step is to find out the object that
corresponds to the user we want to change the settings for. The path of this
object is of the form
<USER> is usually
of the form
User<UID> but there is no guarantee of that. Thankfully, the
/org/freedesktop/Accounts object provides the
org.freedesktop.Accounts.FindUserById methods, which we can use to get the
object path for a user.
Having the user object path, we can use the
methods on the user object to change the required settings.
We can use the dbus-send program to perform the operations mentioned above. For example:
$ USER_PATH=$(dbus-send --print-reply=literal --system --dest=org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts.FindUserById int64:1000) $ dbus-send --print-reply --system --dest=org.freedesktop.Accounts $USER_PATH org.freedesktop.Accounts.User.SetXSession string:'xterm'
As I needed to get and set the X session for a user in a user-friendly manner, I decided to create a small python program instead. You can find the program here: user_xsession.py
You can use user_xsession.py like:
$ ./user_xsession.py [--user-id <ID>|--user-name <NAME>] set <SESSION> $ ./user_xsession.py [--user-id <ID>|--user-name <NAME>] get
Note that you may need to run as root, depending on the account you want to
change the settings for.
$ ./user_xsession.py --user-id 1000 set xterm
You can easily tweak the program to change another setting instead of the X session.