1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 /* Object: semanage_user_extra_t (SELinux User/Class Extra Data)
4  * Object: semanage_user_extra_key_t (SELinux User/Class Key)
5  * Implements: record_t (Database Record)
6  * Implements: record_key_t (Database Record Key)
7  */
8 
9 #include <sepol/user_record.h>
10 
11 typedef sepol_user_key_t semanage_user_key_t;
12 #define _SEMANAGE_USER_KEY_DEFINED_
13 
14 struct semanage_user_extra;
15 typedef struct semanage_user_extra record_t;
16 typedef semanage_user_key_t record_key_t;
17 #define DBASE_RECORD_DEFINED
18 
19 #include <semanage/handle.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "user_internal.h"
23 #include "debug.h"
24 #include "database.h"
25 
26 struct semanage_user_extra {
27 	/* This user's name */
28 	char *name;
29 
30 	/* Labeling prefix */
31 	char *prefix;
32 };
33 
semanage_user_extra_key_extract(semanage_handle_t * handle,const semanage_user_extra_t * user_extra,semanage_user_key_t ** key_ptr)34 static int semanage_user_extra_key_extract(semanage_handle_t * handle,
35 					   const semanage_user_extra_t *
36 					   user_extra,
37 					   semanage_user_key_t ** key_ptr)
38 {
39 
40 	if (semanage_user_key_create(handle, user_extra->name, key_ptr) < 0)
41 		goto err;
42 
43 	return STATUS_SUCCESS;
44 
45       err:
46 	ERR(handle, "could not extract key from user extra record");
47 	return STATUS_ERR;
48 }
49 
semanage_user_extra_compare(const semanage_user_extra_t * user_extra,const semanage_user_key_t * key)50 static int semanage_user_extra_compare(const semanage_user_extra_t * user_extra,
51 				       const semanage_user_key_t * key)
52 {
53 
54 	const char *name;
55 	semanage_user_key_unpack(key, &name);
56 
57 	return strcmp(user_extra->name, name);
58 }
59 
semanage_user_extra_compare2(const semanage_user_extra_t * user_extra,const semanage_user_extra_t * user_extra2)60 static int semanage_user_extra_compare2(const semanage_user_extra_t *
61 					user_extra,
62 					const semanage_user_extra_t *
63 					user_extra2)
64 {
65 
66 	return strcmp(user_extra->name, user_extra2->name);
67 }
68 
semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** user_extra,const semanage_user_extra_t ** user_extra2)69 static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t **
70 					      user_extra,
71 					      const semanage_user_extra_t **
72 					      user_extra2)
73 {
74 
75 	return strcmp((*user_extra)->name, (*user_extra2)->name);
76 }
77 
78 /* Name */
semanage_user_extra_get_name(const semanage_user_extra_t * user_extra)79 hidden const char *semanage_user_extra_get_name(const semanage_user_extra_t *
80 						user_extra)
81 {
82 
83 	return user_extra->name;
84 }
85 
semanage_user_extra_set_name(semanage_handle_t * handle,semanage_user_extra_t * user_extra,const char * name)86 hidden int semanage_user_extra_set_name(semanage_handle_t * handle,
87 					semanage_user_extra_t * user_extra,
88 					const char *name)
89 {
90 
91 	char *tmp_name = strdup(name);
92 	if (!tmp_name) {
93 		ERR(handle, "out of memory, could not set name %s "
94 		    "for user extra data", name);
95 		return STATUS_ERR;
96 	}
97 	free(user_extra->name);
98 	user_extra->name = tmp_name;
99 	return STATUS_SUCCESS;
100 }
101 
102 /* Labeling prefix */
semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra)103 hidden const char *semanage_user_extra_get_prefix(const semanage_user_extra_t *
104 						  user_extra)
105 {
106 
107 	return user_extra->prefix;
108 }
109 
semanage_user_extra_set_prefix(semanage_handle_t * handle,semanage_user_extra_t * user_extra,const char * prefix)110 hidden int semanage_user_extra_set_prefix(semanage_handle_t * handle,
111 					  semanage_user_extra_t * user_extra,
112 					  const char *prefix)
113 {
114 
115 	char *tmp_prefix = strdup(prefix);
116 	if (!tmp_prefix) {
117 		ERR(handle, "out of memory, could not set prefix %s "
118 		    "for user %s", prefix, user_extra->name);
119 		return STATUS_ERR;
120 	}
121 	free(user_extra->prefix);
122 	user_extra->prefix = tmp_prefix;
123 	return STATUS_SUCCESS;
124 }
125 
126 /* Create */
semanage_user_extra_create(semanage_handle_t * handle,semanage_user_extra_t ** user_extra_ptr)127 hidden int semanage_user_extra_create(semanage_handle_t * handle,
128 				      semanage_user_extra_t ** user_extra_ptr)
129 {
130 
131 	semanage_user_extra_t *user_extra =
132 	    (semanage_user_extra_t *) malloc(sizeof(semanage_user_extra_t));
133 
134 	if (!user_extra) {
135 		ERR(handle, "out of memory, could not "
136 		    "create user extra data record");
137 		return STATUS_ERR;
138 	}
139 
140 	user_extra->name = NULL;
141 	user_extra->prefix = NULL;
142 
143 	*user_extra_ptr = user_extra;
144 	return STATUS_SUCCESS;
145 }
146 
147 /* Destroy */
semanage_user_extra_free(semanage_user_extra_t * user_extra)148 hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra)
149 {
150 
151 	if (!user_extra)
152 		return;
153 
154 	free(user_extra->name);
155 	free(user_extra->prefix);
156 	free(user_extra);
157 }
158 
159 /* Deep copy clone */
semanage_user_extra_clone(semanage_handle_t * handle,const semanage_user_extra_t * user_extra,semanage_user_extra_t ** user_extra_ptr)160 hidden int semanage_user_extra_clone(semanage_handle_t * handle,
161 				     const semanage_user_extra_t * user_extra,
162 				     semanage_user_extra_t ** user_extra_ptr)
163 {
164 
165 	semanage_user_extra_t *new_user_extra = NULL;
166 
167 	if (semanage_user_extra_create(handle, &new_user_extra) < 0)
168 		goto err;
169 
170 	if (semanage_user_extra_set_name
171 	    (handle, new_user_extra, user_extra->name) < 0)
172 		goto err;
173 
174 	if (semanage_user_extra_set_prefix
175 	    (handle, new_user_extra, user_extra->prefix) < 0)
176 		goto err;
177 
178 	*user_extra_ptr = new_user_extra;
179 	return STATUS_SUCCESS;
180 
181       err:
182 	ERR(handle, "could not clone extra data for user %s", user_extra->name);
183 	semanage_user_extra_free(new_user_extra);
184 	return STATUS_ERR;
185 }
186 
187 /* Record base functions */
188 record_table_t SEMANAGE_USER_EXTRA_RTABLE = {
189 	.create = semanage_user_extra_create,
190 	.key_extract = semanage_user_extra_key_extract,
191 	.key_free = semanage_user_key_free,
192 	.clone = semanage_user_extra_clone,
193 	.compare = semanage_user_extra_compare,
194 	.compare2 = semanage_user_extra_compare2,
195 	.compare2_qsort = semanage_user_extra_compare2_qsort,
196 	.free = semanage_user_extra_free,
197 };
198