qemu

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

pamacct.c (3937B)


      1 /*
      2  * QEMU PAM 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/pamacct.h"
     23 #include "trace.h"
     24 #include "qemu/module.h"
     25 #include "qom/object_interfaces.h"
     26 
     27 #include <security/pam_appl.h>
     28 
     29 
     30 static bool qauthz_pam_is_allowed(QAuthZ *authz,
     31                                   const char *identity,
     32                                   Error **errp)
     33 {
     34     QAuthZPAM *pauthz = QAUTHZ_PAM(authz);
     35     const struct pam_conv pam_conversation = { 0 };
     36     pam_handle_t *pamh = NULL;
     37     int ret;
     38 
     39     trace_qauthz_pam_check(authz, identity, pauthz->service);
     40     ret = pam_start(pauthz->service,
     41                     identity,
     42                     &pam_conversation,
     43                     &pamh);
     44     if (ret != PAM_SUCCESS) {
     45         error_setg(errp, "Unable to start PAM transaction: %s",
     46                    pam_strerror(NULL, ret));
     47         return false;
     48     }
     49 
     50     ret = pam_acct_mgmt(pamh, PAM_SILENT);
     51     pam_end(pamh, ret);
     52     if (ret != PAM_SUCCESS) {
     53         error_setg(errp, "Unable to authorize user '%s': %s",
     54                    identity, pam_strerror(pamh, ret));
     55         return false;
     56     }
     57 
     58     return true;
     59 }
     60 
     61 
     62 static void
     63 qauthz_pam_prop_set_service(Object *obj,
     64                             const char *service,
     65                             Error **errp G_GNUC_UNUSED)
     66 {
     67     QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
     68 
     69     g_free(pauthz->service);
     70     pauthz->service = g_strdup(service);
     71 }
     72 
     73 
     74 static char *
     75 qauthz_pam_prop_get_service(Object *obj,
     76                             Error **errp G_GNUC_UNUSED)
     77 {
     78     QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
     79 
     80     return g_strdup(pauthz->service);
     81 }
     82 
     83 
     84 static void
     85 qauthz_pam_complete(UserCreatable *uc, Error **errp)
     86 {
     87     QAuthZPAM *pauthz = QAUTHZ_PAM(uc);
     88 
     89     if (!pauthz->service) {
     90         error_setg(errp, "The 'service' property must be set");
     91         return;
     92     }
     93 }
     94 
     95 
     96 static void
     97 qauthz_pam_finalize(Object *obj)
     98 {
     99     QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
    100 
    101     g_free(pauthz->service);
    102 }
    103 
    104 
    105 static void
    106 qauthz_pam_class_init(ObjectClass *oc, void *data)
    107 {
    108     UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    109     QAuthZClass *authz = QAUTHZ_CLASS(oc);
    110 
    111     ucc->complete = qauthz_pam_complete;
    112     authz->is_allowed = qauthz_pam_is_allowed;
    113 
    114     object_class_property_add_str(oc, "service",
    115                                   qauthz_pam_prop_get_service,
    116                                   qauthz_pam_prop_set_service);
    117 }
    118 
    119 
    120 QAuthZPAM *qauthz_pam_new(const char *id,
    121                           const char *service,
    122                           Error **errp)
    123 {
    124     return QAUTHZ_PAM(
    125         object_new_with_props(TYPE_QAUTHZ_PAM,
    126                               object_get_objects_root(),
    127                               id, errp,
    128                               "service", service,
    129                               NULL));
    130 }
    131 
    132 
    133 static const TypeInfo qauthz_pam_info = {
    134     .parent = TYPE_QAUTHZ,
    135     .name = TYPE_QAUTHZ_PAM,
    136     .instance_size = sizeof(QAuthZPAM),
    137     .instance_finalize = qauthz_pam_finalize,
    138     .class_init = qauthz_pam_class_init,
    139     .interfaces = (InterfaceInfo[]) {
    140         { TYPE_USER_CREATABLE },
    141         { }
    142     }
    143 };
    144 
    145 
    146 static void
    147 qauthz_pam_register_types(void)
    148 {
    149     type_register_static(&qauthz_pam_info);
    150 }
    151 
    152 
    153 type_init(qauthz_pam_register_types);