platform_external_selinux/libselinux/utils/selabel_lookup.c
Christian Göttsche 0c407c3f1d libselinux/utils: print errno on failure
Print error description on failure after functions known to set errno.

Also mention the library function name in getenforce, policyvers and
setenforce instead of the program name twice.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
2022-05-16 10:31:15 -04:00

129 lines
3.1 KiB
C

#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: %s\n",
strerror(errno));
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;
}