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 
get_customizable_type_list(char *** retlist)12 static int get_customizable_type_list(char *** retlist)
13 {
14 	FILE *fp;
15 	char *buf;
16 	unsigned int ctr = 0, i;
17 	char **list = NULL;
18 
19 	fp = fopen(selinux_customizable_types_path(), "r");
20 	if (!fp)
21 		return -1;
22 
23 	buf = malloc(selinux_page_size);
24 	if (!buf) {
25 		fclose(fp);
26 		return -1;
27 	}
28 	while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) {
29 		ctr++;
30 	}
31 	rewind(fp);
32 	if (ctr) {
33 		list =
34 		    (char **) calloc(sizeof(char *),
35 						  ctr + 1);
36 		if (list) {
37 			i = 0;
38 			while (fgets_unlocked(buf, selinux_page_size, fp)
39 			       && i < ctr) {
40 				buf[strlen(buf) - 1] = 0;
41 				list[i] = (char *) strdup(buf);
42 				if (!list[i]) {
43 					unsigned int j;
44 					for (j = 0; j < i; j++)
45 						free(list[j]);
46 					free(list);
47 					list = NULL;
48 					break;
49 				}
50 				i++;
51 			}
52 		}
53 	}
54 	fclose(fp);
55 	free(buf);
56 	if (!list)
57 		return -1;
58 	*retlist = list;
59 	return 0;
60 }
61 
62 static char **customizable_list = NULL;
63 
is_context_customizable(const char * scontext)64 int is_context_customizable(const char * scontext)
65 {
66 	int i;
67 	const char *type;
68 	context_t c;
69 
70 	if (!customizable_list) {
71 		if (get_customizable_type_list(&customizable_list) != 0)
72 			return -1;
73 	}
74 
75 	c = context_new(scontext);
76 	if (!c)
77 		return -1;
78 
79 	type = context_type_get(c);
80 	if (!type) {
81 		context_free(c);
82 		return -1;
83 	}
84 
85 	for (i = 0; customizable_list[i]; i++) {
86 		if (strcmp(customizable_list[i], type) == 0) {
87 			context_free(c);
88 			return 1;
89 		}
90 	}
91 	context_free(c);
92 	return 0;
93 }
94