qapi: Split error.json off common.json
[qemu/kevin.git] / authz / list.c
blob5a48074d0aaea3bd98ab5ea9c8a91c143221a73e
1 /*
2 * QEMU access control list authorization driver
4 * Copyright (c) 2018 Red Hat, Inc.
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
9 * version 2 of the License, or (at your option) any later version.
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.
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/>.
21 #include "qemu/osdep.h"
22 #include "authz/list.h"
23 #include "trace.h"
24 #include "qom/object_interfaces.h"
25 #include "qapi/qapi-visit-authz.h"
26 #include "qemu/module.h"
28 static bool qauthz_list_is_allowed(QAuthZ *authz,
29 const char *identity,
30 Error **errp)
32 QAuthZList *lauthz = QAUTHZ_LIST(authz);
33 QAuthZListRuleList *rules = lauthz->rules;
35 while (rules) {
36 QAuthZListRule *rule = rules->value;
37 QAuthZListFormat format = rule->has_format ? rule->format :
38 QAUTHZ_LIST_FORMAT_EXACT;
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;
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;
52 break;
53 default:
54 g_warn_if_reached();
55 return false;
57 rules = rules->next;
60 trace_qauthz_list_default_policy(authz, identity, lauthz->policy);
61 return lauthz->policy == QAUTHZ_LIST_POLICY_ALLOW;
65 static void
66 qauthz_list_prop_set_policy(Object *obj,
67 int value,
68 Error **errp G_GNUC_UNUSED)
70 QAuthZList *lauthz = QAUTHZ_LIST(obj);
72 lauthz->policy = value;
76 static int
77 qauthz_list_prop_get_policy(Object *obj,
78 Error **errp G_GNUC_UNUSED)
80 QAuthZList *lauthz = QAUTHZ_LIST(obj);
82 return lauthz->policy;
86 static void
87 qauthz_list_prop_get_rules(Object *obj, Visitor *v, const char *name,
88 void *opaque, Error **errp)
90 QAuthZList *lauthz = QAUTHZ_LIST(obj);
92 visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
95 static void
96 qauthz_list_prop_set_rules(Object *obj, Visitor *v, const char *name,
97 void *opaque, Error **errp)
99 QAuthZList *lauthz = QAUTHZ_LIST(obj);
100 QAuthZListRuleList *oldrules;
102 oldrules = lauthz->rules;
103 visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
105 qapi_free_QAuthZListRuleList(oldrules);
109 static void
110 qauthz_list_finalize(Object *obj)
112 QAuthZList *lauthz = QAUTHZ_LIST(obj);
114 qapi_free_QAuthZListRuleList(lauthz->rules);
118 static void
119 qauthz_list_class_init(ObjectClass *oc, void *data)
121 QAuthZClass *authz = QAUTHZ_CLASS(oc);
123 object_class_property_add_enum(oc, "policy",
124 "QAuthZListPolicy",
125 &QAuthZListPolicy_lookup,
126 qauthz_list_prop_get_policy,
127 qauthz_list_prop_set_policy,
128 NULL);
130 object_class_property_add(oc, "rules", "QAuthZListRule",
131 qauthz_list_prop_get_rules,
132 qauthz_list_prop_set_rules,
133 NULL, NULL, NULL);
135 authz->is_allowed = qauthz_list_is_allowed;
139 QAuthZList *qauthz_list_new(const char *id,
140 QAuthZListPolicy policy,
141 Error **errp)
143 return QAUTHZ_LIST(
144 object_new_with_props(TYPE_QAUTHZ_LIST,
145 object_get_objects_root(),
146 id, errp,
147 "policy", QAuthZListPolicy_str(policy),
148 NULL));
151 ssize_t qauthz_list_append_rule(QAuthZList *auth,
152 const char *match,
153 QAuthZListPolicy policy,
154 QAuthZListFormat format,
155 Error **errp)
157 QAuthZListRule *rule;
158 QAuthZListRuleList *rules, *tmp;
159 size_t i = 0;
161 rule = g_new0(QAuthZListRule, 1);
162 rule->policy = policy;
163 rule->match = g_strdup(match);
164 rule->format = format;
165 rule->has_format = true;
167 tmp = g_new0(QAuthZListRuleList, 1);
168 tmp->value = rule;
170 rules = auth->rules;
171 if (rules) {
172 while (rules->next) {
173 i++;
174 rules = rules->next;
176 rules->next = tmp;
177 return i + 1;
178 } else {
179 auth->rules = tmp;
180 return 0;
185 ssize_t qauthz_list_insert_rule(QAuthZList *auth,
186 const char *match,
187 QAuthZListPolicy policy,
188 QAuthZListFormat format,
189 size_t index,
190 Error **errp)
192 QAuthZListRule *rule;
193 QAuthZListRuleList *rules, *tmp;
194 size_t i = 0;
196 rule = g_new0(QAuthZListRule, 1);
197 rule->policy = policy;
198 rule->match = g_strdup(match);
199 rule->format = format;
200 rule->has_format = true;
202 tmp = g_new0(QAuthZListRuleList, 1);
203 tmp->value = rule;
205 rules = auth->rules;
206 if (rules && index > 0) {
207 while (rules->next && i < (index - 1)) {
208 i++;
209 rules = rules->next;
211 tmp->next = rules->next;
212 rules->next = tmp;
213 return i + 1;
214 } else {
215 tmp->next = auth->rules;
216 auth->rules = tmp;
217 return 0;
222 ssize_t qauthz_list_delete_rule(QAuthZList *auth, const char *match)
224 QAuthZListRule *rule;
225 QAuthZListRuleList *rules, *prev;
226 size_t i = 0;
228 prev = NULL;
229 rules = auth->rules;
230 while (rules) {
231 rule = rules->value;
232 if (g_str_equal(rule->match, match)) {
233 if (prev) {
234 prev->next = rules->next;
235 } else {
236 auth->rules = rules->next;
238 rules->next = NULL;
239 qapi_free_QAuthZListRuleList(rules);
240 return i;
242 prev = rules;
243 rules = rules->next;
244 i++;
247 return -1;
251 static const TypeInfo qauthz_list_info = {
252 .parent = TYPE_QAUTHZ,
253 .name = TYPE_QAUTHZ_LIST,
254 .instance_size = sizeof(QAuthZList),
255 .instance_finalize = qauthz_list_finalize,
256 .class_size = sizeof(QAuthZListClass),
257 .class_init = qauthz_list_class_init,
258 .interfaces = (InterfaceInfo[]) {
259 { TYPE_USER_CREATABLE },
265 static void
266 qauthz_list_register_types(void)
268 type_register_static(&qauthz_list_info);
272 type_init(qauthz_list_register_types);