Package: timeoutd
Version: 1.5-9
Severity: important
Tags: patch

timeoutd doesn't recognise remote X sessions and these cause a crash.

Also it doesn't call XCloseDisplay which leads to the max number of
clients for an X server being reached over time.

Patch to fix these supplied. I have been running with this patch for a
month now and it works well for me, and stops my children for using the
computers for hours!

Hope it is useful.

Mark

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (400, 'testing'), (300, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.13
Locale: LANG=en_GB, LC_CTYPE=iso_8859_1 (charmap=ISO-8859-1) (ignored: LC_ALL 
set to en_GB)

Versions of packages timeoutd depends on:
ii  libc6              2.3.5-6               GNU C Library: Shared libraries an
ii  libx11-6           4.3.0.dfsg.1-14sarge1 X Window System protocol client li
ii  libxext6           4.3.0.dfsg.1-14sarge1 X Window System miscellaneous exte
ii  libxss1            6.8.2.dfsg.1-11       X Screen Saver client-side library
ii  xlibs              6.8.2.dfsg.1-7        X Window System client libraries m

-- no debconf information
diff -ur timeoutd-1.5/debian/changelog /usr/src/timeoutd-1.5/debian/changelog
--- timeoutd-1.5/debian/changelog	2006-01-09 14:58:09.000000000 +0000
+++ /usr/src/timeoutd-1.5/debian/changelog	2006-01-12 16:19:00.000000000 +0000
@@ -1,3 +1,12 @@
+timeoutd (1.5-9moh) unstable; urgency=low
+
+  * Don't crash when X server is not contactable
+  * Recognise remote X sessions
+  * XCloseDisplay to free resources
+  * Rename shutdown() to prevent conflict with netdb.h
+
+ -- Mark Hindley <[EMAIL PROTECTED]>  Wed,  4 Jan 2006 11:16:31 +0000
+
 timeoutd (1.5-9) unstable; urgency=low
 
   * Removed "-m486" because it breaks builds on other archs.
Only in /usr/src/timeoutd-1.5/debian: changelog~
Only in /usr/src/timeoutd-1.5/debian: files
Only in /usr/src/timeoutd-1.5/debian: timeoutd
Only in /usr/src/timeoutd-1.5/debian: timeoutd.postinst.debhelper
Only in /usr/src/timeoutd-1.5/debian: timeoutd.postrm.debhelper
Only in /usr/src/timeoutd-1.5/debian: timeoutd.prerm.debhelper
Only in /usr/src/timeoutd-1.5/debian: timeoutd.substvars
Only in /usr/src/timeoutd-1.5: dump_wtmp
Only in /usr/src/timeoutd-1.5: .gdbinit
Only in /usr/src/timeoutd-1.5: timeoutd
diff -ur timeoutd-1.5/timeoutd.c /usr/src/timeoutd-1.5/timeoutd.c
--- timeoutd-1.5/timeoutd.c	2006-01-09 14:58:09.000000000 +0000
+++ /usr/src/timeoutd-1.5/timeoutd.c	2006-01-12 16:22:53.000000000 +0000
@@ -44,8 +44,13 @@
 #include    <dirent.h>
 
 #ifdef TIMEOUTDX11
+#include <netdb.h>
 #include <X11/Xlib.h>
 #include <X11/extensions/scrnsaver.h>
+
+#define TIMEOUTD_XSESSION_NONE 0
+#define TIMEOUTD_XSESSION_LOCAL 1
+#define TIMEOUTD_XSESSION_REMOTE 2
 #endif
 
 #define OPENLOG_FLAGS	LOG_CONS|LOG_PID
@@ -131,7 +136,7 @@
 struct utmp *utmpp;         /* pointer to utmp file entry */
 char        *ctime();       /* returns pointer to time string */
 struct utmp *getutent();    /* returns next utmp file entry */
-void	    shutdown();
+void	    shut_down();
 void	    read_config();
 void	    reread_config();
 void        reapchild();
@@ -252,7 +257,7 @@
 int	argc;
 char	*argv[];
 {
-    signal(SIGTERM, shutdown);
+    signal(SIGTERM, shut_down);
     signal(SIGHUP, reread_config);
     signal(SIGCHLD, reapchild);
     signal(SIGINT, SIG_IGN);
@@ -1042,19 +1047,20 @@
     host[sizeof(host) - 1] = '\0';
     strncpy(dev, utmpp->ut_line, sizeof(dev) - 1);    /* get device name */
     dev[sizeof(dev) - 1] = '\0';
-    if (stat(dev, pstat) && !chk_xsession(dev, host))   /* if can't get status for
-    port && if it's no Xsession*/
+    if (stat(dev, pstat) && !chk_xsession(dev, host) == TIMEOUTD_XSESSION_LOCAL)   /* if can't get status for 
+    port && if it's not a local Xsession*/
     {
         sprintf(errmsg, "Can't get status of user %s's terminal (%s)\n",
         	user, dev);
-        bailout(errmsg, 1);
+	/* bailout(errmsg, 1); MOH: is there a reason to exit here? */
+	return; 
     }
     /* idle time is the lesser of:
      * current time less last access time OR
      * current time less last modified time
      */
 #ifdef TIMEOUTDX11	
-    if(chk_xsession(dev, host) && !chk_xterm(dev, host)) { /* check idle for Session, but not for xterm */
+    if(chk_xsession(dev, host) && !chk_xterm(dev, host)) { /* check idle for Xsession, but not for xterm */
     	idle = get_xidle(user, dev) / 1000 / 60; /* get_xidle returns millisecs, we need mins */
 	openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
 	syslog(SYSLOG_DEBUG, "get_xidle(%s,%s) returned %dmins idle for %s.", dev, host, (int)idle, user);
@@ -1126,7 +1132,7 @@
     exit(status);
 }
 
-void shutdown(signum)
+void shut_down(signum)
 int signum;
 {
     openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
@@ -1183,9 +1189,15 @@
    struct passwd	*pw;
 #endif
 
-    if(chk_xsession(dev, host) && !chk_xterm(dev, host)) {
+    if(!chk_xterm(dev, host)) {
+      if (chk_xsession(dev, host)) {
 	killit_xsession(utmpp->ut_pid, user, dev);
-    	return;
+      } else {
+	openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
+        syslog(LOG_ERR, "Unable to logoff remote session %s from %s.", dev, host);
+        closelog();
+      }
+      return;
     }
 /* Tell user which limit they have exceeded and that they will be logged off */
     if ((tty = open(dev, O_WRONLY|O_NOCTTY|O_NONBLOCK)) < 0)
@@ -1347,7 +1359,7 @@
 #endif
 }
 
-int chk_xsession(dev, host) /* returns 1 when dev and host seem to be a xSession. */
+int chk_xsession(dev, host) /* returns TIMEOUTD_XSESSION_{REMOTE,LOCAL,NONE} when dev and host seem to be a xSession. */
 char *dev,*host;
 {
     if(strncmp(dev, ":0", 1) == 0 && strlen(host) == 0 /*|| 
@@ -1367,10 +1379,24 @@
        */       
       #ifdef DEBUG
          openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
-         syslog(LOG_DEBUG, "Xsession detected. device=%s host=%s", dev, host);
+         syslog(LOG_DEBUG, "LOCAL Xsession detected. device=%s host=%s", dev, host);
+         closelog();
+      #endif
+	 return TIMEOUTD_XSESSION_LOCAL;
+    }
+    else if (strstr(dev, ":") && strlen(host) > 1 && gethostbyname(host)) {
+      /* What about remote XDMCP sessions?
+       * USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
+       * mark     pts/3    mercury           Sat11    0.00s 10.99s  0.04s w
+       * rebecca  ap:10    ap                10:32    0.00s  0.00s  1.28s x-session-manager
+       */
+
+      #ifdef DEBUG
+         openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
+         syslog(LOG_DEBUG, "REMOTE Xsession detected. device=%s host=%s", dev, host);
          closelog();
       #endif
-      return 1;
+      return TIMEOUTD_XSESSION_REMOTE;
     }
     else {
       #ifdef DEBUG
@@ -1378,7 +1404,7 @@
          syslog(LOG_DEBUG, "NO xsession detected. device=%s host=%s", dev, host);
          closelog();
       #endif
-      return 0;
+      return TIMEOUTD_XSESSION_NONE;
     }
 }
 
@@ -1501,6 +1527,7 @@
 	char homedir[50]; /*50 should be enough*/
 	char oldhomedir[50];
 	uid_t oldeuid;
+	Time retval = 0;
 
 	pwEntry = getpwnam(user);
 	if(!pwEntry) {
@@ -1533,21 +1560,22 @@
 	putenv(homedir);
 
 	/* First, check if there is a xserver.. */ 
-	if (!(dpy = XOpenDisplay (display))) { /* = intended */
+	if ((dpy = XOpenDisplay (display)) == NULL) { /* = intended */
 		openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
 		syslog(LOG_NOTICE, "Could not connect to %s to query idle-time for %s. Ignoring.", display, user);
 		closelog();
-	}
-
+	} else {
 	if (!mitInfo) 
-		mitInfo = XScreenSaverAllocInfo ();
-    	XScreenSaverQueryInfo (dpy, DefaultRootWindow (dpy), mitInfo);
-	
+	  mitInfo = XScreenSaverAllocInfo ();
+	XScreenSaverQueryInfo (dpy, DefaultRootWindow (dpy), mitInfo);
+	retval = mitInfo->idle;
+	XCloseDisplay(dpy);
+	}
 	/*go back again*/
 	putenv(oldhomedir);
 	setuid(oldeuid);
 
-    	return mitInfo->idle;
+    	return retval;
 } /* get_xidle(user) */
 #endif
 
Only in /usr/src/timeoutd-1.5: timeoutd.c~
Only in /usr/src/timeoutd-1.5: timeoutd.o

Reply via email to