home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / extra_src / uucp_1.shar / filecheck.c next >
C/C++ Source or Header  |  1992-03-10  |  6KB  |  256 lines

  1. /*
  2.  * filecheck - check ownership/permissions of a set of files
  3.  *
  4.  * A list of file specifications is read, one specification per line, and
  5.  * check given by the specification is performed.  If the check fails, a
  6.  * message is printed to stdout.  If no failures occur, this program
  7.  * terminates with a zero exit status, otherwize nonzero if any checks failed.
  8.  *
  9.  * A specification is in the following format:
  10.  *
  11.  *        pathname    [!]key-list    uid-list    gid-list    perms
  12.  *
  13.  * pathname        Full pathname of the file to check.
  14.  *
  15.  * key-list        A list of keys, seperated by colons, to which this spec
  16.  *                applies.  The key is specified by the "-k" command line
  17.  *                options, or "all" if none given.  If the given key is
  18.  *                contained in the key-list, then this spec is checked.  If the
  19.  *                given key does not match then this specification is ignored.
  20.  *
  21.  *                For example, if the specification contains a key-list of
  22.  *                "xenix:usg" and we run "filecheck -k xenix", then the spec
  23.  *                will be checked.  If we run "filecheck -k sun" then the spec
  24.  *                will be ignored.
  25.  *
  26.  *                If the given key is "all" (or none is specified since this is
  27.  *                the default), then all specifications are checked.  If the
  28.  *                key-list for a specification contains "all", then it will be
  29.  *                checked regardless of the key given on the command line.
  30.  *
  31.  *                If a "!" appears at the front of the key-list, then a
  32.  *                complaint will be issued if the file specified by "pathname"
  33.  *                does not exist.  Otherwise, if the file does not exist the
  34.  *                specification is ignored.
  35.  *
  36.  * uid-list        A colon delimited list of user names.  If the file is not
  37.  *                owned by a user in this list, then a complaint is generated.
  38.  *                If the value of this field is "-" then the user ownership
  39.  *                check is suppressed.
  40.  *
  41.  * gid-list        A colon delimited list of group names.  If the file is not
  42.  *                owned by a group in this list, then a complaint is generated.
  43.  *                If the value of this field is "-" then the group ownership
  44.  *                check is suppressed.
  45.  *
  46.  * perms        A maximum set of permissions which this file should have.
  47.  *                For example, if the specification says "755" and the
  48.  *                file is actually "555" then it is OK.  However, if the
  49.  *                file is actually "775" then a complaint will be issued
  50.  *                because the group write privilge is enabled.  If the value
  51.  *                of this field is "-" then the permissions check is suppressed.
  52.  */
  53.  
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <sys/types.h>
  57. #include <sys/stat.h>
  58. #include <pwd.h>
  59. #include <grp.h>
  60.  
  61. #define USAGE    "usage: [-k key] [file]\n"
  62.  
  63. #define TRUE    1
  64. #define FALSE    0
  65.  
  66. int check_key();
  67. int check_uid();
  68. int check_gid();
  69. int check_perms();
  70.  
  71. extern struct passwd *getpwnam(), *getpwuid();
  72. extern struct group *getgrnam(), *getgrgid();
  73. long strtol();
  74.  
  75. main(argc, argv)
  76. int argc;
  77. char *argv[];
  78. {
  79.     char *f_pathname, *f_key, *f_uname, *f_gname, *f_perms;
  80.     char buf[512], *selkey;
  81.     int must_exist, status, lineno, i;
  82.     struct stat sbuf;
  83.     extern int optind;
  84.     extern char *optarg;
  85.  
  86.     selkey = "all";
  87.     while ((i = getopt(argc, argv, "k:")) != EOF) {
  88.         switch (i) {
  89.         case 'k':
  90.             selkey = optarg;
  91.             break;
  92.         default:
  93.             fprintf(stderr, USAGE, argv[0]);
  94.             exit(1);
  95.         }
  96.     }
  97.  
  98.     switch (argc-optind) {
  99.     case 0:
  100.         break;
  101.     case 1:
  102.         if (freopen(argv[optind], "r", stdin) == NULL) {
  103.             perror(argv[optind]);
  104.             exit(1);
  105.         }
  106.         break;
  107.     default:
  108.         fprintf(stderr, USAGE, argv[0]);
  109.         exit(1);
  110.     }
  111.  
  112.     lineno = 0;
  113.     status = 0;
  114.     while (++lineno, fgets(buf, sizeof(buf), stdin) != NULL) {
  115.  
  116.         /*
  117.          * Break up the line.  Skip comments and blank lines.
  118.          */
  119.         if ((f_pathname = strtok(buf, " \t\n")) == NULL || *f_pathname == '#' )
  120.             continue;
  121.         if (
  122.             (f_key = strtok((char *)NULL, " \t\n")) == NULL ||
  123.             (f_uname = strtok((char *)NULL, " \t\n")) == NULL ||
  124.             (f_gname = strtok((char *)NULL, " \t\n")) == NULL ||
  125.             (f_perms = strtok((char *)NULL, " \t\n")) == NULL ||
  126.             strtok((char *)NULL, " \t\n") != NULL
  127.         ) {
  128.             printf("%s(%d): bad line ignored\n", f_pathname, lineno);
  129.             status = 1;
  130.             continue;
  131.         }
  132.  
  133.         /*
  134.          * See if we want to insist that this file exists.
  135.          */
  136.         must_exist = (*f_key == '!');
  137.         if (must_exist)
  138.             ++f_key;
  139.  
  140.         /*
  141.          * See if we want to do this entry.
  142.          */
  143.         if (!check_key(selkey, f_key))
  144.             continue;
  145.  
  146.         /*
  147.          * Get info on this file.
  148.          */
  149.         if (stat(f_pathname, &sbuf) != 0) {
  150.             if (must_exist) {
  151.                 fprintf(stderr, "%s: could not access file\n", f_pathname);
  152.                 status = 1;
  153.             }
  154.             continue;
  155.         }
  156.  
  157.         /*
  158.          * Perform checks.
  159.          */
  160.         if (!check_uid(f_pathname, f_uname, &sbuf))
  161.             status = 1;
  162.         if (!check_gid(f_pathname, f_gname, &sbuf))
  163.             status = 1;
  164.         if (!check_perms(f_pathname, f_perms, &sbuf))
  165.             status = 1;
  166.  
  167.     }
  168.  
  169.     exit(status);
  170.     /*NOTREACHED*/
  171. }
  172.  
  173.  
  174. int check_key(key, klist)
  175. char *key, *klist;
  176. {
  177.     char *k;
  178.     if (key == NULL || klist == NULL || strcmp("all", key) == 0)
  179.         return TRUE;
  180.     while ((k = strtok(klist, ": \t\n")) != NULL) {
  181.         if (strcmp(k, key) == 0 || strcmp(k, "all") == 0)
  182.             return TRUE;
  183.         klist = NULL;
  184.     }
  185.     return FALSE;
  186. }
  187.  
  188.  
  189. int check_uid(fname, ulist, s)
  190. char *fname;
  191. char *ulist;
  192. struct stat *s;
  193. {
  194.     struct passwd *pw;
  195.     char buf[256];
  196.     char *up, *u;
  197.  
  198.     if (strcmp(ulist, "-") == 0)
  199.         return TRUE;
  200.     up = strcpy(buf, ulist);
  201.     while ((u = strtok(up, ": \t\n")) != NULL) {
  202.         if ((pw = getpwnam(u)) != NULL && s->st_uid == pw->pw_uid)
  203.             return TRUE;
  204.         up = NULL;
  205.     }
  206.     pw = getpwuid(s->st_uid);
  207.     printf("%s: uid is %s(%d), expected %s\n",
  208.         fname, (pw == NULL ? "<unknown>" : pw->pw_name), s->st_uid, ulist);
  209.     return FALSE;
  210. }
  211.  
  212.  
  213. int check_gid(fname, glist, s)
  214. char *fname;
  215. char *glist;
  216. struct stat *s;
  217. {
  218.     struct group *gr;
  219.     char buf[256];
  220.     char *gp, *g;
  221.  
  222.     if (strcmp(glist, "-") == 0)
  223.         return TRUE;
  224.     gp = strcpy(buf, glist);
  225.     while ((g = strtok(gp, ": \t\n")) != NULL) {
  226.         if ((gr = getgrnam(g)) != NULL && s->st_gid == gr->gr_gid)
  227.             return TRUE;
  228.         gp = NULL;
  229.     }
  230.     gr = getgrgid(s->st_gid);
  231.     printf("%s: gid is %s(%d), expected %s\n",
  232.         fname, (gr == NULL ? "<unknown>" : gr->gr_name), s->st_gid, glist);
  233.     return FALSE;
  234. }
  235.  
  236.  
  237. int check_perms(fname, perms, s)
  238. char *fname;
  239. char *perms;
  240. struct stat *s;
  241. {
  242.     int perms_want, perms_act;
  243.  
  244.     if (strcmp(perms, "-") == 0)
  245.         return TRUE;
  246.     perms_want = (int) strtol(perms, (char *)NULL, 8);
  247.     perms_act = s->st_mode & 07777;
  248.     if ((perms_act & perms_want) == perms_act)
  249.         return TRUE;
  250.  
  251.     printf("%s: permissions are %04o, should be at least %04o\n",
  252.         fname, perms_act, perms_want);
  253.     return FALSE;
  254. }
  255.  
  256.