1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 /* Object: semanage_seuser_t (Unix User)
4  * Object: semanage_seuser_key_t (Unix User Key)
5  * Implements: record_t (Database Record)
6  * Implements: record_key_t (Database Record Key)
7  */
8 
9 struct semanage_seuser;
10 struct semanage_seuser_key;
11 typedef struct semanage_seuser record_t;
12 typedef struct semanage_seuser_key record_key_t;
13 #define DBASE_RECORD_DEFINED
14 
15 #include <stdlib.h>
16 #include <string.h>
17 #include "seuser_internal.h"
18 #include "debug.h"
19 #include <semanage/handle.h>
20 #include "database.h"
21 
22 struct semanage_seuser {
23 	/* This user's name */
24 	char *name;
25 
26 	/* This user's corresponding
27 	 * seuser ("role set") */
28 	char *sename;
29 
30 	/* This user's mls range (only required for mls) */
31 	char *mls_range;
32 };
33 
34 struct semanage_seuser_key {
35 	/* This user's name */
36 	const char *name;
37 };
38 
semanage_seuser_key_create(semanage_handle_t * handle,const char * name,semanage_seuser_key_t ** key_ptr)39 int semanage_seuser_key_create(semanage_handle_t * handle,
40 			       const char *name,
41 			       semanage_seuser_key_t ** key_ptr)
42 {
43 
44 	semanage_seuser_key_t *tmp_key = (semanage_seuser_key_t *)
45 	    malloc(sizeof(semanage_seuser_key_t));
46 
47 	if (!tmp_key) {
48 		ERR(handle, "out of memory, could not create seuser key");
49 		return STATUS_ERR;
50 	}
51 	tmp_key->name = name;
52 
53 	*key_ptr = tmp_key;
54 	return STATUS_SUCCESS;
55 }
56 
hidden_def(semanage_seuser_key_create)57 hidden_def(semanage_seuser_key_create)
58 
59 int semanage_seuser_key_extract(semanage_handle_t * handle,
60 				const semanage_seuser_t * seuser,
61 				semanage_seuser_key_t ** key_ptr)
62 {
63 
64 	if (semanage_seuser_key_create(handle, seuser->name, key_ptr) < 0)
65 		goto err;
66 
67 	return STATUS_SUCCESS;
68 
69       err:
70 	ERR(handle, "could not extract seuser key from record");
71 	return STATUS_ERR;
72 }
73 
hidden_def(semanage_seuser_key_extract)74 hidden_def(semanage_seuser_key_extract)
75 
76 void semanage_seuser_key_free(semanage_seuser_key_t * key)
77 {
78 
79 	free(key);
80 }
81 
hidden_def(semanage_seuser_key_free)82 hidden_def(semanage_seuser_key_free)
83 
84 int semanage_seuser_compare(const semanage_seuser_t * seuser,
85 			    const semanage_seuser_key_t * key)
86 {
87 
88 	return strcmp(seuser->name, key->name);
89 }
90 
hidden_def(semanage_seuser_compare)91 hidden_def(semanage_seuser_compare)
92 
93 int semanage_seuser_compare2(const semanage_seuser_t * seuser,
94 			     const semanage_seuser_t * seuser2)
95 {
96 
97 	return strcmp(seuser->name, seuser2->name);
98 }
99 
hidden_def(semanage_seuser_compare2)100 hidden_def(semanage_seuser_compare2)
101 
102 static int semanage_seuser_compare2_qsort(const semanage_seuser_t ** seuser,
103 					  const semanage_seuser_t ** seuser2)
104 {
105 
106 	return strcmp((*seuser)->name, (*seuser2)->name);
107 }
108 
109 /* Name */
semanage_seuser_get_name(const semanage_seuser_t * seuser)110 const char *semanage_seuser_get_name(const semanage_seuser_t * seuser)
111 {
112 
113 	return seuser->name;
114 }
115 
hidden_def(semanage_seuser_get_name)116 hidden_def(semanage_seuser_get_name)
117 
118 int semanage_seuser_set_name(semanage_handle_t * handle,
119 			     semanage_seuser_t * seuser, const char *name)
120 {
121 
122 	char *tmp_name = strdup(name);
123 	if (!tmp_name) {
124 		ERR(handle, "out of memory, could not set seuser (Unix) name");
125 		return STATUS_ERR;
126 	}
127 	free(seuser->name);
128 	seuser->name = tmp_name;
129 	return STATUS_SUCCESS;
130 }
131 
hidden_def(semanage_seuser_set_name)132 hidden_def(semanage_seuser_set_name)
133 
134 /* Selinux Name */
135 const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser)
136 {
137 
138 	return seuser->sename;
139 }
140 
hidden_def(semanage_seuser_get_sename)141 hidden_def(semanage_seuser_get_sename)
142 
143 int semanage_seuser_set_sename(semanage_handle_t * handle,
144 			       semanage_seuser_t * seuser, const char *sename)
145 {
146 
147 	char *tmp_sename = strdup(sename);
148 	if (!tmp_sename) {
149 		ERR(handle,
150 		    "out of memory, could not set seuser (SELinux) name");
151 		return STATUS_ERR;
152 	}
153 	free(seuser->sename);
154 	seuser->sename = tmp_sename;
155 	return STATUS_SUCCESS;
156 }
157 
hidden_def(semanage_seuser_set_sename)158 hidden_def(semanage_seuser_set_sename)
159 
160 /* MLS Range */
161 const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser)
162 {
163 
164 	return seuser->mls_range;
165 }
166 
hidden_def(semanage_seuser_get_mlsrange)167 hidden_def(semanage_seuser_get_mlsrange)
168 
169 int semanage_seuser_set_mlsrange(semanage_handle_t * handle,
170 				 semanage_seuser_t * seuser,
171 				 const char *mls_range)
172 {
173 
174 	char *tmp_mls_range = strdup(mls_range);
175 	if (!tmp_mls_range) {
176 		ERR(handle, "out of memory, could not set seuser MLS range");
177 		return STATUS_ERR;
178 	}
179 	free(seuser->mls_range);
180 	seuser->mls_range = tmp_mls_range;
181 	return STATUS_SUCCESS;
182 }
183 
hidden_def(semanage_seuser_set_mlsrange)184 hidden_def(semanage_seuser_set_mlsrange)
185 
186 /* Create */
187 int semanage_seuser_create(semanage_handle_t * handle,
188 			   semanage_seuser_t ** seuser_ptr)
189 {
190 
191 	semanage_seuser_t *seuser =
192 	    (semanage_seuser_t *) malloc(sizeof(semanage_seuser_t));
193 
194 	if (!seuser) {
195 		ERR(handle, "out of memory, could not create seuser");
196 		return STATUS_ERR;
197 	}
198 
199 	seuser->name = NULL;
200 	seuser->sename = NULL;
201 	seuser->mls_range = NULL;
202 
203 	*seuser_ptr = seuser;
204 	return STATUS_SUCCESS;
205 }
206 
hidden_def(semanage_seuser_create)207 hidden_def(semanage_seuser_create)
208 
209 /* Deep copy clone */
210 int semanage_seuser_clone(semanage_handle_t * handle,
211 			  const semanage_seuser_t * seuser,
212 			  semanage_seuser_t ** seuser_ptr)
213 {
214 
215 	semanage_seuser_t *new_seuser = NULL;
216 
217 	if (semanage_seuser_create(handle, &new_seuser) < 0)
218 		goto err;
219 
220 	if (semanage_seuser_set_name(handle, new_seuser, seuser->name) < 0)
221 		goto err;
222 
223 	if (semanage_seuser_set_sename(handle, new_seuser, seuser->sename) < 0)
224 		goto err;
225 
226 	if (seuser->mls_range &&
227 	    (semanage_seuser_set_mlsrange(handle, new_seuser, seuser->mls_range)
228 	     < 0))
229 		goto err;
230 
231 	*seuser_ptr = new_seuser;
232 	return STATUS_SUCCESS;
233 
234       err:
235 	ERR(handle, "could not clone seuser");
236 	semanage_seuser_free(new_seuser);
237 	return STATUS_ERR;
238 }
239 
hidden_def(semanage_seuser_clone)240 hidden_def(semanage_seuser_clone)
241 
242 /* Destroy */
243 void semanage_seuser_free(semanage_seuser_t * seuser)
244 {
245 
246 	if (!seuser)
247 		return;
248 
249 	free(seuser->name);
250 	free(seuser->sename);
251 	free(seuser->mls_range);
252 	free(seuser);
253 }
254 
255 hidden_def(semanage_seuser_free)
256 
257 /* Record base functions */
258 record_table_t SEMANAGE_SEUSER_RTABLE = {
259 	.create = semanage_seuser_create,
260 	.key_extract = semanage_seuser_key_extract,
261 	.key_free = semanage_seuser_key_free,
262 	.clone = semanage_seuser_clone,
263 	.compare = semanage_seuser_compare,
264 	.compare2 = semanage_seuser_compare2,
265 	.compare2_qsort = semanage_seuser_compare2_qsort,
266 	.free = semanage_seuser_free,
267 };
268