Having spent the better part of an entire day trying to figure out how to configure XDM to accomplish what I wanted, I present a complete, working example of my XDM configuration. From what I found while searching via Google, UseNet news postings and private email, I have combined the information, code, and anything else I felt like using into my configuration. As all of the information was freely offered, I also offer this to anyone for any purpose.
My terminology may not be correct; if anyone is so inclined, feel free to send me any changes you feel would make this a better source of information.
Updated October, 2003
I will present my changes in order of features. An individual configuration file may be mentioned more than once as each successive feature is added. The complete set of configuration files is also available for download.
Note that your browser may not render certain characters correctly in the following examples. In particular, the grave-quotes (backward-quotes) will most likely be rendered as a normal single-quote.
! SECURITY: do not listen for XDMCP or Chooser requests ! Comment out this line if you want to manage X terminals with xdm DisplayManager.requestPort: 0Therefore, change the last line to:
!DisplayManager.requestPort: 0
* #any host can get a login window * CHOOSER BROADCAST #any indirect host can get a chooser
:0 local /usr/X11R6/bin/Xas:
#:0 local /usr/X11R6/bin/X
# xdmand then start the X server with the -indirect <hostname> option:
# X -indirect <use your host name here>You should see the CHOOSER menu appear with the local system being available for login. Use Ctl-Alt-Backspace to stop the X server.
I've also added support to call sessreg at the beginning/end of the session so as to update /var/log/lastlog, /var/log/wtmp and /var/run/utmp. I found that I could not use sessreg as the man page suggested; using the -l flag with anything other than a valid tty (or an empty string) would cause the w command to issue an error message. In addition, using $DISPLAY as a search string for Xservers will not work when remote systems log in. I had to devise my own method to assign a slot number.
#
# Two buttons, to reboot or halt the system
#
if { ! [info exists env(DISPLAY)] } {
exit
}
if { ! [file isdirectory /tmp/.X11-unix] } {
exit
}
set pidFile /var/run/buttons.$env(DISPLAY).pid
set ipcFile /tmp/.X11-unix/buttons.[pid]
file delete $ipcFile
if { [catch {exec mkfifo $ipcFile}] } {
exit
}
# Write our PID
set fp [open $pidFile w]
puts -nonewline $fp [pid]
close $fp
# Open IPC fifo and set the graceful termination trigger
proc goaway {} {
file delete $::pidFile
file delete $::ipcFile
exit
}
set fp [open $ipcFile w+]
fileevent $fp readable goaway
# Establish button event handlers
proc shutdown {} {
file delete $::ipcFile
catch {exec /sbin/shutdown -p now >/dev/null 2>/dev/null}
}
proc reboot {} {
file delete $::ipcFile
catch {exec /sbin/shutdown -r now >/dev/null 2>/dev/null}
}
# Create buttons and wait for either a button press or a termination trigger
button .t -borderwidth 3 -width 10 -padx 0 -pady 0 -relief raised -text Reboot -command reboot
button .b -borderwidth 3 -width 10 -padx 0 -pady 0 -relief raised -text Shutdown -command shutdown
grid .t -column 0 -row 0
grid .b -column 0 -row 1
wm geometry . +10-10
/usr/X11R6/bin/xsetroot -solid skyblue4 &
if [ -r /usr/X11R6/lib/X11/xdm/buttons.tcl ]
then
/usr/local/bin/wish /usr/X11R6/lib/X11/xdm/buttons.tcl &
fi
#!/bin/sh
/usr/X11R6/bin/xsetroot -solid skyblue4 &
if [ -r /usr/X11R6/lib/X11/xdm/buttons.tcl ]
then
/usr/local/bin/wish /usr/X11R6/lib/X11/xdm/buttons.tcl &
fi
Make the file executable: chmod +x Setup
# Register login
getTtySlot() {
slot=0
while read line
do
case "$line" in
\#*)
;;
ttyv*)
slot=`expr $slot + 1`
eval set -- $line
if [ "$4" = off ]
then
echo tty=$1 slot=$slot
return
fi
;;
*)
slot=`expr $slot + 1`
;;
esac
done </etc/ttys
}
eval `getTtySlot`
if [ -n "$tty" ]
then
sessreg -a -s $slot -l $tty $USER
fi
# Remove the shutdown/reboot buttons
if [ -r /var/run/buttons.$DISPLAY.pid ]
then
read pid </var/run/buttons.$DISPLAY.pid
if [ -n "$pid" ]
then
if [ -p /tmp/.X11-unix/buttons.$pid ]
then
echo >/tmp/.X11-unix/buttons.$pid
else
# Unfortunately this leaves buttons.tcl registered as an active
# Tk interpreter; applications such as tkcon will erroneously think
# its still active
kill -9 $pid 2>/dev/null
fi
fi
fi
getTtySlot() {
slot=0
while read line
do
case "$line" in
\#*)
;;
ttyv*)
slot=`expr $slot + 1`
eval set -- $line
if [ "$4" = off ]
then
echo tty=$1 slot=$slot
return
fi
;;
*)
slot=`expr $slot + 1`
;;
esac
done </etc/ttys
}
eval `getTtySlot`
if [ -n "$tty" ]
then
sessreg -d -s $slot -l $tty $USER
fi
#!/bin/sh
# Register a remote login
lock() {
while true
do
if mkdir /tmp/.X11-unix/slotLock
then
break
fi
sleep 1
done
}
unlock() {
rmdir /tmp/.X11-unix/slotLock
}
slotFile=/tmp/.X11-unix/slots
lock
if [ -f $slotFile ]
then
if ! fgrep -q -x $DISPLAY $slotFile
then
echo $DISPLAY >>$slotFile
fi
else
echo $DISPLAY >$slotFile
fi
unlock
m=`grep -v '^#' /etc/ttys | wc -l`
n=`fgrep -n -x $DISPLAY $slotFile | cut -d: -f1`
slot=`expr $m + $n`
sessreg -a -l "" -s $slot -h $DISPLAY $USER
# Remove the shutdown/reboot buttons
if [ -r /var/run/buttons.$DISPLAY.pid ]
then
read pid </var/run/buttons.$DISPLAY.pid
if [ -n "$pid" ]
then
if [ -p /tmp/.X11-unix/buttons.$pid ]
then
echo >/tmp/.X11-unix/buttons.$pid
else
# Unfortunately this leaves buttons.tcl registered as an active
# Tk interpreter; applications such as tkcon will erroneously think
# its still active
kill -9 $pid 2>/dev/null
fi
fi
fi
Make the file executable: chmod +x Startup
#!/bin/sh
slotFile=/tmp/.X11-unix/slots
if [ -f $slotFile ]
then
if fgrep -q -x $DISPLAY $slotFile
then
m=`grep -v '^#' /etc/ttys | wc -l`
n=`fgrep -n -x $DISPLAY $slotFile | cut -d: -f1`
slot=`expr $m + $n`
sessreg -d -l "" -s $slot -h $DISPLAY $USER
fi
fi
Make the file executable: chmod +x Xreset
#!/bin/sh /usr/X11R6/bin/xsetroot -solid skyblue4 & /usr/X11R6/bin/oclock -geometry +0-0 & /usr/X11R6/lib/X11/xdm/chooser "$@" kill -KILL $! 2>/dev/nullMake the file executable:
chmod +x Chooser
DisplayManager*setup: /usr/X11R6/lib/X11/xdm/Setup DisplayManager*startup: /usr/X11R6/lib/X11/xdm/Startup DisplayManager*reset: /usr/X11R6/lib/X11/xdm/Xreset DisplayManager*chooser: /usr/X11R6/lib/X11/xdm/Chooser
In order to replace the XFree86 logo on the login screen with a picture of the BSD daemon, we need a pixmap of the daemon. One can be made from /usr/share/examples/BSD_daemon/beastie.fig. Install the xfig port/package and then run:
# cd /usr/share/examples/BSD_daemon # fig2dev -L xpm -m 0.5 beastie.fig > /usr/X11R6/lib/X11/xdm/pixmaps/bsd.xpmTo make the background transparent, patch bsd.xpm with:
--- bsd.xpm.orig Sun Nov 17 19:20:44 2002
+++ bsd.xpm Sun Nov 17 19:25:49 2002
@@ -1,13 +1,12 @@
/* XPM */
static char *noname[] = {
/* width height ncolors chars_per_pixel */
-"212 231 7 1",
+"212 231 6 1",
/* colors */
" c #000000",
". c #00FFFF",
"X c #D10000",
-"o c #FFFFFF",
+"o c none",
"O c #00B000",
"+ c #FFD700",
-"@ c None",
/* pixels */
For placement of the CHOOSER window:
Chooser*geometry: 500x200+150+200To change the title on the CHOOSER menu:
Chooser*label.label: Dave's Home Computing EmpireDo not provide a font for the menu list:
!Chooser*list.font: -*-*-medium-r-normal-*-*-230-*-*-c-*-iso8859-1Not sure what this does...
Chooser*ShapeStyle: OvalUse a different font:
Chooser*Command.font: -adobe-helvetica-bold-r-*-*-12-*Add some pleasing colors:
#ifdef COLOR Chooser*label.foreground: white Chooser*label.background: midnightblue Chooser*Command.background: gray80 Chooser*internalBorderColor: black Chooser*viewport.useRight: true #endifReplace the XFree86 logo with our beloved BSD daemon:
xlogin*logoFileName: /usr/X11R6/lib/X11/xdm/pixmaps/bsd.xpm
Boot-time startup files are added to the /usr/X11R6/etc/rc.d directory. Create this directory if it does not exist. If /etc/defaults/rc.conf does not contain a line looking like:
local_startup="/usr/local/etc/rc.d /usr/X11R6/etc/rc.d"then add the above line to the /etc/rc.conf file. Finally create two files in /usr/X11R6/etc/rc.d:
#!/bin/sh
XDM=/usr/X11R6/bin/xdm
case "$1" in
start)
[ -x $XDM ] && ( $XDM ) && echo -n ' xdm'
;;
stop)
if [ -f /var/run/xdm.pid ]
then
kill -KILL `cat /var/run/xdm.pid` 2>/dev/null && echo -n ' xdm'
fi
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
;;
esac
exit 0
#!/bin/sh
X=/usr/X11R6/bin/X
case "$1" in
start)
[ -x $X ] && ( sleep 5 && $X -wm -indirect `hostname` & ) && echo -n ' X'
;;
stop)
killall XFree86 && echo -n ' X'
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
;;
esac
exit 0
Make them both executable: chmod +x 00xdm.sh 90X.sh
The "sleep 5" above allows you to see the final messages on your console when you boot before the X server starts. (It might also be required so that all the getty's start properly... I'm not sure about this.) You can always use Ctl-Alt-F1 to go back, but I like to see the root login prompt after I boot.
Make the same changes to each system on your network. When completed, you will be given a CHOOSER menu on each system allowing you to login to any system you choose.
The /var/run/buttons.pid file is a poor choice -- if multiple users login at once, the file will be overwritten by the last user. A better choice would be to name the file based on the host:screen. As I cannot login simultaneously, this does not bother me. [Fixed October 2003]
When wish is killed, it leaves itself registerd as an active Tk interpreter. Later Tk applications (such as tkcon) will erroneously think that it is still active. [Fixed October 2003]
The user's connection does not show up with the w or who commands. [Fixed October 2003]
The shutdown/reboot buttons appear on the login screen regardless of which system is given the login screen. Therefore, system A can reboot system B. This is by design. I am the only user on my network, so this does not bother me.
If I use ^R to exit the login screen, I get another login screen. The second time I use ^R, I finally go back to the CHOOSER screen. I don't know why this is happening. It's a minor inconvenience, so I am not going to pursue it further.
| Hit counter: |
|