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