qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

list.c (7296B)


      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
      9  * version 2.1 of the License, or (at your option) any later version.
     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"
     23 #include "trace.h"
     24 #include "qom/object_interfaces.h"
     25 #include "qapi/qapi-visit-authz.h"
     26 #include "qemu/module.h"
     27 
     28 static 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 
     65 static void
     66 qauthz_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 
     76 static int
     77 qauthz_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 
     86 static void
     87 qauthz_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 
     95 static void
     96 qauthz_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 
    109 static void
    110 qauthz_list_finalize(Object *obj)
    111 {
    112     QAuthZList *lauthz = QAUTHZ_LIST(obj);
    113 
    114     qapi_free_QAuthZListRuleList(lauthz->rules);
    115 }
    116 
    117 
    118 static void
    119 qauthz_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,
    127                                    qauthz_list_prop_set_policy);
    128 
    129     object_class_property_add(oc, "rules", "QAuthZListRule",
    130                               qauthz_list_prop_get_rules,
    131                               qauthz_list_prop_set_rules,
    132                               NULL, NULL);
    133 
    134     authz->is_allowed = qauthz_list_is_allowed;
    135 }
    136 
    137 
    138 QAuthZList *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 
    150 ssize_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 
    184 ssize_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 
    221 ssize_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 
    250 static 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,
    255     .class_init = qauthz_list_class_init,
    256     .interfaces = (InterfaceInfo[]) {
    257         { TYPE_USER_CREATABLE },
    258         { }
    259     }
    260 };
    261 
    262 
    263 static void
    264 qauthz_list_register_types(void)
    265 {
    266     type_register_static(&qauthz_list_info);
    267 }
    268 
    269 
    270 type_init(qauthz_list_register_types);