xref: /aosp_15_r20/external/selinux/libselinux/utils/getconlist.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
3*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
5*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
6*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
7*2d543d20SAndroid Build Coastguard Worker #include <string.h>
8*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
9*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
10*2d543d20SAndroid Build Coastguard Worker #include <selinux/get_context_list.h>
11*2d543d20SAndroid Build Coastguard Worker 
usage(const char * name,const char * detail,int rc)12*2d543d20SAndroid Build Coastguard Worker static __attribute__ ((__noreturn__)) void usage(const char *name, const char *detail, int rc)
13*2d543d20SAndroid Build Coastguard Worker {
14*2d543d20SAndroid Build Coastguard Worker 	fprintf(stderr, "usage:  %s [-l level] user [context]\n", name);
15*2d543d20SAndroid Build Coastguard Worker 	if (detail)
16*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  %s\n", name, detail);
17*2d543d20SAndroid Build Coastguard Worker 	exit(rc);
18*2d543d20SAndroid Build Coastguard Worker }
19*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)20*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
21*2d543d20SAndroid Build Coastguard Worker {
22*2d543d20SAndroid Build Coastguard Worker 	char **list;
23*2d543d20SAndroid Build Coastguard Worker 	const char *cur_context, *user;
24*2d543d20SAndroid Build Coastguard Worker 	char *cur_con = NULL, *level = NULL;
25*2d543d20SAndroid Build Coastguard Worker 	int ret, i, opt;
26*2d543d20SAndroid Build Coastguard Worker 
27*2d543d20SAndroid Build Coastguard Worker 	while ((opt = getopt(argc, argv, "l:")) > 0) {
28*2d543d20SAndroid Build Coastguard Worker 		switch (opt) {
29*2d543d20SAndroid Build Coastguard Worker 		case 'l':
30*2d543d20SAndroid Build Coastguard Worker 			free(level);
31*2d543d20SAndroid Build Coastguard Worker 			level = strdup(optarg);
32*2d543d20SAndroid Build Coastguard Worker 			if (!level) {
33*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "memory allocation failure: %d(%s)\n",
34*2d543d20SAndroid Build Coastguard Worker 					errno, strerror(errno));
35*2d543d20SAndroid Build Coastguard Worker 				return 3;
36*2d543d20SAndroid Build Coastguard Worker 			}
37*2d543d20SAndroid Build Coastguard Worker 			break;
38*2d543d20SAndroid Build Coastguard Worker 		default:
39*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0], "invalid option", 1);
40*2d543d20SAndroid Build Coastguard Worker 		}
41*2d543d20SAndroid Build Coastguard Worker 	}
42*2d543d20SAndroid Build Coastguard Worker 
43*2d543d20SAndroid Build Coastguard Worker 	if (((argc - optind) < 1) || ((argc - optind) > 2))
44*2d543d20SAndroid Build Coastguard Worker 		usage(argv[0], "invalid number of arguments", 2);
45*2d543d20SAndroid Build Coastguard Worker 
46*2d543d20SAndroid Build Coastguard Worker 	/* If selinux isn't available, bail out. */
47*2d543d20SAndroid Build Coastguard Worker 	if (!is_selinux_enabled()) {
48*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
49*2d543d20SAndroid Build Coastguard Worker 			"getconlist may be used only on a SELinux kernel.\n");
50*2d543d20SAndroid Build Coastguard Worker 		free(level);
51*2d543d20SAndroid Build Coastguard Worker 		return 1;
52*2d543d20SAndroid Build Coastguard Worker 	}
53*2d543d20SAndroid Build Coastguard Worker 
54*2d543d20SAndroid Build Coastguard Worker 	user = argv[optind];
55*2d543d20SAndroid Build Coastguard Worker 
56*2d543d20SAndroid Build Coastguard Worker 	/* If a context wasn't passed, use the current context. */
57*2d543d20SAndroid Build Coastguard Worker 	if (((argc - optind) < 2)) {
58*2d543d20SAndroid Build Coastguard Worker 		if (getcon(&cur_con) < 0) {
59*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Couldn't get current context:  %s\n", strerror(errno));
60*2d543d20SAndroid Build Coastguard Worker 			free(level);
61*2d543d20SAndroid Build Coastguard Worker 			return 2;
62*2d543d20SAndroid Build Coastguard Worker 		}
63*2d543d20SAndroid Build Coastguard Worker 		cur_context = cur_con;
64*2d543d20SAndroid Build Coastguard Worker 	} else {
65*2d543d20SAndroid Build Coastguard Worker 		cur_context = argv[optind + 1];
66*2d543d20SAndroid Build Coastguard Worker 		if (security_check_context(cur_context) != 0) {
67*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Given context '%s' is invalid.\n", cur_context);
68*2d543d20SAndroid Build Coastguard Worker 			free(level);
69*2d543d20SAndroid Build Coastguard Worker 			return 3;
70*2d543d20SAndroid Build Coastguard Worker 		}
71*2d543d20SAndroid Build Coastguard Worker 	}
72*2d543d20SAndroid Build Coastguard Worker 
73*2d543d20SAndroid Build Coastguard Worker 	/* Get the list and print it */
74*2d543d20SAndroid Build Coastguard Worker 	if (level)
75*2d543d20SAndroid Build Coastguard Worker 		ret =
76*2d543d20SAndroid Build Coastguard Worker 		    get_ordered_context_list_with_level(user, level,
77*2d543d20SAndroid Build Coastguard Worker 							cur_context, &list);
78*2d543d20SAndroid Build Coastguard Worker 	else
79*2d543d20SAndroid Build Coastguard Worker 		ret = get_ordered_context_list(user, cur_context, &list);
80*2d543d20SAndroid Build Coastguard Worker 	if (ret != -1) {
81*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; list[i]; i++)
82*2d543d20SAndroid Build Coastguard Worker 			puts(list[i]);
83*2d543d20SAndroid Build Coastguard Worker 		freeconary(list);
84*2d543d20SAndroid Build Coastguard Worker 	} else {
85*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "get_ordered_context_list%s failure: %d(%s)\n",
86*2d543d20SAndroid Build Coastguard Worker 			level ? "_with_level" : "", errno, strerror(errno));
87*2d543d20SAndroid Build Coastguard Worker 		free(cur_con);
88*2d543d20SAndroid Build Coastguard Worker 		free(level);
89*2d543d20SAndroid Build Coastguard Worker 		return 4;
90*2d543d20SAndroid Build Coastguard Worker 	}
91*2d543d20SAndroid Build Coastguard Worker 
92*2d543d20SAndroid Build Coastguard Worker 	free(cur_con);
93*2d543d20SAndroid Build Coastguard Worker 	free(level);
94*2d543d20SAndroid Build Coastguard Worker 
95*2d543d20SAndroid Build Coastguard Worker 	return 0;
96*2d543d20SAndroid Build Coastguard Worker }
97