home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / faillog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  5.5 KB  |  295 lines

  1. /*
  2.  * Copyright 1989, 1990, 1992, 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.  
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <stdio.h>
  15. #include "pwd.h"
  16. #include <time.h>
  17. #ifndef    BSD
  18. #include <string.h>
  19. #include <memory.h>
  20. #else
  21. #include <strings.h>
  22. #define    strchr    index
  23. #define    strrchr    rindex
  24. #endif
  25. #ifdef    STDLIB_H
  26. #include <stdlib.h>
  27. #endif
  28. #ifdef    UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31. #include "config.h"
  32. #include "faillog.h"
  33.  
  34. #ifndef    lint
  35. static    char    _sccsid[] = "@(#)faillog.c    3.3    20:36:23    3/7/92";
  36. #endif
  37.  
  38. FILE    *fail;        /* failure file stream */
  39. uid_t    user;        /* one single user, specified on command line */
  40. int    days;        /* number of days to consider for print command */
  41. time_t    seconds;    /* that number of days in seconds */
  42. int    max;        /* maximum failure count for fail_max */
  43.  
  44. int    aflg;        /* set if all users are to be printed always */
  45. int    uflg;        /* set if user is a valid user id */
  46. int    tflg;        /* print is restricted to most recent days */
  47. struct    stat    statbuf; /* fstat buffer for file size */
  48.  
  49. #if !defined(UNISTD_H) && !defined(STDLIB_H)
  50. extern    int    optind;
  51. extern    char    *optarg;
  52. extern    char    *asctime ();
  53. extern    struct    passwd    *getpwuid ();
  54. extern    struct    passwd    *getpwnam ();
  55. extern    struct    passwd    *getpwent ();
  56. extern    struct    tm    *localtime ();
  57. #endif
  58.  
  59. #if    __STDC__
  60. void    print(void);
  61. void    print_one(struct faillog *faillog, uid_t uid);
  62. void    reset(void);
  63. int    reset_one(uid_t uid);
  64. void    setmax(void);
  65. void    setmax_one(uid_t uid);
  66. #else
  67. void    print();
  68. void    print_one();
  69. void    reset();
  70. int    reset_one();
  71. void    setmax();
  72. void    setmax_one();
  73. #endif /* __STDC__ */
  74.  
  75. #define    DAY    (24L*3600L)
  76. #define    NOW    (time ((time_t *) 0))
  77.  
  78. void
  79. main (argc, argv)
  80. int    argc;
  81. char    **argv;
  82. {
  83.     char    *mode;
  84.     int    c;
  85.     struct    passwd    *pwent;
  86.  
  87.     if (getuid () == 0)    /* only root can update anything */
  88.         mode = "r+";
  89.     else            /* all others can only look */
  90.         mode = "r";
  91.  
  92.     if ((fail = fopen (FAILFILE, mode)) == (FILE *) 0) {
  93.         perror (FAILFILE);
  94.         exit (1);
  95.     }
  96.     while ((c = getopt (argc, argv, "am:pru:t:")) != EOF) {
  97.         switch (c) {
  98.             case 'a':
  99.                 aflg++;
  100.                 uflg = 0;
  101.                 break;
  102.             case 'm':
  103.                 max = atoi (optarg);
  104.                 setmax ();
  105.                 break;
  106.             case 'p':
  107.                 print ();
  108.                 break;
  109.             case 'r':
  110.                 reset ();
  111.                 break;
  112.             case 'u':
  113.                 pwent = getpwnam (optarg);
  114.                 if (! pwent) {
  115.                     fprintf (stderr, "Unknown User: %s\n", optarg);
  116.                     exit (1);
  117.                 }
  118.                 uflg++;
  119.                 aflg = 0;
  120.                 user = pwent->pw_uid;
  121.                 break;
  122.             case 't':
  123.                 days = atoi (optarg);
  124.                 seconds = days * DAY;
  125.                 tflg++;
  126.                 break;
  127.         }
  128.     }
  129.     fclose (fail);
  130.     exit (0);
  131.     /*NOTREACHED*/
  132. }
  133.  
  134. void
  135. print ()
  136. {
  137.     uid_t    uid;
  138.     off_t    offset;
  139.     struct    faillog    faillog;
  140.  
  141.     if (uflg) {
  142.         offset = user * sizeof faillog;
  143.         fstat (fileno (fail), &statbuf);
  144.         if (offset >= statbuf.st_size)
  145.             return;
  146.  
  147.         fseek (fail, (off_t) user * sizeof faillog, 0);
  148.         if (fread ((char *) &faillog, sizeof faillog, 1, fail) == 1)
  149.             print_one (&faillog, user);
  150.         else
  151.             perror (FAILFILE);
  152.     } else {
  153.         for (uid = 0;
  154.             fread ((char *) &faillog, sizeof faillog, 1, fail) == 1;
  155.                 uid++) {
  156.  
  157.             if (aflg == 0 && faillog.fail_cnt == 0)
  158.                 continue;
  159.  
  160.             if (aflg == 0 && tflg &&
  161.                     NOW - faillog.fail_time > seconds)
  162.                 continue;
  163.  
  164.             if (aflg && faillog.fail_time == 0)
  165.                 continue;
  166.  
  167.             print_one (&faillog, uid);
  168.         }
  169.     }
  170. }
  171.  
  172. void
  173. print_one (faillog, uid)
  174. struct    faillog    *faillog;
  175. uid_t    uid;
  176. {
  177.     static    int    once;
  178.     char    *cp;
  179.     struct    tm    *tm;
  180.     struct    passwd    *pwent;
  181.  
  182.     if (! once) {
  183.         printf ("Username        Failures    Maximum     Latest\n");
  184.         once++;
  185.     }
  186.     pwent = getpwuid (uid);
  187.     tm = localtime (&faillog->fail_time);
  188.     cp = asctime (tm);
  189.     cp[24] = '\0';
  190.  
  191.     if (pwent) {
  192.         printf ("%-16s    %4d       %4d",
  193.             pwent->pw_name, faillog->fail_cnt, faillog->fail_max);
  194.         if (faillog->fail_time)
  195.             printf ("     %s on %s\n", cp, faillog->fail_line);
  196.         else
  197.             putchar ('\n');
  198.     }
  199. }
  200.  
  201. void
  202. reset ()
  203. {
  204.     int    uid = 0;
  205.  
  206.     if (uflg)
  207.         reset_one (user);
  208.     else
  209.         for (uid = 0;reset_one (uid);uid++)
  210.             ;
  211. }
  212.  
  213. int
  214. reset_one (uid)
  215. uid_t    uid;
  216. {
  217.     off_t    offset;
  218.     struct    faillog    faillog;
  219.  
  220.     offset = uid * sizeof faillog;
  221.     fstat (fileno (fail), &statbuf);
  222.     if (offset >= statbuf.st_size)
  223.         return (0);
  224.  
  225.     if (fseek (fail, offset, 0) != 0) {
  226.         perror (FAILFILE);
  227.         return (0);
  228.     }
  229.     if (fread ((char *) &faillog, sizeof faillog, 1, fail) != 1) {
  230.         if (! feof (fail))
  231.             perror (FAILFILE);
  232.  
  233.         return (0);
  234.     }
  235.     if (faillog.fail_cnt == 0)
  236.         return (1);    /* don't fill in no holes ... */
  237.  
  238.     faillog.fail_cnt = 0;
  239.  
  240.     if (fseek (fail, offset, 0) == 0
  241.         && fwrite ((char *) &faillog, sizeof faillog, 1, fail) == 1) {
  242.         fflush (fail);
  243.         return (1);
  244.     } else {
  245.         perror (FAILFILE);
  246.     }
  247.     return (0);
  248. }
  249.  
  250. void
  251. setmax ()
  252. {
  253.     struct    passwd    *pwent;
  254.  
  255.     if (uflg) {
  256.         setmax_one (user);
  257.     } else {
  258.         setpwent ();
  259.         while (pwent = getpwent ())
  260.             setmax_one (pwent->pw_uid);
  261.     }
  262. }
  263.  
  264. void
  265. setmax_one (uid)
  266. uid_t    uid;
  267. {
  268.     off_t    offset;
  269.     struct    faillog    faillog;
  270.  
  271.     offset = uid * sizeof faillog;
  272.  
  273.     if (fseek (fail, offset, 0) != 0) {
  274.         perror (FAILFILE);
  275.         return;
  276.     }
  277.     if (fread ((char *) &faillog, sizeof faillog, 1, fail) != 1) {
  278.         if (! feof (fail))
  279.             perror (FAILFILE);
  280.     } else {
  281. #ifndef    BSD
  282.         memset ((char *) &faillog, 0, sizeof faillog);
  283. #else
  284.         bzero ((char *) &faillog, sizeof faillog);
  285. #endif
  286.     }
  287.     faillog.fail_max = max;
  288.  
  289.     if (fseek (fail, offset, 0) == 0
  290.         && fwrite ((char *) &faillog, sizeof faillog, 1, fail) == 1)
  291.         fflush (fail);
  292.     else
  293.         perror (FAILFILE);
  294. }
  295.