#include #include #include #include #include #include #include #include #include "selinux_internal.h" #include "context_internal.h" static int get_customizable_type_list(char *** retlist) { FILE *fp; char *buf; unsigned int ctr = 0, i; char **list = NULL; fp = fopen(selinux_customizable_types_path(), "re"); if (!fp) return -1; buf = malloc(selinux_page_size); if (!buf) { fclose(fp); return -1; } while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) { ctr++; } rewind(fp); if (ctr) { list = (char **) calloc(sizeof(char *), ctr + 1); if (list) { i = 0; while (fgets_unlocked(buf, selinux_page_size, fp) && i < ctr) { buf[strlen(buf) - 1] = 0; list[i] = (char *) strdup(buf); if (!list[i]) { unsigned int j; for (j = 0; j < i; j++) free(list[j]); free(list); list = NULL; break; } i++; } } } fclose(fp); free(buf); if (!list) return -1; *retlist = list; return 0; } static char **customizable_list = NULL; int is_context_customizable(const char * scontext) { int i; const char *type; context_t c; if (!customizable_list) { if (get_customizable_type_list(&customizable_list) != 0) return -1; } c = context_new(scontext); if (!c) return -1; type = context_type_get(c); if (!type) { context_free(c); return -1; } for (i = 0; customizable_list[i]; i++) { if (strcmp(customizable_list[i], type) == 0) { context_free(c); return 1; } } context_free(c); return 0; }