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