1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <getopt.h>
5 #include <errno.h>
6 #include <selinux/selinux.h>
7 #include <selinux/label.h>
8
usage(const char * progname)9 static __attribute__ ((__noreturn__)) void usage(const char *progname)
10 {
11 fprintf(stderr,
12 "usage: %s -b backend [-v] [-r] -k key [-t type] [-f file]\n\n"
13 "Where:\n\t"
14 "-b The backend - \"file\", \"media\", \"x\", \"db\" or "
15 "\"prop\"\n\t"
16 "-v Validate entries against loaded policy.\n\t"
17 "-r Use \"raw\" function.\n\t"
18 "-k Lookup key - Depends on backend.\n\t"
19 "-t Lookup type - Optional as depends on backend.\n\t"
20 "-f Optional file containing the specs (defaults to\n\t"
21 " those used by loaded policy).\n\n"
22 "Examples:\n\t"
23 "%s -v -b file -k /run -t 0\n\t"
24 " lookup with validation against the loaded policy, the\n\t"
25 " \"file\" backend for path \"/run\" with mode = 0\n\t"
26 "%s -r -b x -t 4 -k X11:ButtonPress\n\t"
27 " lookup_raw the \"X\" backend for type SELABEL_X_EVENT\n\t"
28 " using key \"X11:ButtonPress\"\n\n",
29 progname, progname, progname);
30 exit(1);
31 }
32
main(int argc,char ** argv)33 int main(int argc, char **argv)
34 {
35 int raw = 0, type = 0, rc, opt;
36 unsigned int backend = SELABEL_CTX_FILE;
37 char *validate = NULL, *key = NULL, *context = NULL, *file = NULL;
38
39 struct selabel_handle *hnd;
40 struct selinux_opt selabel_option[] = {
41 { SELABEL_OPT_PATH, file },
42 { SELABEL_OPT_VALIDATE, validate }
43 };
44
45 if (argc < 3)
46 usage(argv[0]);
47
48 while ((opt = getopt(argc, argv, "b:f:vrk:t:")) > 0) {
49 switch (opt) {
50 case 'b':
51 if (!strcasecmp(optarg, "file")) {
52 backend = SELABEL_CTX_FILE;
53 } else if (!strcmp(optarg, "media")) {
54 backend = SELABEL_CTX_MEDIA;
55 } else if (!strcmp(optarg, "x")) {
56 backend = SELABEL_CTX_X;
57 } else if (!strcmp(optarg, "db")) {
58 backend = SELABEL_CTX_DB;
59 } else if (!strcmp(optarg, "prop")) {
60 backend = SELABEL_CTX_ANDROID_PROP;
61 } else if (!strcmp(optarg, "service")) {
62 backend = SELABEL_CTX_ANDROID_SERVICE;
63 } else if (!strcmp(optarg, "keystore2_key")) {
64 backend = SELABEL_CTX_ANDROID_KEYSTORE2_KEY;
65 } else {
66 fprintf(stderr, "Unknown backend: %s\n",
67 optarg);
68 usage(argv[0]);
69 }
70 break;
71 case 'f':
72 file = optarg;
73 break;
74 case 'v':
75 validate = (char *)1;
76 break;
77 case 'r':
78 raw = 1;
79 break;
80 case 'k':
81 key = optarg;
82 break;
83 case 't':
84 type = atoi(optarg);
85 break;
86 default:
87 usage(argv[0]);
88 }
89 }
90
91 selabel_option[0].value = file;
92 selabel_option[1].value = validate;
93
94 hnd = selabel_open(backend, selabel_option, 2);
95 if (!hnd) {
96 fprintf(stderr, "ERROR: selabel_open - Could not obtain "
97 "handle: %s\n",
98 strerror(errno));
99 return -1;
100 }
101
102 switch (raw) {
103 case 1:
104 rc = selabel_lookup_raw(hnd, &context, key, type);
105 break;
106 default:
107 rc = selabel_lookup(hnd, &context, key, type);
108 }
109 selabel_close(hnd);
110
111 if (rc) {
112 switch (errno) {
113 case ENOENT:
114 fprintf(stderr, "ERROR: selabel_lookup failed to "
115 "find a valid context.\n");
116 break;
117 case EINVAL:
118 fprintf(stderr, "ERROR: selabel_lookup failed to "
119 "validate context, or key / type are "
120 "invalid.\n");
121 break;
122 default:
123 fprintf(stderr, "selabel_lookup ERROR: %s\n",
124 strerror(errno));
125 }
126 } else {
127 printf("Default context: %s\n", context);
128 freecon(context);
129 }
130
131 return rc;
132 }
133