xref: /aosp_15_r20/external/selinux/libsemanage/src/interfaces_file.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 struct semanage_iface;
4 struct semanage_iface_key;
5 typedef struct semanage_iface record_t;
6 typedef struct semanage_iface_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 <semanage/handle.h>
16 #include "iface_internal.h"
17 #include "database_file.h"
18 #include "parse_utils.h"
19 #include "debug.h"
20 
iface_print(semanage_handle_t * handle,semanage_iface_t * iface,FILE * str)21 static int iface_print(semanage_handle_t * handle,
22 		       semanage_iface_t * iface, FILE * str)
23 {
24 
25 	char *con_str = NULL;
26 
27 	const char *name = semanage_iface_get_name(iface);
28 	semanage_context_t *ifcon = semanage_iface_get_ifcon(iface);
29 	semanage_context_t *msgcon = semanage_iface_get_msgcon(iface);
30 
31 	if (fprintf(str, "netifcon %s ", name) < 0)
32 		goto err;
33 
34 	if (semanage_context_to_string(handle, ifcon, &con_str) < 0)
35 		goto err;
36 	if (fprintf(str, "%s ", con_str) < 0)
37 		goto err;
38 	free(con_str);
39 	con_str = NULL;
40 
41 	if (semanage_context_to_string(handle, msgcon, &con_str) < 0)
42 		goto err;
43 	if (fprintf(str, "%s\n", con_str) < 0)
44 		goto err;
45 	free(con_str);
46 	con_str = NULL;
47 
48 	return STATUS_SUCCESS;
49 
50       err:
51 	ERR(handle, "could not print interface %s to stream", name);
52 	free(con_str);
53 	return STATUS_ERR;
54 }
55 
iface_parse(semanage_handle_t * handle,parse_info_t * info,semanage_iface_t * iface)56 static int iface_parse(semanage_handle_t * handle,
57 		       parse_info_t * info, semanage_iface_t * iface)
58 {
59 
60 	char *str = NULL;
61 	semanage_context_t *con = NULL;
62 
63 	if (parse_skip_space(handle, info) < 0)
64 		goto err;
65 	if (!info->ptr)
66 		goto last;
67 
68 	/* Header */
69 	if (parse_assert_str(handle, info, "netifcon") < 0)
70 		goto err;
71 	if (parse_assert_space(handle, info) < 0)
72 		goto err;
73 
74 	/* Name */
75 	if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
76 		goto err;
77 	if (semanage_iface_set_name(handle, iface, str) < 0)
78 		goto err;
79 	free(str);
80 	str = NULL;
81 
82 	/* Interface context */
83 	if (parse_assert_space(handle, info) < 0)
84 		goto err;
85 	if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
86 		goto err;
87 	if (semanage_context_from_string(handle, str, &con) < 0) {
88 		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
89 		    str, info->filename, info->lineno, info->orig_line);
90 		goto err;
91 	}
92 	if (con == NULL) {
93 		ERR(handle, "<<none>> context is not valid for "
94 		    "interfaces (%s: %u)\n%s", info->filename,
95 		    info->lineno, info->orig_line);
96 		goto err;
97 	}
98 	free(str);
99 	str = NULL;
100 
101 	if (semanage_iface_set_ifcon(handle, iface, con) < 0)
102 		goto err;
103 	semanage_context_free(con);
104 	con = NULL;
105 
106 	/* Message context */
107 	if (parse_assert_space(handle, info) < 0)
108 		goto err;
109 	if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
110 		goto err;
111 	if (semanage_context_from_string(handle, str, &con) < 0) {
112 		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
113 		    str, info->filename, info->lineno, info->orig_line);
114 		goto err;
115 	}
116 	if (con == NULL) {
117 		ERR(handle, "<<none>> context is not valid for "
118 		    "interfaces (%s: %u)\n%s", info->filename,
119 		    info->lineno, info->orig_line);
120 		goto err;
121 	}
122 	free(str);
123 	str = NULL;
124 
125 	if (semanage_iface_set_msgcon(handle, iface, con) < 0)
126 		goto err;
127 	semanage_context_free(con);
128 	con = NULL;
129 
130 	if (parse_assert_space(handle, info) < 0)
131 		goto err;
132 
133 	return STATUS_SUCCESS;
134 
135       last:
136 	parse_dispose_line(info);
137 	return STATUS_NODATA;
138 
139       err:
140 	ERR(handle, "could not parse interface record");
141 	free(str);
142 	semanage_context_free(con);
143 	parse_dispose_line(info);
144 	return STATUS_ERR;
145 }
146 
147 /* IFACE RECORD: FILE extension: method table */
148 record_file_table_t SEMANAGE_IFACE_FILE_RTABLE = {
149 	.parse = iface_parse,
150 	.print = iface_print,
151 };
152 
iface_file_dbase_init(semanage_handle_t * handle,const char * path_ro,const char * path_rw,dbase_config_t * dconfig)153 int iface_file_dbase_init(semanage_handle_t * handle,
154 			  const char *path_ro,
155 			  const char *path_rw,
156 			  dbase_config_t * dconfig)
157 {
158 
159 	if (dbase_file_init(handle,
160 			    path_ro,
161 			    path_rw,
162 			    &SEMANAGE_IFACE_RTABLE,
163 			    &SEMANAGE_IFACE_FILE_RTABLE, &dconfig->dbase) < 0)
164 		return STATUS_ERR;
165 
166 	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
167 	return STATUS_SUCCESS;
168 }
169 
iface_file_dbase_release(dbase_config_t * dconfig)170 void iface_file_dbase_release(dbase_config_t * dconfig)
171 {
172 
173 	dbase_file_release(dconfig->dbase);
174 }
175