1 #include <unistd.h> 2 #include <errno.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <ctype.h> 7 #include <pwd.h> 8 #include <limits.h> 9 #include "selinux_internal.h" 10 #include "context_internal.h" 11 12 static char **customizable_list = NULL; 13 static pthread_once_t customizable_once = PTHREAD_ONCE_INIT; 14 customizable_init(void)15static void customizable_init(void) 16 { 17 FILE *fp; 18 char *buf; 19 unsigned int ctr = 0, i; 20 char **list = NULL; 21 22 fp = fopen(selinux_customizable_types_path(), "re"); 23 if (!fp) 24 return; 25 26 buf = malloc(selinux_page_size); 27 if (!buf) { 28 fclose(fp); 29 return; 30 } 31 while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) { 32 ctr++; 33 } 34 rewind(fp); 35 if (ctr) { 36 list = 37 (char **) calloc(sizeof(char *), 38 ctr + 1); 39 if (list) { 40 i = 0; 41 while (fgets_unlocked(buf, selinux_page_size, fp) 42 && i < ctr) { 43 buf[strlen(buf) - 1] = 0; 44 list[i] = strdup(buf); 45 if (!list[i]) { 46 unsigned int j; 47 for (j = 0; j < i; j++) 48 free(list[j]); 49 free(list); 50 list = NULL; 51 break; 52 } 53 i++; 54 } 55 } 56 } 57 fclose(fp); 58 free(buf); 59 if (!list) 60 return; 61 customizable_list = list; 62 } 63 is_context_customizable(const char * scontext)64int is_context_customizable(const char * scontext) 65 { 66 int i; 67 const char *type; 68 context_t c; 69 70 __selinux_once(customizable_once, customizable_init); 71 if (!customizable_list) 72 return -1; 73 74 c = context_new(scontext); 75 if (!c) 76 return -1; 77 78 type = context_type_get(c); 79 if (!type) { 80 context_free(c); 81 return -1; 82 } 83 84 for (i = 0; customizable_list[i]; i++) { 85 if (strcmp(customizable_list[i], type) == 0) { 86 context_free(c); 87 return 1; 88 } 89 } 90 context_free(c); 91 return 0; 92 } 93