• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <errno.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdio.h>
5 
6 #include "context_internal.h"
7 #include "debug.h"
8 
9 struct sepol_context {
10 
11 	/* Selinux user */
12 	char *user;
13 
14 	/* Selinux role */
15 	char *role;
16 
17 	/* Selinux type */
18 	char *type;
19 
20 	/* MLS */
21 	char *mls;
22 };
23 
24 /* User */
sepol_context_get_user(const sepol_context_t * con)25 const char *sepol_context_get_user(const sepol_context_t * con)
26 {
27 
28 	return con->user;
29 }
30 
hidden_def(sepol_context_get_user)31 hidden_def(sepol_context_get_user)
32 
33 int sepol_context_set_user(sepol_handle_t * handle,
34 			   sepol_context_t * con, const char *user)
35 {
36 
37 	char *tmp_user = strdup(user);
38 	if (!tmp_user) {
39 		ERR(handle, "out of memory, could not set "
40 		    "context user to %s", user);
41 		return STATUS_ERR;
42 	}
43 
44 	free(con->user);
45 	con->user = tmp_user;
46 	return STATUS_SUCCESS;
47 }
48 
hidden_def(sepol_context_set_user)49 hidden_def(sepol_context_set_user)
50 
51 /* Role */
52 const char *sepol_context_get_role(const sepol_context_t * con)
53 {
54 
55 	return con->role;
56 }
57 
hidden_def(sepol_context_get_role)58 hidden_def(sepol_context_get_role)
59 
60 int sepol_context_set_role(sepol_handle_t * handle,
61 			   sepol_context_t * con, const char *role)
62 {
63 
64 	char *tmp_role = strdup(role);
65 	if (!tmp_role) {
66 		ERR(handle, "out of memory, could not set "
67 		    "context role to %s", role);
68 		return STATUS_ERR;
69 	}
70 	free(con->role);
71 	con->role = tmp_role;
72 	return STATUS_SUCCESS;
73 }
74 
hidden_def(sepol_context_set_role)75 hidden_def(sepol_context_set_role)
76 
77 /* Type */
78 const char *sepol_context_get_type(const sepol_context_t * con)
79 {
80 
81 	return con->type;
82 }
83 
hidden_def(sepol_context_get_type)84 hidden_def(sepol_context_get_type)
85 
86 int sepol_context_set_type(sepol_handle_t * handle,
87 			   sepol_context_t * con, const char *type)
88 {
89 
90 	char *tmp_type = strdup(type);
91 	if (!tmp_type) {
92 		ERR(handle, "out of memory, could not set "
93 		    "context type to %s", type);
94 		return STATUS_ERR;
95 	}
96 	free(con->type);
97 	con->type = tmp_type;
98 	return STATUS_SUCCESS;
99 }
100 
hidden_def(sepol_context_set_type)101 hidden_def(sepol_context_set_type)
102 
103 /* MLS */
104 const char *sepol_context_get_mls(const sepol_context_t * con)
105 {
106 
107 	return con->mls;
108 }
109 
hidden_def(sepol_context_get_mls)110 hidden_def(sepol_context_get_mls)
111 
112 int sepol_context_set_mls(sepol_handle_t * handle,
113 			  sepol_context_t * con, const char *mls)
114 {
115 
116 	char *tmp_mls = strdup(mls);
117 	if (!tmp_mls) {
118 		ERR(handle, "out of memory, could not set "
119 		    "MLS fields to %s", mls);
120 		return STATUS_ERR;
121 	}
122 	free(con->mls);
123 	con->mls = tmp_mls;
124 	return STATUS_SUCCESS;
125 }
126 
hidden_def(sepol_context_set_mls)127 hidden_def(sepol_context_set_mls)
128 
129 /* Create */
130 int sepol_context_create(sepol_handle_t * handle, sepol_context_t ** con_ptr)
131 {
132 
133 	sepol_context_t *con =
134 	    (sepol_context_t *) malloc(sizeof(sepol_context_t));
135 
136 	if (!con) {
137 		ERR(handle, "out of memory, could not " "create context\n");
138 		return STATUS_ERR;
139 	}
140 
141 	con->user = NULL;
142 	con->role = NULL;
143 	con->type = NULL;
144 	con->mls = NULL;
145 	*con_ptr = con;
146 	return STATUS_SUCCESS;
147 }
148 
hidden_def(sepol_context_create)149 hidden_def(sepol_context_create)
150 
151 /* Deep copy clone */
152 int sepol_context_clone(sepol_handle_t * handle,
153 			const sepol_context_t * con, sepol_context_t ** con_ptr)
154 {
155 
156 	sepol_context_t *new_con = NULL;
157 
158 	if (!con) {
159 		*con_ptr = NULL;
160 		return 0;
161 	}
162 
163 	if (sepol_context_create(handle, &new_con) < 0)
164 		goto err;
165 
166 	if (!(new_con->user = strdup(con->user)))
167 		goto omem;
168 
169 	if (!(new_con->role = strdup(con->role)))
170 		goto omem;
171 
172 	if (!(new_con->type = strdup(con->type)))
173 		goto omem;
174 
175 	if (con->mls && !(new_con->mls = strdup(con->mls)))
176 		goto omem;
177 
178 	*con_ptr = new_con;
179 	return STATUS_SUCCESS;
180 
181       omem:
182 	ERR(handle, "out of memory");
183 
184       err:
185 	ERR(handle, "could not clone context record");
186 	sepol_context_free(new_con);
187 	return STATUS_ERR;
188 }
189 
hidden_def(sepol_context_clone)190 hidden_def(sepol_context_clone)
191 
192 /* Destroy */
193 void sepol_context_free(sepol_context_t * con)
194 {
195 
196 	if (!con)
197 		return;
198 
199 	free(con->user);
200 	free(con->role);
201 	free(con->type);
202 	free(con->mls);
203 	free(con);
204 }
205 
hidden_def(sepol_context_free)206 hidden_def(sepol_context_free)
207 
208 int sepol_context_from_string(sepol_handle_t * handle,
209 			      const char *str, sepol_context_t ** con)
210 {
211 
212 	char *tmp = NULL, *low, *high;
213 	sepol_context_t *tmp_con = NULL;
214 
215 	if (!strcmp(str, "<<none>>")) {
216 		*con = NULL;
217 		return STATUS_SUCCESS;
218 	}
219 
220 	if (sepol_context_create(handle, &tmp_con) < 0)
221 		goto err;
222 
223 	/* Working copy context */
224 	tmp = strdup(str);
225 	if (!tmp) {
226 		ERR(handle, "out of memory");
227 		goto err;
228 	}
229 	low = tmp;
230 
231 	/* Then, break it into its components */
232 
233 	/* User */
234 	if (!(high = strchr(low, ':')))
235 		goto mcontext;
236 	else
237 		*high++ = '\0';
238 	if (sepol_context_set_user(handle, tmp_con, low) < 0)
239 		goto err;
240 	low = high;
241 
242 	/* Role */
243 	if (!(high = strchr(low, ':')))
244 		goto mcontext;
245 	else
246 		*high++ = '\0';
247 	if (sepol_context_set_role(handle, tmp_con, low) < 0)
248 		goto err;
249 	low = high;
250 
251 	/* Type, and possibly MLS */
252 	if (!(high = strchr(low, ':'))) {
253 		if (sepol_context_set_type(handle, tmp_con, low) < 0)
254 			goto err;
255 	} else {
256 		*high++ = '\0';
257 		if (sepol_context_set_type(handle, tmp_con, low) < 0)
258 			goto err;
259 		low = high;
260 		if (sepol_context_set_mls(handle, tmp_con, low) < 0)
261 			goto err;
262 	}
263 
264 	free(tmp);
265 	*con = tmp_con;
266 
267 	return STATUS_SUCCESS;
268 
269       mcontext:
270 	errno = EINVAL;
271 	ERR(handle, "malformed context \"%s\"", str);
272 
273       err:
274 	ERR(handle, "could not construct context from string");
275 	free(tmp);
276 	sepol_context_free(tmp_con);
277 	return STATUS_ERR;
278 }
279 
hidden_def(sepol_context_from_string)280 hidden_def(sepol_context_from_string)
281 
282 int sepol_context_to_string(sepol_handle_t * handle,
283 			    const sepol_context_t * con, char **str_ptr)
284 {
285 
286 	int rc;
287 	const int user_sz = strlen(con->user);
288 	const int role_sz = strlen(con->role);
289 	const int type_sz = strlen(con->type);
290 	const int mls_sz = (con->mls) ? strlen(con->mls) : 0;
291 	const int total_sz = user_sz + role_sz + type_sz +
292 	    mls_sz + ((con->mls) ? 3 : 2);
293 
294 	char *str = (char *)malloc(total_sz + 1);
295 	if (!str)
296 		goto omem;
297 
298 	if (con->mls) {
299 		rc = snprintf(str, total_sz + 1, "%s:%s:%s:%s",
300 			      con->user, con->role, con->type, con->mls);
301 		if (rc < 0 || (rc >= total_sz + 1)) {
302 			ERR(handle, "print error");
303 			goto err;
304 		}
305 	} else {
306 		rc = snprintf(str, total_sz + 1, "%s:%s:%s",
307 			      con->user, con->role, con->type);
308 		if (rc < 0 || (rc >= total_sz + 1)) {
309 			ERR(handle, "print error");
310 			goto err;
311 		}
312 	}
313 
314 	*str_ptr = str;
315 	return STATUS_SUCCESS;
316 
317       omem:
318 	ERR(handle, "out of memory");
319 
320       err:
321 	ERR(handle, "could not convert context to string");
322 	free(str);
323 	return STATUS_ERR;
324 }
325