| #include <unistd.h> |
| #include <errno.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <pwd.h> |
| #include <limits.h> |
| #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(), "r"); |
| 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; |
| } |