home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume38 / shadow / part10 / logoutd.c < prev    next >
C/C++ Source or Header  |  1993-08-14  |  5KB  |  283 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  *
  11.  * This software is provided on an AS-IS basis and the author makes
  12.  * no warrantee of any kind.
  13.  */
  14.  
  15. #ifndef lint
  16. static    char    sccsid[] = "@(#)logoutd.c    3.5    07:23:57    08 Apr 1993";
  17. #endif
  18.  
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <stdio.h>
  22. #include <signal.h>
  23. #include <utmp.h>
  24. #include <fcntl.h>
  25. #ifdef    BSD
  26. #include <strings.h>
  27. #else
  28. #include <string.h>
  29. #endif
  30. #include "config.h"
  31.  
  32. #define    HUP_MESG_FILE    "/etc/logoutd.mesg"
  33.  
  34. #ifndef    UTMP_FILE
  35. #define    UTMP_FILE    "/etc/utmp"
  36. #endif
  37.  
  38. #ifdef    SVR4
  39. #include <libgen.h>
  40. #include <unistd.h>
  41. #else
  42. #define    SEEK_SET    0
  43. #endif
  44.  
  45. #ifdef    USE_SYSLOG
  46. #include <syslog.h>
  47.  
  48. #ifndef    LOG_WARN
  49. #define    LOG_WARN    LOG_WARNING
  50. #endif
  51. #endif
  52.  
  53. #ifdef    SVR4
  54. #define    signal    sigset
  55. #endif
  56.  
  57. char    *Prog;
  58.  
  59. char    *mesg_buf = "login time exceeded\r\n";
  60. int    mesg_len = 21;
  61. #ifdef    HUP_MESG_FILE
  62. int    mesg_size;
  63.  
  64. /*
  65.  * reload_mesg - reload the message that is output when killing a process
  66.  */
  67.  
  68. void
  69. reload_mesg (sig)
  70. int    sig;
  71. {
  72.     int    fd;
  73.     struct    stat    sb;
  74.  
  75.     signal (sig, reload_mesg);
  76.  
  77.     if (stat (HUP_MESG_FILE, &sb))
  78.         return;
  79.  
  80.     if ((sb.st_mode & S_IFMT) != S_IFREG)
  81.         return;
  82.  
  83.     if ((fd = open (HUP_MESG_FILE, O_RDONLY)) != -1) {
  84.         if (sb.st_size + 1 > mesg_size) {
  85.             if (mesg_buf && mesg_size)
  86.                 free (mesg_buf);
  87.  
  88.             mesg_len = sb.st_size;
  89.             mesg_size = mesg_len + 1;
  90.             if (! (mesg_buf = (char *) malloc (mesg_len + 1)))
  91.                 goto end;
  92.         } else
  93.             mesg_len = sb.st_size;
  94.  
  95.         if (read (fd, mesg_buf, mesg_len) != mesg_len) {
  96.             mesg_len = 0;
  97.             goto end;
  98.         }
  99.     } else
  100.         return;
  101.  
  102. end:
  103.     close (fd);
  104. }
  105. #endif
  106.  
  107. /*
  108.  * logoutd - logout daemon to enforce /etc/porttime file policy
  109.  *
  110.  *    logoutd is started at system boot time and enforces the login
  111.  *    time and port restrictions specified in /etc/porttime.  The
  112.  *    utmp file is periodically scanned and offending users are logged
  113.  *    off from the system.
  114.  */
  115.  
  116. void
  117. main (argc, argv)
  118. int    argc;
  119. char    **argv;
  120. {
  121.     int    i;
  122.     int    found;
  123.     int    status;
  124.     struct    utmp    utmp;
  125.     int    fd;
  126. #if defined(BSD) || defined(SUN) || defined(SUN4) || defined(HUP_MESG_FILE)
  127.     char    tty_name[BUFSIZ];
  128.     int    tty_fd;
  129. #endif
  130.  
  131. #ifdef    NDEBUG
  132.     for (i = 0;close (i) == 0;i++)
  133.         ;
  134.  
  135. #ifdef    USG
  136.     setpgrp ();
  137. #endif    /* USG */
  138. #if defined(BSD) || defined(SUN) || defined(SUN4) || defined(SVR4)
  139.     setpgid (getpid (), getpid ());
  140. #endif /* BSD || SUN || SUN4 */
  141. #ifdef    HUP_MESG_FILE
  142.     reload_mesg (SIGHUP);
  143. #else
  144.     signal (SIGHUP, SIG_IGN);
  145. #endif    /* HUP_MESG_FILE */
  146.  
  147.     /*
  148.      * Put this process in the background.
  149.      */
  150.  
  151.     if (i = fork ())
  152.         exit (i < 0 ? 1:0);
  153. #endif    /* NDEBUG */
  154.  
  155. #ifdef    USE_SYSLOG
  156.     /*
  157.      * Start syslogging everything
  158.      */
  159.  
  160.     if (Prog = strrchr (argv[0], '/'))
  161.         Prog++;
  162.     else
  163.         Prog = argv[0];
  164.  
  165.     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  166. #endif
  167.  
  168.     /*
  169.      * Scan the UTMP file once per minute looking for users that
  170.      * are not supposed to still be logged in.
  171.      */
  172.  
  173.     while (1) {
  174. #ifdef    NDEBUG
  175.         sleep (60);
  176. #endif
  177.  
  178.         /* 
  179.          * Attempt to re-open the utmp file.  The file is only
  180.          * open while it is being used.
  181.          */
  182.  
  183.         if ((fd = open (UTMP_FILE, 0)) == -1) {
  184. #ifdef    USE_SYSLOG
  185.             syslog (LOG_ERR, "cannot open %s - aborting\n",
  186.                 UTMP_FILE);
  187.             closelog ();
  188. #endif
  189.             exit (1);
  190.         }
  191.  
  192.         /*
  193.          * Read all of the entries in the utmp file.  The entries
  194.          * for login sessions will be checked to see if the user
  195.          * is permitted to be signed on at this time.
  196.          */
  197.  
  198.         while (read (fd, &utmp, sizeof utmp) == sizeof utmp) {
  199. #ifdef    USG_UTMP
  200.             if (utmp.ut_type != USER_PROCESS)
  201.                 continue;
  202.  
  203.             if (isttytime (utmp.ut_user, utmp.ut_line, time (0)))
  204.                 continue;
  205. #endif
  206. #ifdef BSD_UTMP
  207.             if (utmp.ut_name[0] == '\0')
  208.                 continue;
  209.  
  210.             if (isttytime (utmp.ut_name, utmp.ut_line, time (0)))
  211.                 continue;
  212. #endif
  213.             /*
  214.              * Put the rest of this in a child process.  This
  215.              * keeps the scan from waiting on other ports to die.
  216.              */
  217.  
  218.             if (fork () != 0)
  219.                 continue;
  220.  
  221.             if (strncmp (utmp.ut_line, "/dev/", 5) != 0)
  222.                 strcpy (tty_name, "/dev/");
  223.             else
  224.                 tty_name[0] = '\0';
  225.  
  226.             strcat (tty_name, utmp.ut_line);
  227.  
  228. #ifdef    O_NOCTTY
  229.             if ((tty_fd = open (tty_name,
  230.                     O_WRONLY|O_NDELAY|O_NOCTTY)) != -1)
  231. #else
  232.             if ((tty_fd = open (tty_name,
  233.                     O_WRONLY|O_NDELAY)) != -1)
  234. #endif
  235.             {
  236.                 write (tty_fd, mesg_buf, mesg_len);
  237.                 close (tty_fd);
  238.                 sleep (5);
  239.             }
  240. #ifdef    USG_UTMP
  241.             kill (- utmp.ut_pid, SIGHUP);
  242.             sleep (10);
  243.             kill (- utmp.ut_pid, SIGKILL);
  244. #endif    /* USG_UTMP */
  245. #if defined(BSD) || defined(SUN) || defined(SUN4)
  246.  
  247.             /*
  248.              * vhangup() the line to kill try and kill
  249.              * whatever is out there using it.
  250.              */
  251.  
  252.             strcat (strcpy (tty_name, "/dev/"), utmp.ut_line);
  253.             if ((tty_fd = open (tty_name, O_RDONLY|O_NDELAY)) == -1)
  254.                 continue;
  255.  
  256.             vhangup (tty_fd);
  257.             close (tty_fd);
  258. #endif
  259. #ifdef    USE_SYSLOG
  260.             syslog (LOG_NOTICE,
  261.                 "logged off user `%.*s' on `%.*s'\n",
  262.                 sizeof utmp.ut_name, utmp.ut_name,
  263.                 sizeof utmp.ut_line, utmp.ut_line);
  264. #endif    /* USE_SYSLOG */
  265.  
  266.             /*
  267.              * This child has done all it can, drop dead.
  268.              */
  269.  
  270.             exit (0);
  271.         }
  272.  
  273.         /*
  274.          * Reap any dead babies ...
  275.          */
  276.  
  277.         while (wait (&status) != -1)
  278.             ;
  279.  
  280.         close (fd);
  281.     }
  282. }
  283.