TDE base libraries and programs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Slávek Banko 2f706891f3
Desktop file translations:
1 month ago
backend Add missing include/link directories 1 month ago
cryptocardwatcher Move VT switch on card insertion to cryptocardwatcher process 4 years ago
kfrontend Desktop file translations: 1 month ago
CMakeL10n.txt Add CMakeL10n rules. 1 year ago
CMakeLists.txt Add initial cryptographic card login support 4 years ago
ChangeLog Part 2 of prior commit 8 years ago
ConfigureChecks.cmake Change to use arc4random_buf(3) if available 11 months ago Part 2 of prior commit 8 years ago
README Rebranding: TDE Control Center --> Trinity Control Center 6 years ago
TODO Rename kderc -> tderc in support of bug report 1447. 7 years ago
config.def Corrected comment description of new keyboard LED sync option in tdm config. 5 months ago Part 2 of prior commit 8 years ago Part 2 of prior commit 8 years ago Part 2 of prior commit 8 years ago


This is the Trinity Display Manager (TDM),
the TDE replacement for the X Display Manager (XDM).

configure options that affect TDM

Compile TDM (and other parts of tdebase) with PAM support. The default
service is "tde". PAM is automatically used if found.

Override the PAM service used specifically by TDM. Depends on --with-pam.

Compile TDM (and other parts of tdebase) with shadow password support.
Shadow passwords are automatically used if found. This affects TDM only
if PAM is not used.

Compile TDM (and the LDAP TDEIO slave) with KTH Kerberos 4 support. Note
that this does not work with the Kerberos 4 compatibility layer found in
MIT Kerberos 5. This affects TDM only if PAM is not used.

Compile TDM with AFS support. Depends on --with-krb4.

Compile TDM with Kerberos 5 resp. secure RPC support for X authorization
cookies. It's pretty pointless to enable this if you don't use an X server
that supports it.

If you want user authentication against a Kerberos realm, compile TDM with
PAM support and use the appropriate module.

Compile TDM without XDMCP support.

Compile TDM with a builtin "xconsole" replacement in the greeter. I don't
consider this too useful, but SuSE wanted it, so it's there. ;)

TDM's file system layout

${tde_confdir} is usually ${prefix}/share/config
${tde_datadir} is usually ${prefix}/share/apps
The indented locations are envisioned for a configuration shared with GDM.


How to setup TDM

TDM's config files are all located in ${tde_confdir}/tdm.
"make install" will create a probably working configuration, either by
deriving it from an already present TDM/XDM installation or by using
defaults if no previous installation is found.

You can change the configuration from the Trinity Control Center. You will
find the "Login Manager" module in the "System Administration" group.

Have a look at README.pam in the tdebase top level directory if your
system uses PAM.

Configuring session types

Session types are now represented by .desktop files in appropriate locations.
The format of the .desktop files is (not yet) defined in the
desktop entry spec. Differences to "standard" .desktop files are:
- the Type is fixed to XSession and can be omitted
- the Encoding is fixed to UTF-8 and can be omitted
- the Exec field will be passed to "eval exec" in a bourne shell; no macro
expansion is performed on it. "default", "custom" and "failsafe" are magic
constants that cause special actions.
- Name, Comment, TryExec and Hidden are supported
- the remaining keys have no meaning currently
Session types are internally identified by filename (without extension);
that's what will be saved to ~/.dmrc and what DESKTOP_SESSION will be set to.
For every magic Exec constant a session type of the same name exists.

Unless your system is configured differently already, you should create a
directory ${tde_confdir}/tdm/sessions and add this to tdmrc:


(Note that you must use actual paths instead of variables, see the section
about TDM's file system layout.)
Do any changes only in the config directory - any changes in the data
directory will be lost after the next TDE update.

To override a session type, copy the .desktop file from the data dir to the
config dir and edit it at will. Removing the shipped session types can be
accomplished by "shadowing" them with .desktop files containing Hidden=true.
For the magic session types no .desktop files exist by default, but TDM
pretends they would, so you can override them like any other type.
I guess you already know how to add a new session type by now. ;-)

Running TDM from init

NOTE, that this description applies to RedHat 5.x and must be adapted for
other distributions/systems. Generally I'd advise _against_ starting TDM
directly from init - better use a proper init script, possibly by slightly
modifying the XDM init script shipped by your distribution.

Edit (as root) /etc/inittab.

Look for the line:

x:5:respawn:/usr/X11/bin/xdm -nodaemon

Replace it with:


This tells init(8) to respawn TDM, the TDE display manager, when
the system is in run level 5.
Note that TDM does not need the -nodaemon option.

To start TDM, either run (as root) /sbin/telinit 5 (to switch to
run level 5), or (this is risky! don't do it until you _know_ you
want the system to boot into this every time!) edit /etc/inittab
and change the line:




If you do the latter step, then every time your system boots
successfully it will go into run level 5 and run TDM,
presenting you the exceedingly cute TDE login screen.

The command sockets

This is a feature you can use to remote-control TDM. It's mostly intended
for use by ksmserver and kdesktop from a running session, but other
applications are possible as well.

The sockets are UNIX domain sockets which live in subdirectories of the
directory specified by FifoDir=. The subdir is the key to addressing and
security; the sockets all have the file name "socket" and file permissions
rw-rw-rw- (0666). This is because some systems don't care for the file
permissions of the socket files.
There are two types of sockets: the global one (dmctl) and the per-display
ones (dmctl-<display>).
The global one's subdir is owned by root, the subdirs of the per-display
ones' are owned by the user currently owning the session (root or the
logged in user). Group ownership of the subdirs can be set via FifoGroup=,
otherwise it's root. The file permissions of the subdirs are rwxr-x--- (0750).

The fields of a command are separated by tabs (\t), the fields of a list
are separated by spaces, literal spaces in list fields are denoted by "\s".
The command is terminated by a newline (\n).
The same applies to replies. The reply on success is "ok", possibly followed
by the requested information. The reply on error is an errno-style word (e.g.,
"perm", "noent", etc.) followed by a longer explanation.

Global commands:

"login" display ("now"|"schedule") user password [session_arguments]
- login user at specified display. if "now" is specified, a possibly
running session is killed, otherwise the login is done after the
session exits.
session_arguments are printf-like escaped contents for .dmrc. Unlisted
keys will default to previously saved values.

Per-display commands:

- The display is marked as locked. If the X-Server crashes in this state,
no auto-relogin will be performed even if the option is on.

- Reverse the effect of "lock": re-enable auto-relogin.

- The currently running session is forcibly terminated. No auto-relogin is
attempted, but a scheduled "login" command will be executed.

Commands for all sockets:

- Returns a list this socket's capabilities:
"tdm" - identifies tdm, in case some other DM implements this protocol, too.
"list", "activate", "lock", "suicide", "login" - the respective command
is supported.
"bootoptions" - the "listbootoptions" command and the "=" option to
"shutdown" are supported.
"shutdown <list>" - "shutdown" is supported and allowed to the listed users
(comma-separated). "*" means all authenticated users.
"shutdown" - "shutdown" is supported and allowed to everybody.
"nuke <list>" - forced shutdown is allowed to the listed users.
"nuke" - forced shutdown is allowed to everybody.
"reserve <number>" - reserve displays are configured and <number> are
available at this time.

"list" ["all"|"alllocal"]
- Return a list of running sessions. By default all active sessions are
listed. If "all" is specified, passive sessions are listed as well. If
"alllocal" is specified, passive sessions are listed as well, but all
incoming remote sessions are skipped.
Each session entry is a comma-separated tuple of:
- Display or TTY name
- VT name for local sessions
- Logged in user's name, empty for passive sessions and outgoing remote
sessions (local chooser mode)
- Session type or remote host for outgoing remote sessions, empty for
passive sessions
- A flag field:
- "t" for tty sessions
- "*" for the display belonging to the requesting socket
- "!" for sessions that cannot be killed by the requesting socket
- New flags might be added later
- New fields might be added later

"reserve" [timeout in seconds]
- Start a reserve login screen. If nobody logs in within the specified amount
of time (one minute by default), the display is removed again. When the
session on the display exits, the display is removed, too.
- Permitted only on sockets of local displays and the global socket.

"activate" (vt|display)
- Switch to a particular VT (virtual terminal). The VT may be specified
either directly (e.g., vt3) or by a display using it (e.g., :2).
- Permitted only on sockets of local displays and the global socket.

- List available boot options.
=> "ok" list default current
default and current are indices into the list and are -1 if unset or

"shutdown" ("reboot"|"halt") ["="bootchoice] \
start ("-1"|end ("force"|"forcemy"|"cancel")))
- Request a system shutdown, either a reboot or a halt/poweroff.
- An OS choice for the next boot may be specified from the list returned by
- Shutdowns requested from per-display sockets are executed when the current
session on that display exits. Such a request may pop up a dialog asking
for confirmation and/or authentication.
- start is the time for which the shutdown is scheduled. If it starts with
a plus-sign, the current time is added. Zero means immediately.
- end is the latest time at which the shutdown should be performed if active
sessions are still running. If it starts with a plus-sign, the start time
is added. Minus one means wait infinitely. If end is through and active
sessions are still running, TDM can do one of the following:
* "cancel" - give up the shutdown.
* "force" - shut down nonetheless.
* "forcemy" - shut down nonetheless if all active sessions belong to the
requesting user. Only for per-display sockets.
- start and end are specified in seconds since the UNIX epoch.
- "trynow" is a synonym for "0 0 cancel", "forcenow" for "0 0 force" and
"schedule" for "0 -1".
- "ask" attempts an immediate shutdown and interacts with the user if active
sessions are still running. Only for per-display sockets.

"shutdown" "cancel" ["local"|"global"]
- Cancel a scheduled shutdown. The global socket always cancels the currently
pending shutdown, while per-display sockets default to cancelling their
queued request.

"shutdown" "status"
- Return a list with information about shutdowns.
The entries are comma-separated tuples of:
- ("global"|"local") - pending vs. queued shutdown. A local entry can be
returned only by a per-display socket.
- ("halt"|"reboot")
- start
- end
- ("ask"|"force"|"forcemy"|"cancel")
- Numeric user ID of the requesting user, -1 for the global socket.
- The next boot OS choice or "-" for none.
- New fields might be added later.

There are two ways of using the sockets:
- Connecting them directly. FifoDir is exported as $DM_CONTROL; the name
of per-display sockets can be derived from $DISPLAY.
- By using the tdmctl command (e.g., from within a shell script).
Try "tdmctl -h" to find out more.

Here is an example bash script "reboot into FreeBSD":

if tdmctl | grep -q shutdown; then
set -- `tdmctl listbootoptions`
if [ "$1" = ok ]; then
fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}')
if [ -n "$fbsd" ]; then
tdmctl shutdown reboot "=$fbsd" ask > /dev/null
echo "FreeBSD boot unavailable."
echo "Boot options unavailable."
echo "Cannot reboot system."

"It doesn't work!!"

More input! ;-)

TDM accepts two command line options related to logging:

-debug <n>
<n> is a decimal or hexadecimal (prefix 0x) number.
The number is a bitfield, i.e., it is formed by summing up the
required values from this table:
1 (0x1) - core debugging. Probably the most useful one.
2 (0x2) - config reader debugging.
4 (0x4) - greeter debugging.
8 (0x8) - IPC debugging. This logs _all_ communication between the
core, the config reader and the greeter - including the
passwords you type, so edit the log before showing it to
This attempts to synchronize the processes to interleave the
log messages optimally, but will probably fail unless you use
-debug 0x80 as well.
16 (0x10) - wait after forking session sub-daemon.
32 (0x20) - wait after starting config reader.
64 (0x40) - wait after starting greeter.
The wait options are only useful if you need to attach a debugger
to a process, but it crashes before you are able to do so without
the delay. See below.
128 (0x80) - don't use syslog for internally generated messages.
256 (0x100) - core Xauth debugging.
1024 (0x400) - run config reader and greeter through valgrind.
2048 (0x800) - run config reader and greeter through strace.

Logs from "-debug 7" are usually a good start.

-error <file>, -logfile <file>
<file> is the file to log various messages to. The default log file is
/var/log/tdm.log. For internal reasons there is no option in tdmrc to
permanently specify the log file location. If you redirect TDM's
standard error output to a file, TDM will log there.
If TDM is configured to use syslog (and it _very_ probably is on any
modern system), all internally generated messages are logged to the
"daemon" facility. The log usually can be found in /var/log/debug.log
and /var/log/daemon.log; make sure that daemon.* is logged (look at
If you have problems logging in and your system uses PAM (also quite
probable on modern systems), the "auth" and "authpriv" syslog facilities
are interesting, too.

Send me all the logs together with a detailed description of what you did
and what happened. If your problem is related to a specific configuration,
you should also attach a tar.gz archive of your TDM config directory.

If I request a backtrace from you and TDM didn't create one yet via the
usual drkonqi procedure, you'll have to do that yourself. The keyphrase
is "attaching gdb". How exactly this is done depends on the part that
- master daemon. Actually you should never need to attach to it, as
you can start it within the debugger already:
# gdb --args tdm -nodaemon -debug 7
(gdb) run
- display subdaemon. Find (using ps) the process with a name like
"-:0" (where :0 is actually the display this process is for). This
process' PPID is the master daemon. Attach to it this way:
# gdb tdm <the PID you found>
(gdb) cont
If the subdaemon crashes before you can attach, add 16 to the debug flags
when you start TDM.
- config reader. You will have to add 32 to the debug flags almost certainly.
The PPID will be the master daemon as well.
# gdb tdm_config $(pidof tdm_config)
(gdb) cont
- greeter. If it's too fast, add 64 to -debug. The PPID will be the subdaemon.
# gdb tdm_greet $(pidof tdm_greet)
(gdb) cont
The simplification with "pidof" works only if you have only one display,
otherwise you have to find the PID manually (by using ps -fx).
Once you got gdb attached to the offending process, do whatever is needed
to make it crash (probably nothing, if you had to use a delay parameter).
Once it crashed, gdb will tell you a signal name, like SIGSEGV - that's the
first interesting part for me. Then you have to create the actual backtrace:
(gdb) bt
The output of this command is interesting for me.
I might request a backtrace even if nothing crashes, but instead hangs. In
this case don't use "cont" after attaching, but use "bt" right away. If the
process is already running, interrupt it with ctrl-c.
For obvious reasons you have to run gdb on a different virtual terminal than
the X server. To get there, press alt-ctrl-f1 and log in as root. To
switch to the X server's vt, press alt-ctrl-f7 (the exact function key may
be different on your system). You may also use a remote login from a
second machine. In any case it is advantageous to have mouse support on the
debugging console for copying the backtrace.
Note that a backtrace is usually _much_ more useful if the binary contains
debugging info, so you should install from source with the --enable-debug
configure flag if at all possible.

Random rambings and license information

Version 0.1 of TDM is copyright
Matthias Ettrich <>
All later versions copyright:
(C) 1997-2000 Steffen Hansen <>
Since version 0.90 (KDE 2.1) copyright:
(C) 2000-2003 Oswald Buddenhagen <>

The files in the backend directory are licensed under the X licence
(see for more info).
The files in the kfrontend directory are licensed under the GNU GPL.

Thanks to (in no particular order):
Michael Bach Jensen and Torsten Rahn for drawing icons.
Duncan Haldane for investigation of PAM issues.
Stephan Kulow for helping with the autoconf stuff.
Martin Baehr for intensive testing and writing the sample Xsession scripts.
Harald Hoyer <> for the (now obsoleted) chooser.
SuSE for employing me (ossi) for three months to work on tdm.
BasysKom for sponsoring my (ossi's) work on the conversation plugin stuff.
... and _many_ others ...

Have fun with it (and feel free to comment),

Oswald Buddenhagen <>