]> git.proxmox.com Git - mirror_qemu.git/blame - authz/list.c
docs/migration: Convert virtio.txt into rST
[mirror_qemu.git] / authz / list.c
CommitLineData
c8c99887
DB
1/*
2 * QEMU access control list authorization driver
3 *
4 * Copyright (c) 2018 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
036a80cd 9 * version 2.1 of the License, or (at your option) any later version.
c8c99887
DB
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include "qemu/osdep.h"
22#include "authz/list.h"
45b1f68c 23#include "trace.h"
c8c99887
DB
24#include "qom/object_interfaces.h"
25#include "qapi/qapi-visit-authz.h"
0b8fa32f 26#include "qemu/module.h"
c8c99887
DB
27
28static bool qauthz_list_is_allowed(QAuthZ *authz,
29 const char *identity,
30 Error **errp)
31{
32 QAuthZList *lauthz = QAUTHZ_LIST(authz);
33 QAuthZListRuleList *rules = lauthz->rules;
34
35 while (rules) {
36 QAuthZListRule *rule = rules->value;
37 QAuthZListFormat format = rule->has_format ? rule->format :
38 QAUTHZ_LIST_FORMAT_EXACT;
39
40 trace_qauthz_list_check_rule(authz, rule->match, identity,
41 format, rule->policy);
42 switch (format) {
43 case QAUTHZ_LIST_FORMAT_EXACT:
44 if (g_str_equal(rule->match, identity)) {
45 return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
46 }
47 break;
48 case QAUTHZ_LIST_FORMAT_GLOB:
49 if (g_pattern_match_simple(rule->match, identity)) {
50 return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
51 }
52 break;
53 default:
54 g_warn_if_reached();
55 return false;
56 }
57 rules = rules->next;
58 }
59
60 trace_qauthz_list_default_policy(authz, identity, lauthz->policy);
61 return lauthz->policy == QAUTHZ_LIST_POLICY_ALLOW;
62}
63
64
65static void
66qauthz_list_prop_set_policy(Object *obj,
67 int value,
68 Error **errp G_GNUC_UNUSED)
69{
70 QAuthZList *lauthz = QAUTHZ_LIST(obj);
71
72 lauthz->policy = value;
73}
74
75
76static int
77qauthz_list_prop_get_policy(Object *obj,
78 Error **errp G_GNUC_UNUSED)
79{
80 QAuthZList *lauthz = QAUTHZ_LIST(obj);
81
82 return lauthz->policy;
83}
84
85
86static void
87qauthz_list_prop_get_rules(Object *obj, Visitor *v, const char *name,
88 void *opaque, Error **errp)
89{
90 QAuthZList *lauthz = QAUTHZ_LIST(obj);
91
92 visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
93}
94
95static void
96qauthz_list_prop_set_rules(Object *obj, Visitor *v, const char *name,
97 void *opaque, Error **errp)
98{
99 QAuthZList *lauthz = QAUTHZ_LIST(obj);
100 QAuthZListRuleList *oldrules;
101
102 oldrules = lauthz->rules;
103 visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
104
105 qapi_free_QAuthZListRuleList(oldrules);
106}
107
108
109static void
110qauthz_list_finalize(Object *obj)
111{
112 QAuthZList *lauthz = QAUTHZ_LIST(obj);
113
114 qapi_free_QAuthZListRuleList(lauthz->rules);
115}
116
117
118static void
119qauthz_list_class_init(ObjectClass *oc, void *data)
120{
121 QAuthZClass *authz = QAUTHZ_CLASS(oc);
122
123 object_class_property_add_enum(oc, "policy",
124 "QAuthZListPolicy",
125 &QAuthZListPolicy_lookup,
126 qauthz_list_prop_get_policy,
d2623129 127 qauthz_list_prop_set_policy);
c8c99887
DB
128
129 object_class_property_add(oc, "rules", "QAuthZListRule",
130 qauthz_list_prop_get_rules,
131 qauthz_list_prop_set_rules,
d2623129 132 NULL, NULL);
c8c99887
DB
133
134 authz->is_allowed = qauthz_list_is_allowed;
135}
136
137
138QAuthZList *qauthz_list_new(const char *id,
139 QAuthZListPolicy policy,
140 Error **errp)
141{
142 return QAUTHZ_LIST(
143 object_new_with_props(TYPE_QAUTHZ_LIST,
144 object_get_objects_root(),
145 id, errp,
146 "policy", QAuthZListPolicy_str(policy),
147 NULL));
148}
149
150ssize_t qauthz_list_append_rule(QAuthZList *auth,
151 const char *match,
152 QAuthZListPolicy policy,
153 QAuthZListFormat format,
154 Error **errp)
155{
156 QAuthZListRule *rule;
157 QAuthZListRuleList *rules, *tmp;
158 size_t i = 0;
159
160 rule = g_new0(QAuthZListRule, 1);
161 rule->policy = policy;
162 rule->match = g_strdup(match);
163 rule->format = format;
164 rule->has_format = true;
165
166 tmp = g_new0(QAuthZListRuleList, 1);
167 tmp->value = rule;
168
169 rules = auth->rules;
170 if (rules) {
171 while (rules->next) {
172 i++;
173 rules = rules->next;
174 }
175 rules->next = tmp;
176 return i + 1;
177 } else {
178 auth->rules = tmp;
179 return 0;
180 }
181}
182
183
184ssize_t qauthz_list_insert_rule(QAuthZList *auth,
185 const char *match,
186 QAuthZListPolicy policy,
187 QAuthZListFormat format,
188 size_t index,
189 Error **errp)
190{
191 QAuthZListRule *rule;
192 QAuthZListRuleList *rules, *tmp;
193 size_t i = 0;
194
195 rule = g_new0(QAuthZListRule, 1);
196 rule->policy = policy;
197 rule->match = g_strdup(match);
198 rule->format = format;
199 rule->has_format = true;
200
201 tmp = g_new0(QAuthZListRuleList, 1);
202 tmp->value = rule;
203
204 rules = auth->rules;
205 if (rules && index > 0) {
206 while (rules->next && i < (index - 1)) {
207 i++;
208 rules = rules->next;
209 }
210 tmp->next = rules->next;
211 rules->next = tmp;
212 return i + 1;
213 } else {
214 tmp->next = auth->rules;
215 auth->rules = tmp;
216 return 0;
217 }
218}
219
220
221ssize_t qauthz_list_delete_rule(QAuthZList *auth, const char *match)
222{
223 QAuthZListRule *rule;
224 QAuthZListRuleList *rules, *prev;
225 size_t i = 0;
226
227 prev = NULL;
228 rules = auth->rules;
229 while (rules) {
230 rule = rules->value;
231 if (g_str_equal(rule->match, match)) {
232 if (prev) {
233 prev->next = rules->next;
234 } else {
235 auth->rules = rules->next;
236 }
237 rules->next = NULL;
238 qapi_free_QAuthZListRuleList(rules);
239 return i;
240 }
241 prev = rules;
242 rules = rules->next;
243 i++;
244 }
245
246 return -1;
247}
248
249
250static const TypeInfo qauthz_list_info = {
251 .parent = TYPE_QAUTHZ,
252 .name = TYPE_QAUTHZ_LIST,
253 .instance_size = sizeof(QAuthZList),
254 .instance_finalize = qauthz_list_finalize,
c8c99887
DB
255 .class_init = qauthz_list_class_init,
256 .interfaces = (InterfaceInfo[]) {
257 { TYPE_USER_CREATABLE },
258 { }
259 }
260};
261
262
263static void
264qauthz_list_register_types(void)
265{
266 type_register_static(&qauthz_list_info);
267}
268
269
270type_init(qauthz_list_register_types);