1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 struct semanage_fcontext;
4 struct semanage_fcontext_key;
5 typedef struct semanage_fcontext record_t;
6 typedef struct semanage_fcontext_key record_key_t;
7 #define DBASE_RECORD_DEFINED
8 
9 struct dbase_file;
10 typedef struct dbase_file dbase_t;
11 #define DBASE_DEFINED
12 
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <strings.h>
16 #include <semanage/handle.h>
17 #include "fcontext_internal.h"
18 #include "context_internal.h"
19 #include "database_file.h"
20 #include "parse_utils.h"
21 #include "debug.h"
22 
type_str(int type)23 static const char *type_str(int type)
24 {
25 	switch (type) {
26 	default:
27 	case SEMANAGE_FCONTEXT_ALL:
28 		return "  ";
29 	case SEMANAGE_FCONTEXT_REG:
30 		return "--";
31 	case SEMANAGE_FCONTEXT_DIR:
32 		return "-d";
33 	case SEMANAGE_FCONTEXT_CHAR:
34 		return "-c";
35 	case SEMANAGE_FCONTEXT_BLOCK:
36 		return "-b";
37 	case SEMANAGE_FCONTEXT_SOCK:
38 		return "-s";
39 	case SEMANAGE_FCONTEXT_LINK:
40 		return "-l";
41 	case SEMANAGE_FCONTEXT_PIPE:
42 		return "-p";
43 	}
44 }
45 
fcontext_print(semanage_handle_t * handle,semanage_fcontext_t * fcontext,FILE * str)46 static int fcontext_print(semanage_handle_t * handle,
47 			  semanage_fcontext_t * fcontext, FILE * str)
48 {
49 
50 	char *con_str = NULL;
51 
52 	const char *expr = semanage_fcontext_get_expr(fcontext);
53 	int type = semanage_fcontext_get_type(fcontext);
54 	const char *print_str = type_str(type);
55 	const char *tstr = semanage_fcontext_get_type_str(type);
56 	semanage_context_t *con = semanage_fcontext_get_con(fcontext);
57 
58 	if (fprintf(str, "%s %s ", expr, print_str) < 0)
59 		goto err;
60 
61 	if (con != NULL) {
62 		if (semanage_context_to_string(handle, con, &con_str) < 0)
63 			goto err;
64 		if (fprintf(str, "%s\n", con_str) < 0)
65 			goto err;
66 		free(con_str);
67 		con_str = NULL;
68 	} else {
69 		if (fprintf(str, "<<none>>\n") < 0)
70 			goto err;
71 	}
72 	return STATUS_SUCCESS;
73 
74       err:
75 	ERR(handle, "could not print file context for "
76 	    "%s (%s) to stream", expr, tstr);
77 	free(con_str);
78 	return STATUS_ERR;
79 }
80 
fcontext_parse(semanage_handle_t * handle,parse_info_t * info,semanage_fcontext_t * fcontext)81 static int fcontext_parse(semanage_handle_t * handle,
82 			  parse_info_t * info, semanage_fcontext_t * fcontext)
83 {
84 
85 	char *str = NULL;
86 	semanage_context_t *con = NULL;
87 
88 	if (parse_skip_space(handle, info) < 0)
89 		goto err;
90 	if (!info->ptr)
91 		goto last;
92 
93 	/* Regexp */
94 	if (parse_fetch_string(handle, info, &str, ' ') < 0)
95 		goto err;
96 	if (semanage_fcontext_set_expr(handle, fcontext, str) < 0)
97 		goto err;
98 	free(str);
99 	str = NULL;
100 
101 	/* Type */
102 	if (parse_assert_space(handle, info) < 0)
103 		goto err;
104 	if (parse_fetch_string(handle, info, &str, ' ') < 0)
105 		goto err;
106 	if (!strcasecmp(str, "-s"))
107 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_SOCK);
108 	else if (!strcasecmp(str, "-p"))
109 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_PIPE);
110 	else if (!strcasecmp(str, "-b"))
111 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_BLOCK);
112 	else if (!strcasecmp(str, "-l"))
113 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_LINK);
114 	else if (!strcasecmp(str, "-c"))
115 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_CHAR);
116 	else if (!strcasecmp(str, "-d"))
117 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_DIR);
118 	else if (!strcasecmp(str, "--"))
119 		semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_REG);
120 	else
121 		goto process_context;
122 	free(str);
123 	str = NULL;
124 
125 	/* Context */
126 	if (parse_assert_space(handle, info) < 0)
127 		goto err;
128 	if (parse_fetch_string(handle, info, &str, ' ') < 0)
129 		goto err;
130 
131       process_context:
132 	if (semanage_context_from_string(handle, str, &con) < 0) {
133 		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
134 		    str, info->filename, info->lineno, info->orig_line);
135 		goto err;
136 	}
137 	free(str);
138 	str = NULL;
139 
140 	if (con && semanage_fcontext_set_con(handle, fcontext, con) < 0)
141 		goto err;
142 
143 	if (parse_assert_space(handle, info) < 0)
144 		goto err;
145 
146 	semanage_context_free(con);
147 	return STATUS_SUCCESS;
148 
149       last:
150 	parse_dispose_line(info);
151 	return STATUS_NODATA;
152 
153       err:
154 	ERR(handle, "could not parse file context record");
155 	free(str);
156 	semanage_context_free(con);
157 	parse_dispose_line(info);
158 	return STATUS_ERR;
159 }
160 
161 /* FCONTEXT RECORD: FILE extension: method table */
162 record_file_table_t SEMANAGE_FCONTEXT_FILE_RTABLE = {
163 	.parse = fcontext_parse,
164 	.print = fcontext_print,
165 };
166 
fcontext_file_dbase_init(semanage_handle_t * handle,const char * path_ro,const char * path_rw,dbase_config_t * dconfig)167 int fcontext_file_dbase_init(semanage_handle_t * handle,
168 			     const char *path_ro,
169 			     const char *path_rw,
170 			     dbase_config_t * dconfig)
171 {
172 
173 	if (dbase_file_init(handle,
174 			    path_ro,
175 			    path_rw,
176 			    &SEMANAGE_FCONTEXT_RTABLE,
177 			    &SEMANAGE_FCONTEXT_FILE_RTABLE,
178 			    &dconfig->dbase) < 0)
179 		return STATUS_ERR;
180 
181 	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
182 	return STATUS_SUCCESS;
183 }
184 
fcontext_file_dbase_release(dbase_config_t * dconfig)185 void fcontext_file_dbase_release(dbase_config_t * dconfig)
186 {
187 
188 	dbase_file_release(dconfig->dbase);
189 }
190