/*
 * QEMU PAM authorization driver
 *
 * Copyright (c) 2018 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "authz/pamacct.h"
#include "trace.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"

#include <security/pam_appl.h>


static bool qauthz_pam_is_allowed(QAuthZ *authz,
                                  const char *identity,
                                  Error **errp)
{
    QAuthZPAM *pauthz = QAUTHZ_PAM(authz);
    const struct pam_conv pam_conversation = { 0 };
    pam_handle_t *pamh = NULL;
    int ret;

    trace_qauthz_pam_check(authz, identity, pauthz->service);
    ret = pam_start(pauthz->service,
                    identity,
                    &pam_conversation,
                    &pamh);
    if (ret != PAM_SUCCESS) {
        error_setg(errp, "Unable to start PAM transaction: %s",
                   pam_strerror(NULL, ret));
        return false;
    }

    ret = pam_acct_mgmt(pamh, PAM_SILENT);
    pam_end(pamh, ret);
    if (ret != PAM_SUCCESS) {
        error_setg(errp, "Unable to authorize user '%s': %s",
                   identity, pam_strerror(pamh, ret));
        return false;
    }

    return true;
}


static void
qauthz_pam_prop_set_service(Object *obj,
                            const char *service,
                            Error **errp G_GNUC_UNUSED)
{
    QAuthZPAM *pauthz = QAUTHZ_PAM(obj);

    g_free(pauthz->service);
    pauthz->service = g_strdup(service);
}


static char *
qauthz_pam_prop_get_service(Object *obj,
                            Error **errp G_GNUC_UNUSED)
{
    QAuthZPAM *pauthz = QAUTHZ_PAM(obj);

    return g_strdup(pauthz->service);
}


static void
qauthz_pam_complete(UserCreatable *uc, Error **errp)
{
    QAuthZPAM *pauthz = QAUTHZ_PAM(uc);

    if (!pauthz->service) {
        error_setg(errp, "The 'service' property must be set");
        return;
    }
}


static void
qauthz_pam_finalize(Object *obj)
{
    QAuthZPAM *pauthz = QAUTHZ_PAM(obj);

    g_free(pauthz->service);
}


static void
qauthz_pam_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    QAuthZClass *authz = QAUTHZ_CLASS(oc);

    ucc->complete = qauthz_pam_complete;
    authz->is_allowed = qauthz_pam_is_allowed;

    object_class_property_add_str(oc, "service",
                                  qauthz_pam_prop_get_service,
                                  qauthz_pam_prop_set_service);
}


QAuthZPAM *qauthz_pam_new(const char *id,
                          const char *service,
                          Error **errp)
{
    return QAUTHZ_PAM(
        object_new_with_props(TYPE_QAUTHZ_PAM,
                              object_get_objects_root(),
                              id, errp,
                              "service", service,
                              NULL));
}


static const TypeInfo qauthz_pam_info = {
    .parent = TYPE_QAUTHZ,
    .name = TYPE_QAUTHZ_PAM,
    .instance_size = sizeof(QAuthZPAM),
    .instance_finalize = qauthz_pam_finalize,
    .class_init = qauthz_pam_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};


static void
qauthz_pam_register_types(void)
{
    type_register_static(&qauthz_pam_info);
}


type_init(qauthz_pam_register_types);
