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 >
Wrap
C/C++ Source or Header
|
1992-03-10
|
6KB
|
256 lines
/*
* filecheck - check ownership/permissions of a set of files
*
* A list of file specifications is read, one specification per line, and
* check given by the specification is performed. If the check fails, a
* message is printed to stdout. If no failures occur, this program
* terminates with a zero exit status, otherwize nonzero if any checks failed.
*
* A specification is in the following format:
*
* pathname [!]key-list uid-list gid-list perms
*
* pathname Full pathname of the file to check.
*
* key-list A list of keys, seperated by colons, to which this spec
* applies. The key is specified by the "-k" command line
* options, or "all" if none given. If the given key is
* contained in the key-list, then this spec is checked. If the
* given key does not match then this specification is ignored.
*
* For example, if the specification contains a key-list of
* "xenix:usg" and we run "filecheck -k xenix", then the spec
* will be checked. If we run "filecheck -k sun" then the spec
* will be ignored.
*
* If the given key is "all" (or none is specified since this is
* the default), then all specifications are checked. If the
* key-list for a specification contains "all", then it will be
* checked regardless of the key given on the command line.
*
* If a "!" appears at the front of the key-list, then a
* complaint will be issued if the file specified by "pathname"
* does not exist. Otherwise, if the file does not exist the
* specification is ignored.
*
* uid-list A colon delimited list of user names. If the file is not
* owned by a user in this list, then a complaint is generated.
* If the value of this field is "-" then the user ownership
* check is suppressed.
*
* gid-list A colon delimited list of group names. If the file is not
* owned by a group in this list, then a complaint is generated.
* If the value of this field is "-" then the group ownership
* check is suppressed.
*
* perms A maximum set of permissions which this file should have.
* For example, if the specification says "755" and the
* file is actually "555" then it is OK. However, if the
* file is actually "775" then a complaint will be issued
* because the group write privilge is enabled. If the value
* of this field is "-" then the permissions check is suppressed.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#define USAGE "usage: [-k key] [file]\n"
#define TRUE 1
#define FALSE 0
int check_key();
int check_uid();
int check_gid();
int check_perms();
extern struct passwd *getpwnam(), *getpwuid();
extern struct group *getgrnam(), *getgrgid();
long strtol();
main(argc, argv)
int argc;
char *argv[];
{
char *f_pathname, *f_key, *f_uname, *f_gname, *f_perms;
char buf[512], *selkey;
int must_exist, status, lineno, i;
struct stat sbuf;
extern int optind;
extern char *optarg;
selkey = "all";
while ((i = getopt(argc, argv, "k:")) != EOF) {
switch (i) {
case 'k':
selkey = optarg;
break;
default:
fprintf(stderr, USAGE, argv[0]);
exit(1);
}
}
switch (argc-optind) {
case 0:
break;
case 1:
if (freopen(argv[optind], "r", stdin) == NULL) {
perror(argv[optind]);
exit(1);
}
break;
default:
fprintf(stderr, USAGE, argv[0]);
exit(1);
}
lineno = 0;
status = 0;
while (++lineno, fgets(buf, sizeof(buf), stdin) != NULL) {
/*
* Break up the line. Skip comments and blank lines.
*/
if ((f_pathname = strtok(buf, " \t\n")) == NULL || *f_pathname == '#' )
continue;
if (
(f_key = strtok((char *)NULL, " \t\n")) == NULL ||
(f_uname = strtok((char *)NULL, " \t\n")) == NULL ||
(f_gname = strtok((char *)NULL, " \t\n")) == NULL ||
(f_perms = strtok((char *)NULL, " \t\n")) == NULL ||
strtok((char *)NULL, " \t\n") != NULL
) {
printf("%s(%d): bad line ignored\n", f_pathname, lineno);
status = 1;
continue;
}
/*
* See if we want to insist that this file exists.
*/
must_exist = (*f_key == '!');
if (must_exist)
++f_key;
/*
* See if we want to do this entry.
*/
if (!check_key(selkey, f_key))
continue;
/*
* Get info on this file.
*/
if (stat(f_pathname, &sbuf) != 0) {
if (must_exist) {
fprintf(stderr, "%s: could not access file\n", f_pathname);
status = 1;
}
continue;
}
/*
* Perform checks.
*/
if (!check_uid(f_pathname, f_uname, &sbuf))
status = 1;
if (!check_gid(f_pathname, f_gname, &sbuf))
status = 1;
if (!check_perms(f_pathname, f_perms, &sbuf))
status = 1;
}
exit(status);
/*NOTREACHED*/
}
int check_key(key, klist)
char *key, *klist;
{
char *k;
if (key == NULL || klist == NULL || strcmp("all", key) == 0)
return TRUE;
while ((k = strtok(klist, ": \t\n")) != NULL) {
if (strcmp(k, key) == 0 || strcmp(k, "all") == 0)
return TRUE;
klist = NULL;
}
return FALSE;
}
int check_uid(fname, ulist, s)
char *fname;
char *ulist;
struct stat *s;
{
struct passwd *pw;
char buf[256];
char *up, *u;
if (strcmp(ulist, "-") == 0)
return TRUE;
up = strcpy(buf, ulist);
while ((u = strtok(up, ": \t\n")) != NULL) {
if ((pw = getpwnam(u)) != NULL && s->st_uid == pw->pw_uid)
return TRUE;
up = NULL;
}
pw = getpwuid(s->st_uid);
printf("%s: uid is %s(%d), expected %s\n",
fname, (pw == NULL ? "<unknown>" : pw->pw_name), s->st_uid, ulist);
return FALSE;
}
int check_gid(fname, glist, s)
char *fname;
char *glist;
struct stat *s;
{
struct group *gr;
char buf[256];
char *gp, *g;
if (strcmp(glist, "-") == 0)
return TRUE;
gp = strcpy(buf, glist);
while ((g = strtok(gp, ": \t\n")) != NULL) {
if ((gr = getgrnam(g)) != NULL && s->st_gid == gr->gr_gid)
return TRUE;
gp = NULL;
}
gr = getgrgid(s->st_gid);
printf("%s: gid is %s(%d), expected %s\n",
fname, (gr == NULL ? "<unknown>" : gr->gr_name), s->st_gid, glist);
return FALSE;
}
int check_perms(fname, perms, s)
char *fname;
char *perms;
struct stat *s;
{
int perms_want, perms_act;
if (strcmp(perms, "-") == 0)
return TRUE;
perms_want = (int) strtol(perms, (char *)NULL, 8);
perms_act = s->st_mode & 07777;
if ((perms_act & perms_want) == perms_act)
return TRUE;
printf("%s: permissions are %04o, should be at least %04o\n",
fname, perms_act, perms_want);
return FALSE;
}