Blame utils/matchpathcon.c

Packit Service 10cefc
#include <unistd.h>
Packit Service 10cefc
#include <stdio.h>
Packit Service 10cefc
#include <stdlib.h>
Packit Service 10cefc
#include <getopt.h>
Packit Service 10cefc
#include <errno.h>
Packit Service 10cefc
#include <string.h>
Packit Service 10cefc
#include <limits.h>
Packit Service 10cefc
#include <sys/types.h>
Packit Service 10cefc
#include <sys/stat.h>
Packit Service 10cefc
#include <selinux/selinux.h>
Packit Service 10cefc
#include <limits.h>
Packit Service 10cefc
#include <stdlib.h>
Packit Service 10cefc
Packit Service 10cefc
static __attribute__ ((__noreturn__)) void usage(const char *progname)
Packit Service 10cefc
{
Packit Service 10cefc
	fprintf(stderr,
Packit Service 10cefc
		"usage:  %s [-V] [-N] [-n] [-m type] [-f file_contexts_file] [-p prefix] [-P policy_root_path] filepath...\n",
Packit Service 10cefc
		progname);
Packit Service 10cefc
	exit(1);
Packit Service 10cefc
}
Packit Service 10cefc
Packit Service 10cefc
static int printmatchpathcon(const char *path, int header, int mode)
Packit Service 10cefc
{
Packit Service 10cefc
	char *buf;
Packit Service 10cefc
	int rc = matchpathcon(path, mode, &buf;;
Packit Service 10cefc
	if (rc < 0) {
Packit Service 10cefc
		if (errno == ENOENT) {
Packit Service 10cefc
			buf=strdup("<<none>>");
Packit Service 10cefc
		} else {
Packit Service 10cefc
			fprintf(stderr, "matchpathcon(%s) failed: %s\n", path,
Packit Service 10cefc
				strerror(errno));
Packit Service 10cefc
			return 1;
Packit Service 10cefc
		}
Packit Service 10cefc
	}
Packit Service 10cefc
	if (header)
Packit Service 10cefc
		printf("%s\t%s\n", path, buf);
Packit Service 10cefc
	else
Packit Service 10cefc
		printf("%s\n", buf);
Packit Service 10cefc
Packit Service 10cefc
	freecon(buf);
Packit Service 10cefc
	return 0;
Packit Service 10cefc
}
Packit Service 10cefc
Packit Service 10cefc
static mode_t string_to_mode(char *s)
Packit Service 10cefc
{
Packit Service 10cefc
	switch (s[0]) {
Packit Service 10cefc
	case 'b':
Packit Service 10cefc
		return S_IFBLK;
Packit Service 10cefc
	case 'c':
Packit Service 10cefc
		return S_IFCHR;
Packit Service 10cefc
	case 'd':
Packit Service 10cefc
		return S_IFDIR;
Packit Service 10cefc
	case 'p':
Packit Service 10cefc
		return S_IFIFO;
Packit Service 10cefc
	case 'l':
Packit Service 10cefc
		return S_IFLNK;
Packit Service 10cefc
	case 's':
Packit Service 10cefc
		return S_IFSOCK;
Packit Service 10cefc
	case 'f':
Packit Service 10cefc
		return S_IFREG;
Packit Service 10cefc
	default:
Packit Service 10cefc
		return -1;
Packit Service 10cefc
	};
Packit Service 10cefc
	return -1;
Packit Service 10cefc
}
Packit Service 10cefc
Packit Service 10cefc
int main(int argc, char **argv)
Packit Service 10cefc
{
Packit Service 10cefc
	int i, init = 0, force_mode = 0;
Packit Service 10cefc
	int header = 1, opt;
Packit Service 10cefc
	int verify = 0;
Packit Service 10cefc
	int notrans = 0;
Packit Service 10cefc
	int error = 0;
Packit Service 10cefc
	int quiet = 0;
Packit Service 10cefc
Packit Service 10cefc
	if (argc < 2)
Packit Service 10cefc
		usage(argv[0]);
Packit Service 10cefc
Packit Service 10cefc
	while ((opt = getopt(argc, argv, "m:Nnf:P:p:Vq")) > 0) {
Packit Service 10cefc
		switch (opt) {
Packit Service 10cefc
		case 'n':
Packit Service 10cefc
			header = 0;
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'm':
Packit Service 10cefc
			force_mode = string_to_mode(optarg);
Packit Service 10cefc
			if (force_mode < 0) {
Packit Service 10cefc
				fprintf(stderr, "%s: mode %s is invalid\n", argv[0], optarg);
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'V':
Packit Service 10cefc
			verify = 1;
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'N':
Packit Service 10cefc
			notrans = 1;
Packit Service 10cefc
			set_matchpathcon_flags(MATCHPATHCON_NOTRANS);
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'f':
Packit Service 10cefc
			if (init) {
Packit Service 10cefc
				fprintf(stderr,
Packit Service 10cefc
					"%s:  -f and -p are exclusive\n",
Packit Service 10cefc
					argv[0]);
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			init = 1;
Packit Service 10cefc
			if (matchpathcon_init(optarg)) {
Packit Service 10cefc
				fprintf(stderr,
Packit Service 10cefc
					"Error while processing %s:  %s\n",
Packit Service 10cefc
					optarg,
Packit Service 10cefc
					errno ? strerror(errno) : "invalid");
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'P':
Packit Service 10cefc
			if (selinux_set_policy_root(optarg) < 0 ) {
Packit Service 10cefc
				fprintf(stderr,
Packit Service 10cefc
					"Error setting policy root  %s:  %s\n",
Packit Service 10cefc
					optarg,
Packit Service 10cefc
					errno ? strerror(errno) : "invalid");
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'p':
Packit Service 10cefc
			if (init) {
Packit Service 10cefc
				fprintf(stderr,
Packit Service 10cefc
					"%s:  -f and -p are exclusive\n",
Packit Service 10cefc
					argv[0]);
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			init = 1;
Packit Service 10cefc
			if (matchpathcon_init_prefix(NULL, optarg)) {
Packit Service 10cefc
				fprintf(stderr,
Packit Service 10cefc
					"Error while processing %s:  %s\n",
Packit Service 10cefc
					optarg,
Packit Service 10cefc
					errno ? strerror(errno) : "invalid");
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
			break;
Packit Service 10cefc
		case 'q':
Packit Service 10cefc
			quiet = 1;
Packit Service 10cefc
			break;
Packit Service 10cefc
		default:
Packit Service 10cefc
			usage(argv[0]);
Packit Service 10cefc
		}
Packit Service 10cefc
	}
Packit Service 10cefc
	for (i = optind; i < argc; i++) {
Packit Service 10cefc
		int rc, mode = 0;
Packit Service 10cefc
		struct stat buf;
Packit Service 10cefc
		char *path = argv[i];
Packit Service 10cefc
		int len = strlen(path);
Packit Service 10cefc
		if (len > 1  && path[len - 1 ] == '/')
Packit Service 10cefc
			path[len - 1 ] = '\0';
Packit Service 10cefc
Packit Service 10cefc
		if (lstat(path, &buf) == 0)
Packit Service 10cefc
			mode = buf.st_mode;
Packit Service 10cefc
		if (force_mode)
Packit Service 10cefc
			mode = force_mode;
Packit Service 10cefc
Packit Service 10cefc
		if (verify) {
Packit Service 10cefc
			rc = selinux_file_context_verify(path, mode);
Packit Service 10cefc
Packit Service 10cefc
			if (quiet) {
Packit Service 10cefc
				if (rc == 1)
Packit Service 10cefc
					continue;
Packit Service 10cefc
				else
Packit Service 10cefc
					exit(1);
Packit Service 10cefc
			}
Packit Service 10cefc
Packit Service 10cefc
			if (rc == -1) {
Packit Service 10cefc
				printf("%s error: %s\n", path, strerror(errno));
Packit Service 10cefc
				exit(1);
Packit Service 10cefc
			} else if (rc == 1) {
Packit Service 10cefc
				printf("%s verified.\n", path);
Packit Service 10cefc
			} else {
Packit Service 10cefc
				char * con;
Packit Service 10cefc
				error = 1;
Packit Service 10cefc
				if (notrans)
Packit Service 10cefc
					rc = lgetfilecon_raw(path, &con);
Packit Service 10cefc
				else
Packit Service 10cefc
					rc = lgetfilecon(path, &con);
Packit Service 10cefc
Packit Service 10cefc
				if (rc >= 0) {
Packit Service 10cefc
					printf("%s has context %s, should be ",
Packit Service 10cefc
					       path, con);
Packit Service 10cefc
					printmatchpathcon(path, 0, mode);
Packit Service 10cefc
					freecon(con);
Packit Service 10cefc
				} else {
Packit Service 10cefc
					printf
Packit Service 10cefc
					    ("actual context unknown: %s, should be ",
Packit Service 10cefc
					     strerror(errno));
Packit Service 10cefc
					printmatchpathcon(path, 0, mode);
Packit Service 10cefc
				}
Packit Service 10cefc
			}
Packit Service 10cefc
		} else {
Packit Service 10cefc
			error |= printmatchpathcon(path, header, mode);
Packit Service 10cefc
		}
Packit Service 10cefc
	}
Packit Service 10cefc
	matchpathcon_fini();
Packit Service 10cefc
	return error;
Packit Service 10cefc
}