diff mbox series

[4/4] dispol: add --actions option for non-interactive use

Message ID 20230608015241.2454912-4-yamato@redhat.com (mailing list archive)
State Accepted
Commit 666a7dfdc8d4
Headers show
Series [1/4] dispol: add --help option | expand

Commit Message

Masatake YAMATO June 8, 2023, 1:52 a.m. UTC
Example session:

    $ ./dispol --help
    Usage:
     ./dismod [OPTIONS] binary_pol_file

    Options:
     -h, --help              print this help message
     -a, --actions ACTIONS   run non-interactively

    Actions:
      1    display unconditional AVTAB
      2    display conditional AVTAB (entirely)
      3    display conditional AVTAB (only ENABLED rules)
      4    display conditional AVTAB (only DISABLED rules)
      5    display conditional bools
      6    display conditional expressions
      8    display role transitions
      c    display policy capabilities
      b    display booleans
      C    display classes
      r    display roles
      t    display types
      a    display type attributes
      p    display the list of permissive types
      u    display unknown handling setting
      F    display filename_trans rules

    $ ./dispol --actions 1 /etc/selinux/targeted/policy/policy.33  | head
    Reading policy...
    libsepol.policydb_index_others: security:  8 users, 15 roles, 5408 types, 358 bools
    libsepol.policydb_index_others: security: 1 sens, 1024 cats
    libsepol.policydb_index_others: security:  134 classes, 86750 rules, 8818 cond rules
    binary policy file loaded

    allow abrt_dump_oops_t sssd_var_lib_t : sock_file { write getattr append open };
    type_transition authconfig_t entropyd_initrc_exec_t : process initrc_t;
    type_transition glusterd_t syslogd_initrc_exec_t : process initrc_t;xxxx

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
---
 checkpolicy/test/dispol.c | 121 +++++++++++++++++++++++++++-----------
 1 file changed, 86 insertions(+), 35 deletions(-)
diff mbox series

Patch

diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
index e1f6d7fc..bee1a660 100644
--- a/checkpolicy/test/dispol.c
+++ b/checkpolicy/test/dispol.c
@@ -35,13 +35,58 @@ 
 
 static policydb_t policydb;
 
+static struct command {
+	enum {
+		EOL    = 0,
+		HEADER = 1,
+		CMD    = 1 << 1,
+		NOOPT  = 1 << 2,
+	} meta;
+	char cmd;
+	const char *desc;
+} commands[] = {
+	{HEADER, 0, "\nSelect a command:"},
+	{CMD,       '1',  "display unconditional AVTAB" },
+	{CMD,       '2',  "display conditional AVTAB (entirely)"},
+	{CMD,       '3',  "display conditional AVTAB (only ENABLED rules)"},
+	{CMD,       '4',  "display conditional AVTAB (only DISABLED rules)"},
+	{CMD,       '5',  "display conditional bools"},
+	{CMD,       '6',  "display conditional expressions"},
+	{CMD|NOOPT, '7',  "change a boolean value"},
+	{CMD,       '8',  "display role transitions"},
+	{HEADER, 0, ""},
+	{CMD,       'c',  "display policy capabilities"},
+	{CMD,       'b',  "display booleans"},
+	{CMD,       'C',  "display classes"},
+	{CMD,       'r',  "display roles"},
+	{CMD,       't',  "display types"},
+	{CMD,       'a',  "display type attributes"},
+	{CMD,       'p',  "display the list of permissive types"},
+	{CMD,       'u',  "display unknown handling setting"},
+	{CMD,       'F',  "display filename_trans rules"},
+	{HEADER, 0, ""},
+	{CMD|NOOPT, 'f',  "set output file"},
+	{CMD|NOOPT, 'm',  "display menu"},
+	{CMD|NOOPT, 'q',  "quit"},
+	{EOL,   0, "" },
+};
+
 static __attribute__((__noreturn__)) void usage(const char *progname)
 {
 	puts("Usage:");
 	printf(" %s [OPTIONS] binary_pol_file\n\n", progname);
 	puts("Options:");
 	puts(" -h, --help   print this help message");
-	puts("\n");
+	puts(" -a, --actions ACTIONS   run non-interactively");
+	puts("");
+	puts("Actions:");
+	for (unsigned int i = 0; commands[i].meta != EOL; i++) {
+		if (commands[i].meta == HEADER
+		    || commands[i].meta & NOOPT)
+			continue;
+		printf("  %c    %s\n", commands[i].cmd, commands[i].desc);
+	}
+	puts("");
 	exit(1);
 }
 
@@ -447,34 +492,20 @@  static void display_filename_trans(policydb_t *p, FILE *fp)
 
 static int menu(void)
 {
-	printf("\nSelect a command:\n");
-	printf("1)  display unconditional AVTAB\n");
-	printf("2)  display conditional AVTAB (entirely)\n");
-	printf("3)  display conditional AVTAB (only ENABLED rules)\n");
-	printf("4)  display conditional AVTAB (only DISABLED rules)\n");
-	printf("5)  display conditional bools\n");
-	printf("6)  display conditional expressions\n");
-	printf("7)  change a boolean value\n");
-	printf("8)  display role transitions\n");
-	printf("\n");
-	printf("c)  display policy capabilities\n");
-	printf("b)  display booleans\n");
-	printf("C)  display classes\n");
-	printf("r)  display roles\n");
-	printf("t)  display types\n");
-	printf("a)  display type attributes\n");
-	printf("p)  display the list of permissive types\n");
-	printf("u)  display unknown handling setting\n");
-	printf("F)  display filename_trans rules\n");
-	printf("\n");
-	printf("f)  set output file\n");
-	printf("m)  display menu\n");
-	printf("q)  quit\n");
+	unsigned int i;
+	for (i = 0; commands[i].meta != EOL; i++) {
+		if (commands[i].meta == HEADER)
+			printf("%s\n", commands[i].desc);
+		else if (commands[i].meta & CMD)
+			printf("%c) %s\n", commands[i].cmd, commands[i].desc);
+	}
 	return 0;
 }
 
 int main(int argc, char **argv)
 {
+	char *ops = NULL;
+	char *bpol;
 	FILE *out_fp = stdout;
 	char ans[81], OutfileName[121];
 	int fd, ret;
@@ -487,22 +518,35 @@  int main(int argc, char **argv)
 	if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
 		usage(argv[0]);
 
-	fd = open(argv[1], O_RDONLY);
+	bpol = argv[1];
+	if (strcmp (bpol, "--actions") == 0 || strcmp (bpol, "-a") == 0) {
+		if (argc != 4) {
+			fprintf(stderr, "%s: unexpected number of arguments\n", argv[0]);
+			usage(argv[0]);
+		}
+		ops = argv[2];
+		bpol = argv[3];
+	} else if (bpol[0] == '-') {
+		fprintf(stderr, "%s: unknown option: %s\n", argv[0], bpol);
+		usage(argv[0]);
+	}
+
+	fd = open(bpol, O_RDONLY);
 	if (fd < 0) {
 		fprintf(stderr, "Can't open '%s':  %s\n",
-			argv[1], strerror(errno));
+			bpol, strerror(errno));
 		exit(1);
 	}
 	if (fstat(fd, &sb) < 0) {
 		fprintf(stderr, "Can't stat '%s':  %s\n",
-			argv[1], strerror(errno));
+			bpol, strerror(errno));
 		exit(1);
 	}
 	map =
 	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	if (map == MAP_FAILED) {
 		fprintf(stderr, "Can't map '%s':  %s\n",
-			argv[1], strerror(errno));
+			bpol, strerror(errno));
 		exit(1);
 	}
 
@@ -527,15 +571,22 @@  int main(int argc, char **argv)
 	fprintf(stdout, "binary policy file loaded\n\n");
 	close(fd);
 
-	menu();
+	if (!ops)
+		menu();
 	for (;;) {
-		printf("\nCommand (\'m\' for menu):  ");
-		if (fgets(ans, sizeof(ans), stdin) == NULL) {
-			if (feof(stdin))
-				break;
-			fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
+		if (ops) {
+			puts("");
+			ans[0] = *ops? *ops++: 'q';
+			ans[1] = '\0';
+		} else {
+			printf("\nCommand (\'m\' for menu):  ");
+			if (fgets(ans, sizeof(ans), stdin) == NULL) {
+				if (feof(stdin))
+					break;
+				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
 					strerror(errno));
-			continue;
+				continue;
+			}
 		}
 		switch (ans[0]) {