Taming The X Display Manager

This is the original text which was eventually edited, translated and published in the Issue 4 (Fall 1992) of O'Reilly's X Resource Journal.

OVERVIEW

The X Display Manager, xdm, keeps X running on displays and provides basic user session management. As part of this job, xdm provides an X-based login function via the Xlogin widget, performing essentially the same services as the usual unix getty or login programs. It also provides client cleanup facilities for displays on which the server is no longer running. Finally, xdm automatically generates authorization information which can be used by the X display server to control which users on which hosts may access any given display.

This column will explore some aspects of xdm in depth. It is not meant to replace the xdm man page. which will give further information, such as the complete list of resources used by xdm. This article assumes a basic understanding of administering X on unix systems.

A set of configuration files illustrating the power and flexibility of xdm will be provided at the end of the column. These will also be available via anonymous ftp from $THE_USUAL_OREILLY_FTP_PLACES.

Throughout the rest of the article, the following terms will be used as defined here unless otherwise specified.

Server
will designate an X server.
Display
will refer to either a workstation display or an X terminal.

Whence it Came

xdm was developed by Keith Packard shortly after he joined the X Consortium, primarily as a result of his frustration with trying to manually control X from an ASCII login environment. It was released with X11R3, although there were copies floating about prior to that. Other companies such as Visual were developing their own display managers, but xdm quickly became the standard for most companies. The remaining major holdout is IBM, which ships xdm as an unsupported client and expects that their own x_st_mgr will be run instead (for X terminal support; no support is provided for managing workstation displays).

The X Display Manager Control Protocol (XDMCP) was introduced with X11R4. XDMCP requires that when a controlling client disconnects from a display server, the remaining clients associated with that session also be disconnected. It also allows servers to talk to xdm without requiring xdm to have explicit, prior knowledge of each server.

Also introduced with X11R4 was much better support for security. This support was implemented in the display server, in XDMCP and xdm, and Xlib. A new pseudo-client, xauth, was provided to aid in managing the new security files. At that time, only support for MIT-MAGIC-COOKIE-1 was provided by the Consortium. Three modes of session initiation were provided with R4: BROADCAST, DIRECT and INDIRECT. Of these, only the first two worked. (These modes will be discussed later.)

With X11R5, xdm added real support for the INDIRECT mode, so that users may now select from a list of hosts the host they wish to log into. As part of this, a chooser client is provided, which displays the list of available servers. Also provided with Release 5 is XDM-AUTHENTICATION-1, which allows an X terminal to authenticate xdm, so that passwords are sent only to xdm, not just any program playing password collector. I know of no X terminal vendors currently offering support for this. Ask your terminal vendor.

Why Use It?

Besides the security features and convenience of XDMCP, xdm is the universally accepted method of managing X displays. Like all Consortium software, it is freely available in source form. Most major system and X station vendors support it. It is the only method of controlling X stations common to all vendors.

It provides easily-managed, centralized control over the site X environment. It can provide rudimentary load balancing of the X environment.

How It Works

xdm has a list of servers it is to manage. It also listens on the XDMCP port for others servers requesting management. For each managed server, xdm spawns a copy of itself in which it provides an Xlogin widget. When a user has been authenticated via the normal password techniques, xdm runs the session program (usually a script) to set up the user environment. This includes attempting to run a user-provided setup script or program. Until a user is authenticated, xdm maintains tight control over the display.

After a user has logged in, xdm writes a session key in the .Xauthority file if the authorize resource is set for that display in the xdm-config file. For local servers this key is passed through a file with the -auth switch on the display server command line. For remote servers (X terminals) this information is passed via XDMCP.

When a user terminates the last client started by the session program, or the session is otherwise terminated, xdm makes sure all the clients attached to that server are terminated.

When a session ends normally, xdm sends the server a reset request. This tells the server to drop all connections and reinitialize itself. At this point xdm provides another Xlogin window. If the server has terminated for any reason xdm will restart it if possible (in other words, local servers). In normal operation this only applies if the DisplayManager*DISPLAY*terminateServer resource is set.

The xdm database (other than the authority files) is comprised of flat files. The first file read is xdm's config file, which contains the names of the other database files to read, along with a few high-level resources such as authorize.

                     TABLE 1 - COMMON XDM DATABASE FILES
    Name       Default                 Usage             Release    Notes
------------ -----------------  -----------------------  ------- ------------   
config       xdm-config         configuration            all     command line
                                                                 or resource
servers      XServers           displays to manage       all
resources    XResources         X resource database      all
session      Xsession           session manager          all     runs user
                                                                 session file
             GiveConsole        unsecures console        R5
             TakeConsole        resecures console        R5
startup      Xstartup           root-based housekeeping  pre-R5  available
                                                                 if desired
reset        Xreset             root-based housekeeping  pre-R5  available
                                                                 if desired
setup        Xsetup             server setup             R5
errorLogFile xdm-errors         error log                all
pidFile      xdm-pid            process ID               post-R3
authFile     $HOME/.Xauthority  authorization file       post-R3

Several signals are important to xdm. (All signals will be referenced by their POSIX names.) SIGHUP tells xdm to reread the configuration file and the servers file. SIGINT may be required to coerce xdm into rereading the resources file on some systems. This is very non-standard. SIGTERM tells xdm to shut down all managed servers and exit.

To force a display server reset, xdm sends the server a SIGHUP. xdm sends a SIGTERM signal to force a server to exit. If you need to explicitly send one of these signals, use the unix kill command, as shown below.

reseting xdm      kill -HUP `cat <pidFile>`
halting xdm       kill -TERM `cat <pidFile>`
reseting a server kill -HUP `cat <server_pid>`
halting a server  kill -TERM `cat <server_pid>`
(<pidFile> is the path of xdm's pidFile described below in the resources section. (<server_pid> refers to the process ID (pid) of a local display server.)

Communication Modes

XDMCP allows servers not listed in the servers file to communicate with xdm via one of three modes, DIRECT, INDIRECT, or BROADCAST.

DIRECT mode is used when a server is to attempt to directly communicate to an xdm process on a given system. In BROADCAST mode a server places a general request for management on the network. The first xdm to respond as available becomes the server's manager. INDIRECT mode allows a server to communicate with an xdm process on a given system to find out where it should really be looking for management. This is especially handy in environments running multiple networks, and environments such as DECnet, where no broadcast function is available.

While XDMCP is usually thought of for X terminals, newer servers running on system displays also speak XDMCP. In theory these servers may be brought up as part of the system boot procedure in lieu of (or in addition to, in the case of IBM) a console getty process. This can be a problem if the system running xdm for your server is down. In practical terms this is a terrible idea. About all it's useful for is debugging xdm configurations; local servers usually start much quicker than X terminals booting across networks.

Limitations

If xdm is run on a workstation console display, that display must run X. xdm does not work well in environments where multiple graphics systems attempt to share a display. As most vendors have merged X with their other graphics packages, this is not nearly the problem it formerly was.

Console output redirection was somewhat vendor specific prior to Release 5. Some vendors provided a solution to this problem. With other vendors you had to supply your own solution. A new client, xconsole, was provided in R5 to solve this problem for X in general, not just for xdm. See the man page for xconsole for further information.

While some systems allow you to run a separate display server on each screen of a display (a nonstandard feature), xdm provides no support for this concept.

xdm creates one process per display for login purposes. After login, at least one process is usually consumed by the session script. As some login process and a login shell must normally be provided anyway, the number of processes created by xdm is not really excessive, but you should be aware of what's out there. The last client invoked in the session file may be invoked with the exec command found in all common shells, thus saving one process per server.

Running multiple display managers on multiple systems can provide some ad hoc load balancing, but if you need firm controls over system loading you will have to tweak the configuration files yourself. Some vendors provide load information beside each system available through the chooser client.

GETTING STARTED

Hopefully your system vendor provided xdm. If so, it will most likely be found wherever other X clients are found (typically in /usr/bin/X11). If not, many X terminal vendors provide it. It is also available from MIT with the rest of the X software. or from any of the major net sites archiving X. Configuration files are most commonly found in /usr/lib/X11/xdm .

As delivered, xdm should attempt to manage the system console display (if any), and listen on the XDMCP port for any servers looking to be managed. It should bring up a basic login window prompting for a user name and password. This window may or may not identify the system, depending upon vendor customization.

While many vendors still ship a plain console login as the default, others such as Silicon Graphics now ship xdm as the default method for logging in on the console display.

DEC provides an xdm work-alike.

As delivered with R4, IBM's xdm is seriously broken. If you have installed the X11 development software, you can build a new executable yourself which works much better. The source is is /usr/lpp/X11/Xamples/clients/xdm . You will first have to build imake. Details are given in the /usr/lpp/X11/Xamples/README file (beware - there are a couple of typos). If you don't have the development software available, there may be a patch available by now.

By default most vendors have authorization turned on for the system console; some may have it turned on for all servers. As of R4, the servers file should not need to contain an entry for the system console display. If there is no console display, you need to be sure there is no console entry in the servers file, as xdm will attempt to manage any display listed therein.

Configuring X terminals to use xdm with minimal configuration of xdm varies widely according to manufacturer. Some X terminals will come up in BROADCAST mode by default; others initially require a host name and DIRECT mode. Older X terminals not using XDMCP will require a servers file entry.

If your X terminals provide a built-in chooser menu, BROADCAST mode works great. If not, in R5 you should use INDIRECT mode with the chooser client. Older versions of xdm generally work best with DIRECT mode.

The configuration files usually default as noted in Table 1 above, providing basic functionality with no frills, and reasonable security. Even if you are currently running a simple xdm configuration you should glance through these files for obvious problems, and to familiarize yourself with them.

Starting xdm

xdm is typically started at system boot time. This is typically done in either an rc file in the /etc directory, or in the inittab file.

Starting xdm in an rc file is usually simply a matter of adding the desired command line to the file, as in the example below.

/usr/bin/X11/xdm -daemon -config /usr/lib/X11/xdm-config &

IBM wants xdm to integrate into their src subsystem. The AIX version of the above command is a bit different.

start /usr/bin/X11/xdm $src_running
The problem with this is that since xdm is not supported in R4 under AIX, it is not really integrated into the src subsystem, so the attendant startup, shutdown, and other src commands do not work properly. An alternative, which works on many other systems as well, is to start xdm from the inittab file.
xdm:2:respawn:/usr/bin/X11/xdm -nodaemon -config /usr/lib/X11/xdm-config
The -nodaemon flag keeps xdm from starting a daemon and exiting, which would cause the respawn option to start another copy of xdm, whereupon the process would repeat itself, quickly filling up your process table and dragging your system to its knees attempting to run oodles of managers and servers. xdm attempts to use system lock calls to prevent this from happening. It nevertheless happens on some systems.

Updating xdm's List of Servers

The servers file is not reread every time it is modified. xdm rereads it only when a session terminates (if autoRescan is enabled - see the resources section), or when it receives a SIGHUP signal. Forcing changes to take place immediately requires sending the SIGHUP signal as described earlier.

If You Have Problems

If a server is not displaying a login window as expected, check first to see if the server is running by moving the pointer (usually a mouse) device and making the sure the cursor moves. If a server has no entry in the servers file, be sure that server supports, and is configured for, the proper XDMCP mode. Check to see if the proper number of xdm processes is running - there should be one copy for the main manager and one for each server requiring a login window. xdm modifies its command line arguments to show the name of the display being managed. This is a big debugging aid. Unfortunately, this does not work on all systems.

Check the errorLogFile. If a server is having problems connecting, or dying mysteriously, there will usually be an entry in this file. Resource problems, such as not being able to find a font, will also show up here.

On systems running R4 and earlier releases of X software, user session file errors (such as not being able to find clients) will also appear here. As of R5 these messages will be in the user's session-errors file.

If the login process appears to be failing, try using the failsafe option. This may take the form of using the [F1] key instead of the [RETURN] key, or it may be simply a button to press after the user name and password have been entered. This option provides a minimal session for debugging. By default this is usually an xterm client. Some vendors also run a window manager.

If all else fails, you can run xdm with the -debug command line option. As the man page notes, this option was primarily intended for the developers, and output may or may not be helpful.

CUSTOMIZATION

One of the great strengths of xdm is that it is extremely customizable. Like most well-written X programs, it provides a number of resources to control both appearance and behavior. Unlike many X programs, the built-in defaults are usable in almost every case; many sites run xdm without ever changing anything at all. But it is quite easy to customize. Running multiple configurations is quite easy due to the power and flexibility provided by the config file.

Some of the following files are processed by xrdb, which means that variables known to xrdb are expanded. The most interesting of these is probably CLIENTHOST, which contains the name of the host running the login session.

As is always true with xrdb, both class and instance names are supported. Names beginning with lower case letters are instance names. Names beginning with upper case letters are class names, and apply to all instances of that class. An example of a class is DisplayManager; since various instances may (should) have different names, the only way to apply something to all of them is through the class.

config File

A typical Sun configuration file looks like this.

DisplayManager.servers:         $OPENWINHOME/lib/xdm/Xservers
DisplayManager.errorLogFile:    /usr/tmp/xdm-errors
DisplayManager.pidFile:         /usr/tmp/xdm-pid
DisplayManager*resources:       $OPENWINHOME/lib/xdm/Xresources
DisplayManager*session:         $OPENWINHOME/lib/xdm/Xsession
DisplayManager*authorize:       true
DisplayManager*reset:           $OPENWINHOME/lib/xdm/Xreset
DisplayManager.remoteAuthDir:   $OPENWINHOME/lib/xdm
DisplayManager._0.xrdb:         $OPENWINHOME/lib/xdm/xrdb.sh
DisplayManager._0.authorize:    true
DisplayManager._0.authFile:     /usr/tmp/server-auth
DisplayManager._0.resetForAuth: true
DisplayManager._0.userPath:     "/etc:/bin:/usr/bin:/usr/ucb:$OPENWINHOME/bin"
DisplayManager._0.systemPath:   "/etc:/bin:/usr/bin:/usr/ucb:$OPENWINHOME/bin"
The _0 construct is something you have probably never seen before. Since a colon normally indicates the end of a resource name, all colons that would otherwise be part of a resource name in this file are entered as underscores. So what you would normally designate as :0 you designate as _0 in the config file.

For displays, the display name is the instance name, and the display class (see next section) is the class name.

sample instance names  _0, ncd1_0, muttonhead_0
sample class name      NCD-19C

Note again that these resources are per-display, not per-screen.

servers File

The servers file contains one entry per server to be directly managed by xdm. Servers speaking XDMCP may be listed here but need not be. (This becomes a real problem if multiple display managers are running; more than 1 login window may appear on a given terminal. In such cases, logins may even appear after the user session has started, resulting in the X terminal locking up.) This file replaces the per-user .xserverrc file used by xinit.

                     TABLE 2 - SERVER ENTRY FIELDS
     Name           Usage                          Notes
--------------  ----------------  ------------------------------------------
display         standard format   :0 is usually adequate for console display
display class   vendor string     optional, often blank
type            local or foreign  local only if server to run locally
server command  varies            (local type) server command line
The display class is intended for use in resource parsing. Servers using XDMCP are supposed to supply their own display class to xdm, but you may supply one here anyway.

The server command can be the path of the server itself or it can be the path of a shell script or program which provides other functionality as well as running the server. Sun's StartOW script is an example of this; it sets up and modifies some environment variables the server requires. This keeps Sun's server command line interface as close to the X Consortium's as possible while still allowing added functionality.

When using a script in this way the server should always be started via the shell exec command. xdm assumes the server is a direct child, not some further removed descendent.

As the server is started here, this is also where you designate things such as font path, which becomes a major issue with R5 and the font server.

resources File

This file is where the xdm resources are set. These resources may be common to xdm, specific to the Xlogin window, specific to a display class, or even to a display.

             TABLE 3 - RESOURCE FORMATS
                Example                      Usage
--------------------------------------- -----------------
DisplayManager*resource:                common
DisplayManager.dpyClass.CLASS*resource: per display class
DisplayManager.DISPLAY*resources:       per display
xlogin.Login.resource:                  xlogin only
Resources specific to xlogin may be customized per display via a DisplayManager.DISPLAY.resources file.

Most vendors ship with a fairly simple set of xdm resources. It typically looks something like the following (essentially what was shipped with R4 by the X Consortium).

xlogin*login.translations: #override\\\\
        <Key>F1: set-session-argument(failsafe) finish-field()\\\\n\\\\
        <Key>Return: set-session-argument() finish-field()
xlogin*borderWidth:     3
#ifdef COLOR
xlogin*greetColor:      #f63
xlogin*failColor:       red
xlogin*Foreground:      black
xlogin*Background:      #fdc
#else
xlogin*Foreground:      black
xlogin*Background:      white
xlogin.Login.greeting:  Welcome to the X Window System
#endif
Probably the most common resources set are the ones involving the xlogin appearance, and those relating to authorization.

Again, xrdb is used in X resource parsing, so all its power is available. Among other things this means xrdb variables will expand in the resource files. The COLOR symbol in the sample file is defined by xrdb, as are a number of others, such as HOST and CLIENTHOST. These allow greeting customization.

xlogin.Login.greeting: Welcome to HOST
See the xrdb(1) man page for further information.

This file is the one place per-screen resources may be set (as of X11R5).

session File

The session file sets up the basic environment and attempts to run a user session script. If no user session file is available, a default session is run, typically consisting of an xterm and a window manager (MIT ships with twm). Vendors typically use their favorite window manager, and may add one or two extra clients. You might wish to add something yourself, such as xclock. If a user resources file (usually .Xresources) is available, it is loaded via xrdb. Depending upon the vendor, the user session script may be .xinitrc, .xsession, or whichever of the two is available. This is one reason users should be encouraged to have one file for both xinit and xdm. In environments where this will not work, a link between two will suffice. Some vendors also customize the session file to perform special operations such as keyboard remapping. (If Xsetup is available, keyboard remapping should occur there so the keyboard is correct in the login window.)

xdm does not run a user's .profile or .login script. This is because unix thinks login shells always run from what it understands as a terminal, and the shell code is hacked accordingly. One way to get around this (at least in csh and ksh) is to test for a variable in the per-shell config file (such as chsrc), and if it is not defined, run the login script.

# at end of .cshrc
if ( $?DO_LOGIN == 0 ) then
        source ~/.login
fi

# in .login
setenv DO_LOGIN 1

startup and reset Files

These were used primarily by the pre-R4 versions of xdm for such things as faking utmp entries. startup is now seldom used. reset is still handy for cleanup, as it is always run, even if xdm dies.

GiveConsole

This appeared in the R5 release. It basically changes the ownership of the console to the user's UID after the login has taken place.

TakeConsole

Also appearing in the R5 release, this returns ownership of the console to root when the user logs out.

setup

Added in X11R5, setup runs before the xlogin window is displayed. Since this is a command to run, any command may be used, including a script running multiple commands. This is a typical place t use display classes.

DisplayManager.NEWT-23-COLOR.setup: xsetroot -bg blue
DisplayManager.NEWT-23-MONO.setup: xsetroot -bg black
DisplayManager.NEWT-23-GRAY.setup: xsetroot -bg gray21
DisplayManager.muttonhead_0.setup: xfish

WHAT CAN THE USER DO?

Users can basically do the same sorts of things as they have done with xinit. The user session script can usually be in the user's preferred shell, whereas under xinit the .xinitrc file had to be a bourne shell script. Some users like to customize their environment; these will do so regardless of what you do. For those who don't want to mess with it, or who don't know much about it, you should provide a reasonable default environment with a couple of xterms, a window manager, and an xclock at the very least. For those migrating from a PC environment, you will definitely want to start a desktop environment if one is available on your systems.

While you could do this in the system session file, such changes could be lost in an upgrade. You may wish to simply provide a sample user session file to get new users started.

RUNNING MULTIPLE DISPLAY MANAGERS

For maximum flexibility you may wish to run multiple copies of xdm with different configuration files. Running each manager on a separate system also provides some rudimentary load balancing. (As xdm provides no capability for using different XDMCP sockets, you don't want to run multiple copies of xdm on a single system.) Even without tying displays to specific systems, the less loaded systems will usually accept new servers before busier systems. Of course, system loading varies over time, so this form of load balancing is crude.

Network loading also comes into play here, and a little planning will let you use routers and gateways to your advantage in keeping network loads lighter by isolating servers and their managers on subnets.

Other sites prefer running multiple servers to keep work groups together on certain systems, or to tie certain users' home displays to their default systems. (This is probably the most common reason for running multiple display managers.) INDIRECT mode also provides this capability.

Finally, this might be used to isolate certain sets of displays for security reasons, or for licensing reasons, or to provide more turnkey environments. (Customized session files can also help with per-display customization.)

Even running multiple managers does not require much extra work; because of the flexibility of configuration files, in most cases the same (or very nearly the same) files can be used on each system.

The crudest load balancing is performed by having all servers run in BROADCAST mode. This allows the systems with the (current) lightest loads to manage available servers. All available systems will respond to the request, but the first responder will become the manager for that display.

Setting each server up to attach directly to a particular manager gives you the most control. This would be done by having each display set up to use the DIRECT XDMCP mode, for direct connection to a given system. The obvious problem here is that if that system is down, the display will not be able to connect.

Alternatively, one system can be the focal point of all initial attachments, via the INDIRECT mode. An R5 manager, if the XAccess file is present, provides a list of available systems running managers from which the user can pick with the mouse via the chooser client (or the X terminal's builtin chooser, if provided).

Combinations of these modes may also be used at large sites.

SECURITY

Until a user successfully logs in, a display is as secure as any network login (passwords are passed over the network in cleartext).

Servers running under xdm have at least the same security as they would without xdm. In other words, they are on their own, with the help of the xhost command. You can try

xhost -
and then add hosts one at a time as needed, or set up a minimal /etc/Xn.hosts file. The latter method is preferred, as on some systemsZZ the former method prevents all further communication with the server by any clients, including xhost. Try this on your systems before recommending anyone else use it, or adding it to any system xdm configuration files.

R5 allows per-user access control with xhost as well, if you are running Sun's Secure RPC.

Beyond this, however, R4 and later versions of xdm provide per-user, per-host based security. This is handled through the authorization files and resources. The authorization file (typically $HOME/.Xauthority) file contains information on which servers a user is allowed access to, along with an authentication type and key. If the user's file contains correct authorization data (the display and user names correlate) and authentication data (the key matches), the server will allow the user to run clients from the user's current system on the display.

(Note that display names should match exactly. The name :0 should always match unix:0, but will not match localhost:0 due to a bug in Xlib. It will not match $HOSTNAME:0. As far as using hostnames, domains should not matter, nor should aliases. Names are converted to addresses before matching is attempted.)

These files are managed via the xauth command. This is not strictly an X client as it never connects to the server. It simply provides a method of managing authentication data. It cooperates with xdm via file locking to assure the authorization files are not corrupted. The two most common uses of xauth are to list the current database, and to copy information from one system to another. It can be used in an interactive mode, where it prompts for commands (such as list to see the current data), or it can be run strictly from the command line, as when merging data from one system to another. The man page describes its use fully.

It is a good idea to keep authorization turned on, especially for displays where root might be logged in. Otherwise, root's session script should probably use xhost to turn off all connectivity.

Xaccess File

The Xaccess file is straightforward and powerful. It uses shell-style pattern matching for display names. You can explicitly allow or disallow displays or groups of displays, such as

eng*      # allow all terminals in engineering
!*mkt*    # disallow all marketing terminals
mkt_head  # allow head of marketing per eng. VP orders
(This assumes all engineering terminal network names begin with 'eng', and that marketing terminal names contain the string 'mkt' somewhere in the name.)
Last updated: 10 July 1996

Copyright 1992, 1994 Miles O'Neal, Austin, TX. All rights reserved.

Miles O'Neal <roadkills.r.us@XYZZY.gmail.com> [remove the "XYZZY." to make things work!] c/o RNN / 1705 Oak Forest Dr / Round Rock, TX / 78681-1514