1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <errno.h>
2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h>
3255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h>
4255e72915d4cbddceb435e13d81601755714e9fSE Android
5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "user_internal.h"
6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h"
7255e72915d4cbddceb435e13d81601755714e9fSE Android
8255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_user {
9255e72915d4cbddceb435e13d81601755714e9fSE Android	/* This user's name */
10255e72915d4cbddceb435e13d81601755714e9fSE Android	char *name;
11255e72915d4cbddceb435e13d81601755714e9fSE Android
12255e72915d4cbddceb435e13d81601755714e9fSE Android	/* This user's mls level (only required for mls) */
13255e72915d4cbddceb435e13d81601755714e9fSE Android	char *mls_level;
14255e72915d4cbddceb435e13d81601755714e9fSE Android
15255e72915d4cbddceb435e13d81601755714e9fSE Android	/* This user's mls range (only required for mls) */
16255e72915d4cbddceb435e13d81601755714e9fSE Android	char *mls_range;
17255e72915d4cbddceb435e13d81601755714e9fSE Android
18255e72915d4cbddceb435e13d81601755714e9fSE Android	/* The role array */
19255e72915d4cbddceb435e13d81601755714e9fSE Android	char **roles;
20255e72915d4cbddceb435e13d81601755714e9fSE Android
21255e72915d4cbddceb435e13d81601755714e9fSE Android	/* The number of roles */
22255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int num_roles;
23255e72915d4cbddceb435e13d81601755714e9fSE Android};
24255e72915d4cbddceb435e13d81601755714e9fSE Android
25255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_user_key {
26255e72915d4cbddceb435e13d81601755714e9fSE Android	/* This user's name */
27255e72915d4cbddceb435e13d81601755714e9fSE Android	const char *name;
28255e72915d4cbddceb435e13d81601755714e9fSE Android};
29255e72915d4cbddceb435e13d81601755714e9fSE Android
30255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_key_create(sepol_handle_t * handle,
31255e72915d4cbddceb435e13d81601755714e9fSE Android			  const char *name, sepol_user_key_t ** key_ptr)
32255e72915d4cbddceb435e13d81601755714e9fSE Android{
33255e72915d4cbddceb435e13d81601755714e9fSE Android
34255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_user_key_t *tmp_key =
35255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_user_key_t *) malloc(sizeof(sepol_user_key_t));
36255e72915d4cbddceb435e13d81601755714e9fSE Android
37255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_key) {
38255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, "
39255e72915d4cbddceb435e13d81601755714e9fSE Android		    "could not create selinux user key");
40255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
41255e72915d4cbddceb435e13d81601755714e9fSE Android	}
42255e72915d4cbddceb435e13d81601755714e9fSE Android
43255e72915d4cbddceb435e13d81601755714e9fSE Android	tmp_key->name = name;
44255e72915d4cbddceb435e13d81601755714e9fSE Android
45255e72915d4cbddceb435e13d81601755714e9fSE Android	*key_ptr = tmp_key;
46255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
47255e72915d4cbddceb435e13d81601755714e9fSE Android}
48255e72915d4cbddceb435e13d81601755714e9fSE Android
49255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_key_create)
50255e72915d4cbddceb435e13d81601755714e9fSE Android
51255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_user_key_unpack(const sepol_user_key_t * key, const char **name)
52255e72915d4cbddceb435e13d81601755714e9fSE Android{
53255e72915d4cbddceb435e13d81601755714e9fSE Android
54255e72915d4cbddceb435e13d81601755714e9fSE Android	*name = key->name;
55255e72915d4cbddceb435e13d81601755714e9fSE Android}
56255e72915d4cbddceb435e13d81601755714e9fSE Android
57255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_key_unpack)
58255e72915d4cbddceb435e13d81601755714e9fSE Android
59255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_key_extract(sepol_handle_t * handle,
60255e72915d4cbddceb435e13d81601755714e9fSE Android			   const sepol_user_t * user,
61255e72915d4cbddceb435e13d81601755714e9fSE Android			   sepol_user_key_t ** key_ptr)
62255e72915d4cbddceb435e13d81601755714e9fSE Android{
63255e72915d4cbddceb435e13d81601755714e9fSE Android
64255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_user_key_create(handle, user->name, key_ptr) < 0) {
65255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "could not extract key from user %s", user->name);
66255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
67255e72915d4cbddceb435e13d81601755714e9fSE Android	}
68255e72915d4cbddceb435e13d81601755714e9fSE Android
69255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
70255e72915d4cbddceb435e13d81601755714e9fSE Android}
71255e72915d4cbddceb435e13d81601755714e9fSE Android
72255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_user_key_free(sepol_user_key_t * key)
73255e72915d4cbddceb435e13d81601755714e9fSE Android{
74255e72915d4cbddceb435e13d81601755714e9fSE Android	free(key);
75255e72915d4cbddceb435e13d81601755714e9fSE Android}
76255e72915d4cbddceb435e13d81601755714e9fSE Android
77255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key)
78255e72915d4cbddceb435e13d81601755714e9fSE Android{
79255e72915d4cbddceb435e13d81601755714e9fSE Android
80255e72915d4cbddceb435e13d81601755714e9fSE Android	return strcmp(user->name, key->name);
81255e72915d4cbddceb435e13d81601755714e9fSE Android}
82255e72915d4cbddceb435e13d81601755714e9fSE Android
83255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2)
84255e72915d4cbddceb435e13d81601755714e9fSE Android{
85255e72915d4cbddceb435e13d81601755714e9fSE Android
86255e72915d4cbddceb435e13d81601755714e9fSE Android	return strcmp(user->name, user2->name);
87255e72915d4cbddceb435e13d81601755714e9fSE Android}
88255e72915d4cbddceb435e13d81601755714e9fSE Android
89255e72915d4cbddceb435e13d81601755714e9fSE Android/* Name */
90255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_user_get_name(const sepol_user_t * user)
91255e72915d4cbddceb435e13d81601755714e9fSE Android{
92255e72915d4cbddceb435e13d81601755714e9fSE Android
93255e72915d4cbddceb435e13d81601755714e9fSE Android	return user->name;
94255e72915d4cbddceb435e13d81601755714e9fSE Android}
95255e72915d4cbddceb435e13d81601755714e9fSE Android
96255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_set_name(sepol_handle_t * handle,
97255e72915d4cbddceb435e13d81601755714e9fSE Android			sepol_user_t * user, const char *name)
98255e72915d4cbddceb435e13d81601755714e9fSE Android{
99255e72915d4cbddceb435e13d81601755714e9fSE Android
100255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_name = strdup(name);
101255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_name) {
102255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, could not set name");
103255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
104255e72915d4cbddceb435e13d81601755714e9fSE Android	}
105255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->name);
106255e72915d4cbddceb435e13d81601755714e9fSE Android	user->name = tmp_name;
107255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
108255e72915d4cbddceb435e13d81601755714e9fSE Android}
109255e72915d4cbddceb435e13d81601755714e9fSE Android
110255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_set_name)
111255e72915d4cbddceb435e13d81601755714e9fSE Android
112255e72915d4cbddceb435e13d81601755714e9fSE Android/* MLS */
113255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_user_get_mlslevel(const sepol_user_t * user)
114255e72915d4cbddceb435e13d81601755714e9fSE Android{
115255e72915d4cbddceb435e13d81601755714e9fSE Android
116255e72915d4cbddceb435e13d81601755714e9fSE Android	return user->mls_level;
117255e72915d4cbddceb435e13d81601755714e9fSE Android}
118255e72915d4cbddceb435e13d81601755714e9fSE Android
119255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_get_mlslevel)
120255e72915d4cbddceb435e13d81601755714e9fSE Android
121255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_set_mlslevel(sepol_handle_t * handle,
122255e72915d4cbddceb435e13d81601755714e9fSE Android			    sepol_user_t * user, const char *mls_level)
123255e72915d4cbddceb435e13d81601755714e9fSE Android{
124255e72915d4cbddceb435e13d81601755714e9fSE Android
125255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_mls_level = strdup(mls_level);
126255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_mls_level) {
127255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, "
128255e72915d4cbddceb435e13d81601755714e9fSE Android		    "could not set MLS default level");
129255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
130255e72915d4cbddceb435e13d81601755714e9fSE Android	}
131255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->mls_level);
132255e72915d4cbddceb435e13d81601755714e9fSE Android	user->mls_level = tmp_mls_level;
133255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
134255e72915d4cbddceb435e13d81601755714e9fSE Android}
135255e72915d4cbddceb435e13d81601755714e9fSE Android
136255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_set_mlslevel)
137255e72915d4cbddceb435e13d81601755714e9fSE Android
138255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_user_get_mlsrange(const sepol_user_t * user)
139255e72915d4cbddceb435e13d81601755714e9fSE Android{
140255e72915d4cbddceb435e13d81601755714e9fSE Android
141255e72915d4cbddceb435e13d81601755714e9fSE Android	return user->mls_range;
142255e72915d4cbddceb435e13d81601755714e9fSE Android}
143255e72915d4cbddceb435e13d81601755714e9fSE Android
144255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_get_mlsrange)
145255e72915d4cbddceb435e13d81601755714e9fSE Android
146255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_set_mlsrange(sepol_handle_t * handle,
147255e72915d4cbddceb435e13d81601755714e9fSE Android			    sepol_user_t * user, const char *mls_range)
148255e72915d4cbddceb435e13d81601755714e9fSE Android{
149255e72915d4cbddceb435e13d81601755714e9fSE Android
150255e72915d4cbddceb435e13d81601755714e9fSE Android	char *tmp_mls_range = strdup(mls_range);
151255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_mls_range) {
152255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, "
153255e72915d4cbddceb435e13d81601755714e9fSE Android		    "could not set MLS allowed range");
154255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
155255e72915d4cbddceb435e13d81601755714e9fSE Android	}
156255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->mls_range);
157255e72915d4cbddceb435e13d81601755714e9fSE Android	user->mls_range = tmp_mls_range;
158255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
159255e72915d4cbddceb435e13d81601755714e9fSE Android}
160255e72915d4cbddceb435e13d81601755714e9fSE Android
161255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_set_mlsrange)
162255e72915d4cbddceb435e13d81601755714e9fSE Android
163255e72915d4cbddceb435e13d81601755714e9fSE Android/* Roles */
164255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_get_num_roles(const sepol_user_t * user)
165255e72915d4cbddceb435e13d81601755714e9fSE Android{
166255e72915d4cbddceb435e13d81601755714e9fSE Android
167255e72915d4cbddceb435e13d81601755714e9fSE Android	return user->num_roles;
168255e72915d4cbddceb435e13d81601755714e9fSE Android}
169255e72915d4cbddceb435e13d81601755714e9fSE Android
170255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_add_role(sepol_handle_t * handle,
171255e72915d4cbddceb435e13d81601755714e9fSE Android			sepol_user_t * user, const char *role)
172255e72915d4cbddceb435e13d81601755714e9fSE Android{
173255e72915d4cbddceb435e13d81601755714e9fSE Android
174255e72915d4cbddceb435e13d81601755714e9fSE Android	char *role_cp;
175255e72915d4cbddceb435e13d81601755714e9fSE Android	char **roles_realloc;
176255e72915d4cbddceb435e13d81601755714e9fSE Android
177255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_user_has_role(user, role))
178255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_SUCCESS;
179255e72915d4cbddceb435e13d81601755714e9fSE Android
180255e72915d4cbddceb435e13d81601755714e9fSE Android	role_cp = strdup(role);
181255e72915d4cbddceb435e13d81601755714e9fSE Android	roles_realloc = realloc(user->roles,
182255e72915d4cbddceb435e13d81601755714e9fSE Android				sizeof(char *) * (user->num_roles + 1));
183255e72915d4cbddceb435e13d81601755714e9fSE Android
184255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!role_cp || !roles_realloc)
185255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
186255e72915d4cbddceb435e13d81601755714e9fSE Android
187255e72915d4cbddceb435e13d81601755714e9fSE Android	user->num_roles++;
188255e72915d4cbddceb435e13d81601755714e9fSE Android	user->roles = roles_realloc;
189255e72915d4cbddceb435e13d81601755714e9fSE Android	user->roles[user->num_roles - 1] = role_cp;
190255e72915d4cbddceb435e13d81601755714e9fSE Android
191255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
192255e72915d4cbddceb435e13d81601755714e9fSE Android
193255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
194255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory, could not add role %s", role);
195255e72915d4cbddceb435e13d81601755714e9fSE Android	free(role_cp);
196255e72915d4cbddceb435e13d81601755714e9fSE Android	free(roles_realloc);
197255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
198255e72915d4cbddceb435e13d81601755714e9fSE Android}
199255e72915d4cbddceb435e13d81601755714e9fSE Android
200255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_add_role)
201255e72915d4cbddceb435e13d81601755714e9fSE Android
202255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_has_role(const sepol_user_t * user, const char *role)
203255e72915d4cbddceb435e13d81601755714e9fSE Android{
204255e72915d4cbddceb435e13d81601755714e9fSE Android
205255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
206255e72915d4cbddceb435e13d81601755714e9fSE Android
207255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++)
208255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!strcmp(user->roles[i], role))
209255e72915d4cbddceb435e13d81601755714e9fSE Android			return 1;
210255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
211255e72915d4cbddceb435e13d81601755714e9fSE Android}
212255e72915d4cbddceb435e13d81601755714e9fSE Android
213255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_has_role)
214255e72915d4cbddceb435e13d81601755714e9fSE Android
215255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_set_roles(sepol_handle_t * handle,
216255e72915d4cbddceb435e13d81601755714e9fSE Android			 sepol_user_t * user,
217255e72915d4cbddceb435e13d81601755714e9fSE Android			 const char **roles_arr, unsigned int num_roles)
218255e72915d4cbddceb435e13d81601755714e9fSE Android{
219255e72915d4cbddceb435e13d81601755714e9fSE Android
220255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
221255e72915d4cbddceb435e13d81601755714e9fSE Android	char **tmp_roles = NULL;
222255e72915d4cbddceb435e13d81601755714e9fSE Android
223255e72915d4cbddceb435e13d81601755714e9fSE Android	if (num_roles > 0) {
224255e72915d4cbddceb435e13d81601755714e9fSE Android
225255e72915d4cbddceb435e13d81601755714e9fSE Android		/* First, make a copy */
226255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles);
227255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!tmp_roles)
228255e72915d4cbddceb435e13d81601755714e9fSE Android			goto omem;
229255e72915d4cbddceb435e13d81601755714e9fSE Android
230255e72915d4cbddceb435e13d81601755714e9fSE Android		for (i = 0; i < num_roles; i++) {
231255e72915d4cbddceb435e13d81601755714e9fSE Android			tmp_roles[i] = strdup(roles_arr[i]);
232255e72915d4cbddceb435e13d81601755714e9fSE Android			if (!tmp_roles[i])
233255e72915d4cbddceb435e13d81601755714e9fSE Android				goto omem;
234255e72915d4cbddceb435e13d81601755714e9fSE Android		}
235255e72915d4cbddceb435e13d81601755714e9fSE Android	}
236255e72915d4cbddceb435e13d81601755714e9fSE Android
237255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Apply other changes */
238255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++)
239255e72915d4cbddceb435e13d81601755714e9fSE Android		free(user->roles[i]);
240255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->roles);
241255e72915d4cbddceb435e13d81601755714e9fSE Android	user->roles = tmp_roles;
242255e72915d4cbddceb435e13d81601755714e9fSE Android	user->num_roles = num_roles;
243255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
244255e72915d4cbddceb435e13d81601755714e9fSE Android
245255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
246255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory, could not allocate roles array for"
247255e72915d4cbddceb435e13d81601755714e9fSE Android	    "user %s", user->name);
248255e72915d4cbddceb435e13d81601755714e9fSE Android
249255e72915d4cbddceb435e13d81601755714e9fSE Android	if (tmp_roles) {
250255e72915d4cbddceb435e13d81601755714e9fSE Android		for (i = 0; i < num_roles; i++) {
251255e72915d4cbddceb435e13d81601755714e9fSE Android			if (!tmp_roles[i])
252255e72915d4cbddceb435e13d81601755714e9fSE Android				break;
253255e72915d4cbddceb435e13d81601755714e9fSE Android			free(tmp_roles[i]);
254255e72915d4cbddceb435e13d81601755714e9fSE Android		}
255255e72915d4cbddceb435e13d81601755714e9fSE Android	}
256255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_roles);
257255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
258255e72915d4cbddceb435e13d81601755714e9fSE Android}
259255e72915d4cbddceb435e13d81601755714e9fSE Android
260255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_get_roles(sepol_handle_t * handle,
261255e72915d4cbddceb435e13d81601755714e9fSE Android			 const sepol_user_t * user,
262255e72915d4cbddceb435e13d81601755714e9fSE Android			 const char ***roles_arr, unsigned int *num_roles)
263255e72915d4cbddceb435e13d81601755714e9fSE Android{
264255e72915d4cbddceb435e13d81601755714e9fSE Android
265255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
266255e72915d4cbddceb435e13d81601755714e9fSE Android	const char **tmp_roles =
267255e72915d4cbddceb435e13d81601755714e9fSE Android	    (const char **)malloc(sizeof(char *) * user->num_roles);
268255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!tmp_roles)
269255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
270255e72915d4cbddceb435e13d81601755714e9fSE Android
271255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++)
272255e72915d4cbddceb435e13d81601755714e9fSE Android		tmp_roles[i] = user->roles[i];
273255e72915d4cbddceb435e13d81601755714e9fSE Android
274255e72915d4cbddceb435e13d81601755714e9fSE Android	*roles_arr = tmp_roles;
275255e72915d4cbddceb435e13d81601755714e9fSE Android	*num_roles = user->num_roles;
276255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
277255e72915d4cbddceb435e13d81601755714e9fSE Android
278255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
279255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory, could not "
280255e72915d4cbddceb435e13d81601755714e9fSE Android	    "allocate roles array for user %s", user->name);
281255e72915d4cbddceb435e13d81601755714e9fSE Android	free(tmp_roles);
282255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
283255e72915d4cbddceb435e13d81601755714e9fSE Android}
284255e72915d4cbddceb435e13d81601755714e9fSE Android
285255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_get_roles)
286255e72915d4cbddceb435e13d81601755714e9fSE Android
287255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_user_del_role(sepol_user_t * user, const char *role)
288255e72915d4cbddceb435e13d81601755714e9fSE Android{
289255e72915d4cbddceb435e13d81601755714e9fSE Android
290255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
291255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++) {
292255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!strcmp(user->roles[i], role)) {
293255e72915d4cbddceb435e13d81601755714e9fSE Android			free(user->roles[i]);
294255e72915d4cbddceb435e13d81601755714e9fSE Android			user->roles[i] = NULL;
295255e72915d4cbddceb435e13d81601755714e9fSE Android			user->roles[i] = user->roles[user->num_roles - 1];
296255e72915d4cbddceb435e13d81601755714e9fSE Android			user->num_roles--;
297255e72915d4cbddceb435e13d81601755714e9fSE Android		}
298255e72915d4cbddceb435e13d81601755714e9fSE Android	}
299255e72915d4cbddceb435e13d81601755714e9fSE Android}
300255e72915d4cbddceb435e13d81601755714e9fSE Android
301255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create */
302255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr)
303255e72915d4cbddceb435e13d81601755714e9fSE Android{
304255e72915d4cbddceb435e13d81601755714e9fSE Android
305255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t));
306255e72915d4cbddceb435e13d81601755714e9fSE Android
307255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!user) {
308255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory, "
309255e72915d4cbddceb435e13d81601755714e9fSE Android		    "could not create selinux user record");
310255e72915d4cbddceb435e13d81601755714e9fSE Android		return STATUS_ERR;
311255e72915d4cbddceb435e13d81601755714e9fSE Android	}
312255e72915d4cbddceb435e13d81601755714e9fSE Android
313255e72915d4cbddceb435e13d81601755714e9fSE Android	user->roles = NULL;
314255e72915d4cbddceb435e13d81601755714e9fSE Android	user->num_roles = 0;
315255e72915d4cbddceb435e13d81601755714e9fSE Android	user->name = NULL;
316255e72915d4cbddceb435e13d81601755714e9fSE Android	user->mls_level = NULL;
317255e72915d4cbddceb435e13d81601755714e9fSE Android	user->mls_range = NULL;
318255e72915d4cbddceb435e13d81601755714e9fSE Android
319255e72915d4cbddceb435e13d81601755714e9fSE Android	*user_ptr = user;
320255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
321255e72915d4cbddceb435e13d81601755714e9fSE Android}
322255e72915d4cbddceb435e13d81601755714e9fSE Android
323255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_create)
324255e72915d4cbddceb435e13d81601755714e9fSE Android
325255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deep copy clone */
326255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_clone(sepol_handle_t * handle,
327255e72915d4cbddceb435e13d81601755714e9fSE Android		     const sepol_user_t * user, sepol_user_t ** user_ptr)
328255e72915d4cbddceb435e13d81601755714e9fSE Android{
329255e72915d4cbddceb435e13d81601755714e9fSE Android
330255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_user_t *new_user = NULL;
331255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
332255e72915d4cbddceb435e13d81601755714e9fSE Android
333255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_user_create(handle, &new_user) < 0)
334255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
335255e72915d4cbddceb435e13d81601755714e9fSE Android
336255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_user_set_name(handle, new_user, user->name) < 0)
337255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
338255e72915d4cbddceb435e13d81601755714e9fSE Android
339255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++) {
340255e72915d4cbddceb435e13d81601755714e9fSE Android		if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0)
341255e72915d4cbddceb435e13d81601755714e9fSE Android			goto err;
342255e72915d4cbddceb435e13d81601755714e9fSE Android	}
343255e72915d4cbddceb435e13d81601755714e9fSE Android
344255e72915d4cbddceb435e13d81601755714e9fSE Android	if (user->mls_level &&
345255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0))
346255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
347255e72915d4cbddceb435e13d81601755714e9fSE Android
348255e72915d4cbddceb435e13d81601755714e9fSE Android	if (user->mls_range &&
349255e72915d4cbddceb435e13d81601755714e9fSE Android	    (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0))
350255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
351255e72915d4cbddceb435e13d81601755714e9fSE Android
352255e72915d4cbddceb435e13d81601755714e9fSE Android	*user_ptr = new_user;
353255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
354255e72915d4cbddceb435e13d81601755714e9fSE Android
355255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
356255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not clone selinux user record");
357255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_user_free(new_user);
358255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
359255e72915d4cbddceb435e13d81601755714e9fSE Android}
360255e72915d4cbddceb435e13d81601755714e9fSE Android
361255e72915d4cbddceb435e13d81601755714e9fSE Android/* Destroy */
362255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_user_free(sepol_user_t * user)
363255e72915d4cbddceb435e13d81601755714e9fSE Android{
364255e72915d4cbddceb435e13d81601755714e9fSE Android
365255e72915d4cbddceb435e13d81601755714e9fSE Android	unsigned int i;
366255e72915d4cbddceb435e13d81601755714e9fSE Android
367255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!user)
368255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
369255e72915d4cbddceb435e13d81601755714e9fSE Android
370255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->name);
371255e72915d4cbddceb435e13d81601755714e9fSE Android	for (i = 0; i < user->num_roles; i++)
372255e72915d4cbddceb435e13d81601755714e9fSE Android		free(user->roles[i]);
373255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->roles);
374255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->mls_level);
375255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user->mls_range);
376255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user);
377255e72915d4cbddceb435e13d81601755714e9fSE Android}
378255e72915d4cbddceb435e13d81601755714e9fSE Android
379255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_user_free)
380