home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Unix / c-src / chusr.c < prev    next >
C/C++ Source or Header  |  1999-11-04  |  4KB  |  204 lines

  1. /*
  2. The problem often seems to arise in dealing with terminated
  3. xterms.  (This is yet another reason for why we need a real
  4. session manager.)  Rebooting to fix utmp is unduly harsh!
  5. Just use a binary editor of some sort or write a single-purpose
  6. script to hammer a null at the beginning of the entry.  In
  7. either case, you'll need to understand the format of utmp(5).
  8.  
  9. Or you could use the following program, written by a younger
  10. version of myself long ago and far away.  It's aesthetically
  11. bothersome in various ways, but it still works well enough to
  12. get the job done on the machines I have to deal with, even today.
  13.  
  14. To clear an entry on say ttyp5, as root type:
  15.  
  16.     chusr '' ttyp5
  17.  
  18. --tom
  19. */
  20.  
  21. /*
  22.  * chusr.c -- change user entry in utmp 
  23.  *
  24.  * Tom Christiansen (1984), for BSD4.2 systems
  25.  *
  26.  * (various minor hacks since then, like 4.3 compat stuff)
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <pwd.h>
  31. #include <sys/file.h>
  32. #include <sysexits.h>
  33. #include <syslog.h>
  34. #include <utmp.h>
  35.  
  36. #define SCPYN(to,from) (void) strncpy(to,from,sizeof(to))
  37.  
  38. #ifndef BSD42
  39. #    define BSD43 1
  40. #endif
  41.  
  42.  
  43. char   *strncpy ();
  44. char   *ttyname ();
  45. char   *index ();
  46. char   *rindex ();
  47. int     strncmp ();
  48.  
  49. main (ac, av)
  50.     char  **av;
  51. {
  52.     struct utmp utmp;            /* new utmp entry for utmp file */
  53.  
  54.     int     nentries,            /* how many we got */
  55.             ufd,            /* utmp's fd */
  56.             tslot,            /* where to put the entry */
  57.             tflag = 0;            /* update time? */
  58.  
  59.     char   *mytty = "/dev/ttyXXXX",    
  60.        *ufile = "/etc/utmp", 
  61.        *s;
  62.  
  63.     if (ac < 2 || ac > 4)
  64.     usage (*av);
  65.  
  66.  
  67.     if (!strcmp (av[1], "-t")) {
  68.     tflag++;
  69.     av++;
  70.     ac--;
  71.     }
  72.     s = av[2];
  73.  
  74.     if ((ufd = open (ufile, O_RDWR)) < 0) {
  75.     perror (ufile);
  76.     exit (EX_OSFILE);
  77.     }
  78.     if (ac == 2) {
  79.     if ((mytty = ttyname (fileno (stdin))) == NULL) {
  80.         fprintf (stderr, "%s: no tty\n", *av);
  81.         exit (EX_UNAVAILABLE);
  82.     }
  83.     } else {
  84.     if (strlen (s) == 2) {
  85.         if (s[0] == 'c' && s[1] == 'o')
  86.         strcpy (rindex (mytty, '/') + 1, "console");
  87.         else if (s[0] == 'e' && s[1] == 'x')
  88.         strcpy (rindex (mytty, '/') + 1, "express");
  89.         else
  90.         strcpy (index (mytty, 'X'), s);
  91.     } else {
  92.         char *i1 = index (mytty, 't');
  93.         char *i2 = index (s, 't');
  94.         if (!i1) {
  95.         printf(stderr,"no t in %s\n", mytty);
  96.         exit(17);
  97.         } 
  98.         if (!i2) {
  99.         printf(stderr,"no t in %s\n", s);
  100.         exit(18);
  101.         } 
  102.         strncpy (i1, i2, 7);
  103.     }
  104.     }
  105.  
  106.     mytty += 5;                /* skip "/dev/" */
  107.  
  108.     if (!(tslot = ttyslot (mytty))) {
  109.     fprintf (stderr, "no tty\n");
  110.     exit (1);
  111.     }
  112.     lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
  113.     read (ufd, (char *) &utmp, sizeof (utmp));
  114.  
  115. #ifdef LOG_AUTH
  116.     openlog ("chusr", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
  117. #else
  118.     openlog ("chusr", LOG_PID);
  119. #endif
  120.  
  121.     syslog (LOG_NOTICE, "\"%.*s\" changed to \"%s\" on %s\n",
  122.         sizeof (utmp.ut_name), utmp.ut_name, av[1], mytty);
  123.     closelog();
  124.     SCPYN (utmp.ut_name, av[1]);
  125.     SCPYN (utmp.ut_line, mytty);
  126.     if (ac == 4)
  127.     SCPYN (utmp.ut_host, av[3]);
  128.     if (tflag)
  129.     time (&utmp.ut_time);
  130.     lseek (ufd, (long) (tslot * sizeof (utmp)), 0);
  131.     write (ufd, (char *) &utmp, sizeof (utmp));
  132.     (void) close (ufd);
  133. }
  134.  
  135.  
  136. usage (name)
  137.     char   *name;
  138. {
  139.     fprintf (stderr, "usage: %s user [-t] [ tty [whence] ]\n", name);
  140.     exit (EX_USAGE);
  141. }
  142.  
  143. /* 
  144. /*
  145.  * Return the number of the slot in the utmp file
  146.  * corresponding to the passed tty.
  147.  * returns 0 on error.
  148.  */
  149.  
  150. char   *getttys ();
  151. static char ttys[] = "/etc/ttys";
  152.  
  153. #define    NULL    0
  154.  
  155. ttyslot (tty) 
  156.     register char *tty;
  157. {
  158.     register char *tp, *p;
  159.     register s;
  160.     FILE   *tf;
  161.     tp = tty;
  162.  
  163.     if ((p = rindex (tp, '/')) == NULL)
  164.     p = tp;
  165.     else
  166.     p++;
  167.     if ((tf = fopen (ttys, "r")) == NULL)
  168.     return (0);
  169.     s = 0;
  170.     while (tp = getttys (tf)) {
  171.     s++;
  172.     if (strncmp (p, tp, strlen (p)) == 0) {
  173.         fclose (tf);
  174.         return (s);
  175.     }
  176.     }
  177.     fclose (tf);
  178.     return (0);
  179. }
  180.  
  181. static char *
  182. getttys (f)
  183.     FILE   *f;
  184. {
  185.     static char line[256];
  186.     register char *lp;
  187.  
  188.     do {
  189.     if (fgets (line, 256, f) == NULL)
  190.         return NULL;
  191.     } while (*line == '#');        /* ignore comment lines */
  192.  
  193.     for (lp = line;; lp++) {
  194.     if ((*lp == '\t') || (*lp == ' ') || (*lp == '\n')) {
  195.         *lp = '\0';
  196. #ifdef BSD43
  197.         return (line);
  198. #else
  199.         return (line + 2);
  200. #endif
  201.     }
  202.     }
  203. }
  204.