• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <errno.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "user_internal.h"
6 #include "debug.h"
7 
8 struct sepol_user {
9 	/* This user's name */
10 	char *name;
11 
12 	/* This user's mls level (only required for mls) */
13 	char *mls_level;
14 
15 	/* This user's mls range (only required for mls) */
16 	char *mls_range;
17 
18 	/* The role array */
19 	char **roles;
20 
21 	/* The number of roles */
22 	unsigned int num_roles;
23 };
24 
25 struct sepol_user_key {
26 	/* This user's name */
27 	char *name;
28 };
29 
sepol_user_key_create(sepol_handle_t * handle,const char * name,sepol_user_key_t ** key_ptr)30 int sepol_user_key_create(sepol_handle_t * handle,
31 			  const char *name, sepol_user_key_t ** key_ptr)
32 {
33 
34 	sepol_user_key_t *tmp_key =
35 	    (sepol_user_key_t *) malloc(sizeof(sepol_user_key_t));
36 
37 	if (!tmp_key) {
38 		ERR(handle, "out of memory, "
39 		    "could not create selinux user key");
40 		return STATUS_ERR;
41 	}
42 
43 	tmp_key->name = strdup(name);
44 	if (!tmp_key->name) {
45 		ERR(handle, "out of memory, could not create selinux user key");
46 		free(tmp_key);
47 		return STATUS_ERR;
48 	}
49 
50 	*key_ptr = tmp_key;
51 	return STATUS_SUCCESS;
52 }
53 
hidden_def(sepol_user_key_create)54 hidden_def(sepol_user_key_create)
55 
56 void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name)
57 {
58 
59 	*name = key->name;
60 }
61 
hidden_def(sepol_user_key_unpack)62 hidden_def(sepol_user_key_unpack)
63 
64 int sepol_user_key_extract(sepol_handle_t * handle,
65 			   const sepol_user_t * user,
66 			   sepol_user_key_t ** key_ptr)
67 {
68 
69 	if (sepol_user_key_create(handle, user->name, key_ptr) < 0) {
70 		ERR(handle, "could not extract key from user %s", user->name);
71 		return STATUS_ERR;
72 	}
73 
74 	return STATUS_SUCCESS;
75 }
76 
sepol_user_key_free(sepol_user_key_t * key)77 void sepol_user_key_free(sepol_user_key_t * key)
78 {
79 	if (!key)
80 		return;
81 	free(key->name);
82 	free(key);
83 }
84 
sepol_user_compare(const sepol_user_t * user,const sepol_user_key_t * key)85 int sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key)
86 {
87 
88 	return strcmp(user->name, key->name);
89 }
90 
sepol_user_compare2(const sepol_user_t * user,const sepol_user_t * user2)91 int sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2)
92 {
93 
94 	return strcmp(user->name, user2->name);
95 }
96 
97 /* Name */
sepol_user_get_name(const sepol_user_t * user)98 const char *sepol_user_get_name(const sepol_user_t * user)
99 {
100 
101 	return user->name;
102 }
103 
sepol_user_set_name(sepol_handle_t * handle,sepol_user_t * user,const char * name)104 int sepol_user_set_name(sepol_handle_t * handle,
105 			sepol_user_t * user, const char *name)
106 {
107 
108 	char *tmp_name = strdup(name);
109 	if (!tmp_name) {
110 		ERR(handle, "out of memory, could not set name");
111 		return STATUS_ERR;
112 	}
113 	free(user->name);
114 	user->name = tmp_name;
115 	return STATUS_SUCCESS;
116 }
117 
hidden_def(sepol_user_set_name)118 hidden_def(sepol_user_set_name)
119 
120 /* MLS */
121 const char *sepol_user_get_mlslevel(const sepol_user_t * user)
122 {
123 
124 	return user->mls_level;
125 }
126 
hidden_def(sepol_user_get_mlslevel)127 hidden_def(sepol_user_get_mlslevel)
128 
129 int sepol_user_set_mlslevel(sepol_handle_t * handle,
130 			    sepol_user_t * user, const char *mls_level)
131 {
132 
133 	char *tmp_mls_level = strdup(mls_level);
134 	if (!tmp_mls_level) {
135 		ERR(handle, "out of memory, "
136 		    "could not set MLS default level");
137 		return STATUS_ERR;
138 	}
139 	free(user->mls_level);
140 	user->mls_level = tmp_mls_level;
141 	return STATUS_SUCCESS;
142 }
143 
hidden_def(sepol_user_set_mlslevel)144 hidden_def(sepol_user_set_mlslevel)
145 
146 const char *sepol_user_get_mlsrange(const sepol_user_t * user)
147 {
148 
149 	return user->mls_range;
150 }
151 
hidden_def(sepol_user_get_mlsrange)152 hidden_def(sepol_user_get_mlsrange)
153 
154 int sepol_user_set_mlsrange(sepol_handle_t * handle,
155 			    sepol_user_t * user, const char *mls_range)
156 {
157 
158 	char *tmp_mls_range = strdup(mls_range);
159 	if (!tmp_mls_range) {
160 		ERR(handle, "out of memory, "
161 		    "could not set MLS allowed range");
162 		return STATUS_ERR;
163 	}
164 	free(user->mls_range);
165 	user->mls_range = tmp_mls_range;
166 	return STATUS_SUCCESS;
167 }
168 
hidden_def(sepol_user_set_mlsrange)169 hidden_def(sepol_user_set_mlsrange)
170 
171 /* Roles */
172 int sepol_user_get_num_roles(const sepol_user_t * user)
173 {
174 
175 	return user->num_roles;
176 }
177 
sepol_user_add_role(sepol_handle_t * handle,sepol_user_t * user,const char * role)178 int sepol_user_add_role(sepol_handle_t * handle,
179 			sepol_user_t * user, const char *role)
180 {
181 
182 	char *role_cp;
183 	char **roles_realloc = NULL;
184 
185 	if (sepol_user_has_role(user, role))
186 		return STATUS_SUCCESS;
187 
188 	role_cp = strdup(role);
189 	if (!role_cp)
190 		goto omem;
191 
192 	roles_realloc = realloc(user->roles,
193 				sizeof(char *) * (user->num_roles + 1));
194 	if (!roles_realloc)
195 		goto omem;
196 
197 	user->num_roles++;
198 	user->roles = roles_realloc;
199 	user->roles[user->num_roles - 1] = role_cp;
200 
201 	return STATUS_SUCCESS;
202 
203       omem:
204 	ERR(handle, "out of memory, could not add role %s", role);
205 	free(role_cp);
206 	free(roles_realloc);
207 	return STATUS_ERR;
208 }
209 
hidden_def(sepol_user_add_role)210 hidden_def(sepol_user_add_role)
211 
212 int sepol_user_has_role(const sepol_user_t * user, const char *role)
213 {
214 
215 	unsigned int i;
216 
217 	for (i = 0; i < user->num_roles; i++)
218 		if (!strcmp(user->roles[i], role))
219 			return 1;
220 	return 0;
221 }
222 
hidden_def(sepol_user_has_role)223 hidden_def(sepol_user_has_role)
224 
225 int sepol_user_set_roles(sepol_handle_t * handle,
226 			 sepol_user_t * user,
227 			 const char **roles_arr, unsigned int num_roles)
228 {
229 
230 	unsigned int i;
231 	char **tmp_roles = NULL;
232 
233 	if (num_roles > 0) {
234 
235 		/* First, make a copy */
236 		tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles);
237 		if (!tmp_roles)
238 			goto omem;
239 
240 		for (i = 0; i < num_roles; i++) {
241 			tmp_roles[i] = strdup(roles_arr[i]);
242 			if (!tmp_roles[i])
243 				goto omem;
244 		}
245 	}
246 
247 	/* Apply other changes */
248 	for (i = 0; i < user->num_roles; i++)
249 		free(user->roles[i]);
250 	free(user->roles);
251 	user->roles = tmp_roles;
252 	user->num_roles = num_roles;
253 	return STATUS_SUCCESS;
254 
255       omem:
256 	ERR(handle, "out of memory, could not allocate roles array for"
257 	    "user %s", user->name);
258 
259 	if (tmp_roles) {
260 		for (i = 0; i < num_roles; i++) {
261 			if (!tmp_roles[i])
262 				break;
263 			free(tmp_roles[i]);
264 		}
265 	}
266 	free(tmp_roles);
267 	return STATUS_ERR;
268 }
269 
sepol_user_get_roles(sepol_handle_t * handle,const sepol_user_t * user,const char *** roles_arr,unsigned int * num_roles)270 int sepol_user_get_roles(sepol_handle_t * handle,
271 			 const sepol_user_t * user,
272 			 const char ***roles_arr, unsigned int *num_roles)
273 {
274 
275 	unsigned int i;
276 	const char **tmp_roles =
277 	    (const char **)malloc(sizeof(char *) * user->num_roles);
278 	if (!tmp_roles)
279 		goto omem;
280 
281 	for (i = 0; i < user->num_roles; i++)
282 		tmp_roles[i] = user->roles[i];
283 
284 	*roles_arr = tmp_roles;
285 	*num_roles = user->num_roles;
286 	return STATUS_SUCCESS;
287 
288       omem:
289 	ERR(handle, "out of memory, could not "
290 	    "allocate roles array for user %s", user->name);
291 	free(tmp_roles);
292 	return STATUS_ERR;
293 }
294 
hidden_def(sepol_user_get_roles)295 hidden_def(sepol_user_get_roles)
296 
297 void sepol_user_del_role(sepol_user_t * user, const char *role)
298 {
299 
300 	unsigned int i;
301 	for (i = 0; i < user->num_roles; i++) {
302 		if (!strcmp(user->roles[i], role)) {
303 			free(user->roles[i]);
304 			user->roles[i] = NULL;
305 			user->roles[i] = user->roles[user->num_roles - 1];
306 			user->num_roles--;
307 		}
308 	}
309 }
310 
311 /* Create */
sepol_user_create(sepol_handle_t * handle,sepol_user_t ** user_ptr)312 int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr)
313 {
314 
315 	sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t));
316 
317 	if (!user) {
318 		ERR(handle, "out of memory, "
319 		    "could not create selinux user record");
320 		return STATUS_ERR;
321 	}
322 
323 	user->roles = NULL;
324 	user->num_roles = 0;
325 	user->name = NULL;
326 	user->mls_level = NULL;
327 	user->mls_range = NULL;
328 
329 	*user_ptr = user;
330 	return STATUS_SUCCESS;
331 }
332 
hidden_def(sepol_user_create)333 hidden_def(sepol_user_create)
334 
335 /* Deep copy clone */
336 int sepol_user_clone(sepol_handle_t * handle,
337 		     const sepol_user_t * user, sepol_user_t ** user_ptr)
338 {
339 
340 	sepol_user_t *new_user = NULL;
341 	unsigned int i;
342 
343 	if (sepol_user_create(handle, &new_user) < 0)
344 		goto err;
345 
346 	if (sepol_user_set_name(handle, new_user, user->name) < 0)
347 		goto err;
348 
349 	for (i = 0; i < user->num_roles; i++) {
350 		if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0)
351 			goto err;
352 	}
353 
354 	if (user->mls_level &&
355 	    (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0))
356 		goto err;
357 
358 	if (user->mls_range &&
359 	    (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0))
360 		goto err;
361 
362 	*user_ptr = new_user;
363 	return STATUS_SUCCESS;
364 
365       err:
366 	ERR(handle, "could not clone selinux user record");
367 	sepol_user_free(new_user);
368 	return STATUS_ERR;
369 }
370 
371 /* Destroy */
sepol_user_free(sepol_user_t * user)372 void sepol_user_free(sepol_user_t * user)
373 {
374 
375 	unsigned int i;
376 
377 	if (!user)
378 		return;
379 
380 	free(user->name);
381 	for (i = 0; i < user->num_roles; i++)
382 		free(user->roles[i]);
383 	free(user->roles);
384 	free(user->mls_level);
385 	free(user->mls_range);
386 	free(user);
387 }
388 
389 hidden_def(sepol_user_free)
390