#include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> #include <errno.h> #include <selinux/selinux.h> #include <selinux/label.h> static __attribute__ ((__noreturn__)) void usage(const char *progname) { fprintf(stderr, "usage: %s -b backend [-v] [-r] -k key [-t type] [-f file]\n\n" "Where:\n\t" "-b The backend - \"file\", \"media\", \"x\", \"db\" or " "\"prop\"\n\t" "-v Validate entries against loaded policy.\n\t" "-r Use \"raw\" function.\n\t" "-k Lookup key - Depends on backend.\n\t" "-t Lookup type - Optional as depends on backend.\n\t" "-f Optional file containing the specs (defaults to\n\t" " those used by loaded policy).\n\n" "Examples:\n\t" "%s -v -b file -k /run -t 0\n\t" " lookup with validation against the loaded policy, the\n\t" " \"file\" backend for path \"/run\" with mode = 0\n\t" "%s -r -b x -t 4 -k X11:ButtonPress\n\t" " lookup_raw the \"X\" backend for type SELABEL_X_EVENT\n\t" " using key \"X11:ButtonPress\"\n\n", progname, progname, progname); exit(1); } int main(int argc, char **argv) { int raw = 0, type = 0, backend = 0, rc, opt; char *validate = NULL, *key = NULL, *context = NULL, *file = NULL; struct selabel_handle *hnd; struct selinux_opt selabel_option[] = { { SELABEL_OPT_PATH, file }, { SELABEL_OPT_VALIDATE, validate } }; if (argc < 3) usage(argv[0]); while ((opt = getopt(argc, argv, "b:f:vrk:t:")) > 0) { switch (opt) { case 'b': if (!strcasecmp(optarg, "file")) { backend = SELABEL_CTX_FILE; } else if (!strcmp(optarg, "media")) { backend = SELABEL_CTX_MEDIA; } else if (!strcmp(optarg, "x")) { backend = SELABEL_CTX_X; } else if (!strcmp(optarg, "db")) { backend = SELABEL_CTX_DB; } else if (!strcmp(optarg, "prop")) { backend = SELABEL_CTX_ANDROID_PROP; } else if (!strcmp(optarg, "service")) { backend = SELABEL_CTX_ANDROID_SERVICE; } else { fprintf(stderr, "Unknown backend: %s\n", optarg); usage(argv[0]); } break; case 'f': file = optarg; break; case 'v': validate = (char *)1; break; case 'r': raw = 1; break; case 'k': key = optarg; break; case 't': type = atoi(optarg); break; default: usage(argv[0]); } } selabel_option[0].value = file; selabel_option[1].value = validate; hnd = selabel_open(backend, selabel_option, 2); if (!hnd) { fprintf(stderr, "ERROR: selabel_open - Could not obtain " "handle.\n"); return -1; } switch (raw) { case 1: rc = selabel_lookup_raw(hnd, &context, key, type); break; default: rc = selabel_lookup(hnd, &context, key, type); } selabel_close(hnd); if (rc) { switch (errno) { case ENOENT: fprintf(stderr, "ERROR: selabel_lookup failed to " "find a valid context.\n"); break; case EINVAL: fprintf(stderr, "ERROR: selabel_lookup failed to " "validate context, or key / type are " "invalid.\n"); break; default: fprintf(stderr, "selabel_lookup ERROR: %s\n", strerror(errno)); } } else { printf("Default context: %s\n", context); freecon(context); } return rc; }