/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Security options etc.
 *
 * Module derived from code originally written by Rob McCool
 *
 */

#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_md5.h"

#define APR_WANT_STRFUNC
#define APR_WANT_BYTEFUNC
#include "apr_want.h"

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"
#include "ap_provider.h"
#include "ap_expr.h"

#include "mod_auth.h"

#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#undef AUTHZ_EXTRA_CONFIGS

typedef struct provider_alias_rec {
    char *provider_name;
    char *provider_alias;
    char *provider_args;
    const void *provider_parsed_args;
    ap_conf_vector_t *sec_auth;
    const authz_provider *provider;
} provider_alias_rec;

typedef enum {
    AUTHZ_LOGIC_AND,
    AUTHZ_LOGIC_OR,
    AUTHZ_LOGIC_OFF,
    AUTHZ_LOGIC_UNSET
} authz_logic_op;

typedef struct authz_section_conf authz_section_conf;

struct authz_section_conf {
    const char *provider_name;
    const char *provider_args;
    const void *provider_parsed_args;
    const authz_provider *provider;
    apr_int64_t limited;
    authz_logic_op op;
    int negate;
    /** true if this is not a real container but produced by AuthMerging;
     *  only used for logging */
    int is_merged;
    authz_section_conf *first;
    authz_section_conf *next;
};

typedef struct authz_core_dir_conf authz_core_dir_conf;

struct authz_core_dir_conf {
    authz_section_conf *section;
    authz_core_dir_conf *next;
    authz_logic_op op;
    signed char authz_forbidden_on_fail;
};

#define UNSET -1

typedef struct authz_core_srv_conf {
    apr_hash_t *alias_rec;
} authz_core_srv_conf;

module AP_MODULE_DECLARE_DATA authz_core_module;

static authz_core_dir_conf *authz_core_first_dir_conf;

static void *create_authz_core_dir_config(apr_pool_t *p, char *dummy)
{
    authz_core_dir_conf *conf = apr_pcalloc(p, sizeof(*conf));

    conf->op = AUTHZ_LOGIC_UNSET;
    conf->authz_forbidden_on_fail = UNSET;

    conf->next = authz_core_first_dir_conf;
    authz_core_first_dir_conf = conf;

    return (void *)conf;
}

static void *merge_authz_core_dir_config(apr_pool_t *p,
                                         void *basev, void *newv)
{
    authz_core_dir_conf *base = (authz_core_dir_conf *)basev;
    authz_core_dir_conf *new = (authz_core_dir_conf *)newv;
    authz_core_dir_conf *conf;

    if (new->op == AUTHZ_LOGIC_UNSET && !new->section && base->section ) {
        /* Only authz_forbidden_on_fail has been set in new. Don't treat
         * it as a new auth config w.r.t. AuthMerging */
        conf = apr_pmemdup(p, base, sizeof(*base));
    }
    else if (new->op == AUTHZ_LOGIC_OFF || new->op == AUTHZ_LOGIC_UNSET ||
             !(base->section || new->section)) {
        conf = apr_pmemdup(p, new, sizeof(*new));
    }
    else {
        authz_section_conf *section;

        if (base->section) {
            if (new->section) {
                section = apr_pcalloc(p, sizeof(*section));

                section->limited =
                    base->section->limited | new->section->limited;

                section->op = new->op;
                section->is_merged = 1;

                section->first = apr_pmemdup(p, base->section,
                                             sizeof(*base->section));
                section->first->next = apr_pmemdup(p, new->section,
                                                   sizeof(*new->section));
            } else {
                section = apr_pmemdup(p, base->section,
                                      sizeof(*base->section));
            }
        }
        else {
            section = apr_pmemdup(p, new->section, sizeof(*new->section));
        }

        conf = apr_pcalloc(p, sizeof(*conf));

        conf->section = section;
        conf->op = new->op;
    }

    if (new->authz_forbidden_on_fail == UNSET)
        conf->authz_forbidden_on_fail = base->authz_forbidden_on_fail;
    else
        conf->authz_forbidden_on_fail = new->authz_forbidden_on_fail;

    return (void*)conf;
}

/* Only per-server directive we have is GLOBAL_ONLY */
static void *merge_authz_core_svr_config(apr_pool_t *p,
                                         void *basev, void *newv)
{
    return basev;
}

static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s)
{
    authz_core_srv_conf *authcfg;

    authcfg = apr_pcalloc(p, sizeof(*authcfg));
    authcfg->alias_rec = apr_hash_make(p);

    return (void *)authcfg;
}

/* This is a fake authz provider that really merges various authz alias
 * configurations and then invokes them.
 */
static authz_status authz_alias_check_authorization(request_rec *r,
                                                    const char *require_args,
                                                    const void *parsed_require_args)
{
    const char *provider_name;
    authz_status ret = AUTHZ_DENIED;

    /* Look up the provider alias in the alias list.
     * Get the dir_config and call ap_Merge_per_dir_configs()
     * Call the real provider->check_authorization() function
     * return the result of the above function call
     */

    provider_name = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);

    if (provider_name) {
        authz_core_srv_conf *authcfg;
        provider_alias_rec *prvdraliasrec;

        authcfg = ap_get_module_config(r->server->module_config,
                                       &authz_core_module);

        prvdraliasrec = apr_hash_get(authcfg->alias_rec, provider_name,
                                     APR_HASH_KEY_STRING);

        /* If we found the alias provider in the list, then merge the directory
           configurations and call the real provider */
        if (prvdraliasrec) {
            ap_conf_vector_t *orig_dir_config = r->per_dir_config;

            r->per_dir_config =
                ap_merge_per_dir_configs(r->pool, orig_dir_config,
                                         prvdraliasrec->sec_auth);

            ret = prvdraliasrec->provider->
                check_authorization(r, prvdraliasrec->provider_args,
                                    prvdraliasrec->provider_parsed_args);

            r->per_dir_config = orig_dir_config;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02305)
                          "no alias provider found for '%s' (BUG?)",
                          provider_name);
        }
    }
    else {
        ap_assert(provider_name != NULL);
    }

    return ret;
}

static const authz_provider authz_alias_provider =
{
    &authz_alias_check_authorization,
    NULL,
};

static const char *authz_require_alias_section(cmd_parms *cmd, void *mconfig,
                                               const char *args)
{
    const char *endp = ap_strrchr_c(args, '>');
    char *provider_name;
    char *provider_alias;
    char *provider_args;
    ap_conf_vector_t *new_authz_config;
    int old_overrides = cmd->override;
    const char *errmsg;

    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }

    if (endp == NULL) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive missing closing '>'", NULL);
    }

    args = apr_pstrndup(cmd->temp_pool, args, endp - args);

    if (!args[0]) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive requires additional arguments", NULL);
    }

    /* Pull the real provider name and the alias name from the block header */
    provider_name = ap_getword_conf(cmd->pool, &args);
    provider_alias = ap_getword_conf(cmd->pool, &args);
    provider_args = ap_getword_conf(cmd->pool, &args);

    if (!provider_name[0] || !provider_alias[0]) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive requires additional arguments", NULL);
    }

    new_authz_config = ap_create_per_dir_config(cmd->pool);

    /* Walk the subsection configuration to get the per_dir config that we will
     * merge just before the real provider is called.
     */
    cmd->override = OR_AUTHCFG | ACCESS_CONF;
    errmsg = ap_walk_config(cmd->directive->first_child, cmd,
                            new_authz_config);
    cmd->override = old_overrides;

    if (!errmsg) {
        provider_alias_rec *prvdraliasrec;
        authz_core_srv_conf *authcfg;

        prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(*prvdraliasrec));

        /* Save off the new directory config along with the original
         * provider name and function pointer data
         */
        prvdraliasrec->provider_name = provider_name;
        prvdraliasrec->provider_alias = provider_alias;
        prvdraliasrec->provider_args = provider_args;
        prvdraliasrec->sec_auth = new_authz_config;
        prvdraliasrec->provider =
            ap_lookup_provider(AUTHZ_PROVIDER_GROUP, provider_name,
                               AUTHZ_PROVIDER_VERSION);

        /* by the time the config file is used, the provider should be loaded
         * and registered with us.
         */
        if (!prvdraliasrec->provider) {
            return apr_psprintf(cmd->pool,
                                "Unknown Authz provider: %s",
                                provider_name);
        }
        if (prvdraliasrec->provider->parse_require_line) {
            err = prvdraliasrec->provider->parse_require_line(cmd,
                         provider_args, &prvdraliasrec->provider_parsed_args);
            if (err)
                return apr_psprintf(cmd->pool,
                                    "Can't parse 'Require %s %s': %s",
                                    provider_name, provider_args, err);
        }

        authcfg = ap_get_module_config(cmd->server->module_config,
                                       &authz_core_module);

        apr_hash_set(authcfg->alias_rec, provider_alias,
                     APR_HASH_KEY_STRING, prvdraliasrec);

        /* Register the fake provider so that we get called first */
        ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP,
                                  provider_alias, AUTHZ_PROVIDER_VERSION,
                                  &authz_alias_provider,
                                  AP_AUTH_INTERNAL_PER_CONF);
    }

    return errmsg;
}

static const char* format_authz_result(authz_status result)
{
    return ((result == AUTHZ_DENIED)
            ? "denied"
            : ((result == AUTHZ_GRANTED)
               ? "granted"
               : ((result == AUTHZ_DENIED_NO_USER)
                  ? "denied (no authenticated user yet)"
                  : "neutral")));
}

static const char* format_authz_command(apr_pool_t *p,
                                        authz_section_conf *section)
{
    return (section->provider
            ? apr_pstrcat(p, "Require ", (section->negate ? "not " : ""),
                          section->provider_name, " ",
                          section->provider_args, NULL)
            : apr_pstrcat(p, section->is_merged ? "AuthMerging " : "<Require",
                          ((section->op == AUTHZ_LOGIC_AND)
                           ? (section->negate ? "NotAll" : "All")
                           : (section->negate ? "None" : "Any")),
                          section->is_merged ? "" : ">", NULL));
}

static authz_section_conf* create_default_section(apr_pool_t *p)
{
    authz_section_conf *section = apr_pcalloc(p, sizeof(*section));

    section->op = AUTHZ_LOGIC_OR;

    return section;
}

static const char *add_authz_provider(cmd_parms *cmd, void *config,
                                      const char *args)
{
    authz_core_dir_conf *conf = (authz_core_dir_conf*)config;
    authz_section_conf *section = apr_pcalloc(cmd->pool, sizeof(*section));
    authz_section_conf *child;

    section->provider_name = ap_getword_conf(cmd->pool, &args);

    if (!strcasecmp(section->provider_name, "not")) {
        section->provider_name = ap_getword_conf(cmd->pool, &args);
        section->negate = 1;
    }

    section->provider_args = args;

    /* lookup and cache the actual provider now */
    section->provider = ap_lookup_provider(AUTHZ_PROVIDER_GROUP,
                                           section->provider_name,
                                           AUTHZ_PROVIDER_VERSION);

    /* by the time the config file is used, the provider should be loaded
     * and registered with us.
     */
    if (!section->provider) {
        return apr_psprintf(cmd->pool,
                            "Unknown Authz provider: %s",
                            section->provider_name);
    }

    /* if the provider doesn't provide the appropriate function, reject it */
    if (!section->provider->check_authorization) {
        return apr_psprintf(cmd->pool,
                            "The '%s' Authz provider is not supported by any "
                            "of the loaded authorization modules",
                            section->provider_name);
    }

    section->limited = cmd->limited;

    if (section->provider->parse_require_line) {
        const char *err;
        apr_pool_userdata_setn(section->provider_name,
                               AUTHZ_PROVIDER_NAME_NOTE,
                               apr_pool_cleanup_null,
                               cmd->temp_pool);
        err = section->provider->parse_require_line(cmd, args,
                                              &section->provider_parsed_args);

        if (err)
            return err;
    }

    if (!conf->section) {
        conf->section = create_default_section(cmd->pool);
    }

    if (section->negate && conf->section->op == AUTHZ_LOGIC_OR) {
        return apr_psprintf(cmd->pool, "negative %s directive has no effect "
                            "in %s directive",
                            cmd->cmd->name,
                            format_authz_command(cmd->pool, conf->section));
    }

    conf->section->limited |= section->limited;

    child = conf->section->first;

    if (child) {
        while (child->next) {
            child = child->next;
        }

        child->next = section;
    }
    else {
        conf->section->first = section;
    }

    return NULL;
}

static const char *add_authz_section(cmd_parms *cmd, void *mconfig,
                                     const char *args)
{
    authz_core_dir_conf *conf = mconfig;
    const char *endp = ap_strrchr_c(args, '>');
    authz_section_conf *old_section = conf->section;
    authz_section_conf *section;
    int old_overrides = cmd->override;
    apr_int64_t old_limited = cmd->limited;
    const char *errmsg;

    if (endp == NULL) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive missing closing '>'", NULL);
    }

    args = apr_pstrndup(cmd->temp_pool, args, endp - args);

    if (args[0]) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive doesn't take additional arguments",
                           NULL);
    }

    section = apr_pcalloc(cmd->pool, sizeof(*section));

    if (!strcasecmp(cmd->cmd->name, "<RequireAll")) {
        section->op = AUTHZ_LOGIC_AND;
    }
    else if (!strcasecmp(cmd->cmd->name, "<RequireAny")) {
        section->op = AUTHZ_LOGIC_OR;
    }
    else if (!strcasecmp(cmd->cmd->name, "<RequireNotAll")) {
        section->op = AUTHZ_LOGIC_AND;
        section->negate = 1;
    }
    else {
        section->op = AUTHZ_LOGIC_OR;
        section->negate = 1;
    }

    conf->section = section;

    /* trigger NOT_IN_LIMIT errors as if this were a <Limit> directive */
    cmd->limited &= ~(AP_METHOD_BIT << (METHODS - 1));

    cmd->override = OR_AUTHCFG;
    errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
    cmd->override = old_overrides;

    cmd->limited = old_limited;

    conf->section = old_section;

    if (errmsg) {
        return errmsg;
    }

    if (section->first) {
        authz_section_conf *child;

        if (!old_section) {
            old_section = conf->section = create_default_section(cmd->pool);
        }

        if (section->negate && old_section->op == AUTHZ_LOGIC_OR) {
            return apr_psprintf(cmd->pool, "%s directive has "
                                "no effect in %s directive",
                                format_authz_command(cmd->pool, section),
                                format_authz_command(cmd->pool, old_section));
        }

        old_section->limited |= section->limited;

        if (!section->negate && section->op == old_section->op) {
            /* be associative */
            section = section->first;
        }

        child = old_section->first;

        if (child) {
            while (child->next) {
                child = child->next;
            }

            child->next = section;
        }
        else {
            old_section->first = section;
        }
    }
    else {
        return apr_pstrcat(cmd->pool,
                           format_authz_command(cmd->pool, section),
                           " directive contains no authorization directives",
                           NULL);
    }

    return NULL;
}

static const char *authz_merge_sections(cmd_parms *cmd, void *mconfig,
                                        const char *arg)
{
    authz_core_dir_conf *conf = mconfig;

    if (!strcasecmp(arg, "Off")) {
        conf->op = AUTHZ_LOGIC_OFF;
    }
    else if (!strcasecmp(arg, "And")) {
        conf->op = AUTHZ_LOGIC_AND;
    }
    else if (!strcasecmp(arg, "Or")) {
        conf->op = AUTHZ_LOGIC_OR;
    }
    else {
        return apr_pstrcat(cmd->pool, cmd->cmd->name, " must be one of: "
                           "Off | And | Or", NULL);
    }

    return NULL;
}

static int authz_core_check_section(apr_pool_t *p, server_rec *s,
                                    authz_section_conf *section, int is_conf)
{
    authz_section_conf *prev = NULL;
    authz_section_conf *child = section->first;
    int ret = !OK;

    while (child) {
        if (child->first) {
            if (authz_core_check_section(p, s, child, 0) != OK) {
                return !OK;
            }

            if (child->negate && child->op != section->op) {
                authz_section_conf *next = child->next;

                /* avoid one level of recursion when De Morgan permits */
                child = child->first;

                if (prev) {
                    prev->next = child;
                }
                else {
                    section->first = child;
                }

                do {
                    child->negate = !child->negate;
                } while (child->next && (child = child->next));

                child->next = next;
            }
        }

        prev = child;
        child = child->next;
    }

    child = section->first;

    while (child) {
        if (!child->negate) {
            ret = OK;
            break;
        }

        child = child->next;
    }

    if (ret != OK) {
        ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, APR_SUCCESS, s, APLOGNO(01624)
                     "%s directive contains only negative authorization directives",
                     is_conf ? "<Directory>, <Location>, or similar"
                             : format_authz_command(p, section));
    }

    return ret;
}

static int authz_core_pre_config(apr_pool_t *p, apr_pool_t *plog,
                                 apr_pool_t *ptemp)
{
    authz_core_first_dir_conf = NULL;

    return OK;
}

static int authz_core_check_config(apr_pool_t *p, apr_pool_t *plog,
                                   apr_pool_t *ptemp, server_rec *s)
{
    authz_core_dir_conf *conf = authz_core_first_dir_conf;

    while (conf) {
        if (conf->section) {
            if (authz_core_check_section(p, s, conf->section, 1) != OK) {
                return !OK;
            }
        }

        conf = conf->next;
    }

    return OK;
}

static const command_rec authz_cmds[] =
{
    AP_INIT_RAW_ARGS("<AuthzProviderAlias", authz_require_alias_section,
                     NULL, RSRC_CONF,
                     "container for grouping an authorization provider's "
                     "directives under a provider alias"),
    AP_INIT_RAW_ARGS("Require", add_authz_provider, NULL, OR_AUTHCFG,
                     "specifies authorization directives "
                     "which one must pass (or not) for a request to suceeed"),
    AP_INIT_RAW_ARGS("<RequireAll", add_authz_section, NULL, OR_AUTHCFG,
                     "container for grouping authorization directives "
                     "of which none must fail and at least one must pass "
                     "for a request to succeed"),
    AP_INIT_RAW_ARGS("<RequireAny", add_authz_section, NULL, OR_AUTHCFG,
                     "container for grouping authorization directives "
                     "of which one must pass "
                     "for a request to succeed"),
#ifdef AUTHZ_EXTRA_CONFIGS
    AP_INIT_RAW_ARGS("<RequireNotAll", add_authz_section, NULL, OR_AUTHCFG,
                     "container for grouping authorization directives "
                     "of which some must fail or none must pass "
                     "for a request to succeed"),
#endif
    AP_INIT_RAW_ARGS("<RequireNone", add_authz_section, NULL, OR_AUTHCFG,
                     "container for grouping authorization directives "
                     "of which none must pass "
                     "for a request to succeed"),
    AP_INIT_TAKE1("AuthMerging", authz_merge_sections, NULL, OR_AUTHCFG,
                  "controls how a <Directory>, <Location>, or similar "
                  "directive's authorization directives are combined with "
                  "those of its predecessor"),
    AP_INIT_FLAG("AuthzSendForbiddenOnFailure", ap_set_flag_slot_char,
                 (void *)APR_OFFSETOF(authz_core_dir_conf, authz_forbidden_on_fail),
                 OR_AUTHCFG,
                 "Controls if an authorization failure should result in a "
                 "'403 FORBIDDEN' response instead of the HTTP-conforming "
                 "'401 UNAUTHORIZED'"),
    {NULL}
};

static authz_status apply_authz_sections(request_rec *r,
                                         authz_section_conf *section,
                                         authz_logic_op parent_op)
{
    authz_status auth_result;

    /* check to make sure that the request method requires authorization */
    if (!(section->limited & (AP_METHOD_BIT << r->method_number))) {
        auth_result =
            (parent_op == AUTHZ_LOGIC_AND) ? AUTHZ_GRANTED : AUTHZ_NEUTRAL;

        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01625)
                      "authorization result of %s: %s "
                      "(directive limited to other methods)",
                      format_authz_command(r->pool, section),
                      format_authz_result(auth_result));

        return auth_result;
    }

    if (section->provider) {
        apr_table_setn(r->notes, AUTHZ_PROVIDER_NAME_NOTE,
                       section->provider_name);

        auth_result =
            section->provider->check_authorization(r, section->provider_args,
                                                   section->provider_parsed_args);

        apr_table_unset(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
    }
    else {
        authz_section_conf *child = section->first;

        auth_result = AUTHZ_NEUTRAL;

        while (child) {
            authz_status child_result;

            child_result = apply_authz_sections(r, child, section->op);

            if (child_result == AUTHZ_GENERAL_ERROR) {
                return AUTHZ_GENERAL_ERROR;
            }

            if (child_result != AUTHZ_NEUTRAL) {
                /*
                 * Handling of AUTHZ_DENIED/AUTHZ_DENIED_NO_USER: Return
                 * AUTHZ_DENIED_NO_USER if providing a user may change the
                 * result, AUTHZ_DENIED otherwise.
                 */
                if (section->op == AUTHZ_LOGIC_AND) {
                    if (child_result == AUTHZ_DENIED) {
                        auth_result = child_result;
                        break;
                    }
                    if ((child_result == AUTHZ_DENIED_NO_USER
                         && auth_result != AUTHZ_DENIED)
                        || (auth_result == AUTHZ_NEUTRAL)) {
                        auth_result = child_result;
                    }
                }
                else {
                    /* AUTHZ_LOGIC_OR */
                    if (child_result == AUTHZ_GRANTED) {
                        auth_result = child_result;
                        break;
                    }
                    if ((child_result == AUTHZ_DENIED_NO_USER
                         && auth_result == AUTHZ_DENIED)
                        || (auth_result == AUTHZ_NEUTRAL)) {
                        auth_result = child_result;
                    }
                }
            }

            child = child->next;
        }
    }

    if (section->negate) {
        if (auth_result == AUTHZ_GRANTED) {
            auth_result = AUTHZ_DENIED;
        }
        else if (auth_result == AUTHZ_DENIED ||
                 auth_result == AUTHZ_DENIED_NO_USER) {
            /* For negated directives, if the original result was denied
             * then the new result is neutral since we can not grant
             * access simply because authorization was not rejected.
             */
            auth_result = AUTHZ_NEUTRAL;
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01626)
                  "authorization result of %s: %s",
                  format_authz_command(r->pool, section),
                  format_authz_result(auth_result));

    return auth_result;
}

static int authorize_user_core(request_rec *r, int after_authn)
{
    authz_core_dir_conf *conf;
    authz_status auth_result;

    conf = ap_get_module_config(r->per_dir_config, &authz_core_module);

    if (!conf->section) {
        if (ap_auth_type(r)) {
            /* there's an AuthType configured, but no authorization
             * directives applied to support it
             */

            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01627)
                          "AuthType configured with no corresponding "
                          "authorization directives");

            return HTTP_INTERNAL_SERVER_ERROR;
        }

        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01628)
                      "authorization result: granted (no directives)");

        return OK;
    }

    auth_result = apply_authz_sections(r, conf->section, AUTHZ_LOGIC_AND);

    if (auth_result == AUTHZ_GRANTED) {
        return OK;
    }
    else if (auth_result == AUTHZ_DENIED_NO_USER) {
        if (after_authn) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01629)
                          "authorization failure (no authenticated user): %s",
                          r->uri);
            /*
             * If we're returning 401 to an authenticated user, tell them to
             * try again. If unauthenticated, note_auth_failure has already
             * been called during auth.
             */
            if (r->user)
                ap_note_auth_failure(r);

            return HTTP_UNAUTHORIZED;
        }
        else {
            /*
             * We need a user before we can decide what to do.
             * Get out of the way and proceed with authentication.
             */
            return DECLINED;
        }
    }
    else if (auth_result == AUTHZ_DENIED || auth_result == AUTHZ_NEUTRAL) {
        if (!after_authn || ap_auth_type(r) == NULL) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01630)
                          "client denied by server configuration: %s%s",
                          r->filename ? "" : "uri ",
                          r->filename ? r->filename : r->uri);

            return HTTP_FORBIDDEN;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01631)
                          "user %s: authorization failure for \"%s\": ",
                          r->user, r->uri);

            if (conf->authz_forbidden_on_fail > 0) {
                return HTTP_FORBIDDEN;
            }
            else {
                /*
                 * If we're returning 401 to an authenticated user, tell them to
                 * try again. If unauthenticated, note_auth_failure has already
                 * been called during auth.
                 */
                if (r->user)
                    ap_note_auth_failure(r);
                return HTTP_UNAUTHORIZED;
            }
        }
    }
    else {
        /* We'll assume that the module has already said what its
         * error was in the logs.
         */
        return HTTP_INTERNAL_SERVER_ERROR;
    }
}

static int authorize_userless(request_rec *r)
{
    return authorize_user_core(r, 0);
}

static int authorize_user(request_rec *r)
{
    return authorize_user_core(r, 1);
}

static int authz_some_auth_required(request_rec *r)
{
    authz_core_dir_conf *conf;

    conf = ap_get_module_config(r->per_dir_config, &authz_core_module);

    if (conf->section
        && (conf->section->limited & (AP_METHOD_BIT << r->method_number))) {
        return 1;
    }

    return 0;
}

/*
 * env authz provider
 */

static authz_status env_check_authorization(request_rec *r,
                                            const char *require_line,
                                            const void *parsed_require_line)
{
    const char *t, *w;

    /* The 'env' provider will allow the configuration to specify a list of
        env variables to check rather than a single variable.  This is different
        from the previous host based syntax. */
    t = require_line;
    while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
        if (apr_table_get(r->subprocess_env, w)) {
            return AUTHZ_GRANTED;
        }
    }

    return AUTHZ_DENIED;
}

static const authz_provider authz_env_provider =
{
    &env_check_authorization,
    NULL,
};


/*
 * all authz provider
 */

static authz_status all_check_authorization(request_rec *r,
                                            const char *require_line,
                                            const void *parsed_require_line)
{
    if (parsed_require_line) {
        return AUTHZ_GRANTED;
    }
    return AUTHZ_DENIED;
}

static const char *all_parse_config(cmd_parms *cmd, const char *require_line,
                                    const void **parsed_require_line)
{
    /*
     * If the argument to the 'all' provider is 'granted' then just let
     * everybody in. This would be equivalent to the previous syntax of
     * 'allow from all'. If the argument is 'denied' we reject everbody,
     * which is equivalent to 'deny from all'.
     */
    if (strcasecmp(require_line, "granted") == 0) {
        *parsed_require_line = (void *)1;
        return NULL;
    }
    else if (strcasecmp(require_line, "denied") == 0) {
        /* *parsed_require_line is already NULL */
        return NULL;
    }
    else {
        return "Argument for 'Require all' must be 'granted' or 'denied'";
    }
}

static const authz_provider authz_all_provider =
{
    &all_check_authorization,
    &all_parse_config,
};


/*
 * method authz provider
 */

static authz_status method_check_authorization(request_rec *r,
                                               const char *require_line,
                                               const void *parsed_require_line)
{
    const apr_int64_t *allowed = parsed_require_line;
    if (*allowed & (AP_METHOD_BIT << r->method_number))
        return AUTHZ_GRANTED;
    else
        return AUTHZ_DENIED;
}

static const char *method_parse_config(cmd_parms *cmd, const char *require_line,
                                       const void **parsed_require_line)
{
    const char *w, *t;
    apr_int64_t *allowed = apr_pcalloc(cmd->pool, sizeof(apr_int64_t));

    t = require_line;

    while ((w = ap_getword_conf(cmd->temp_pool, &t)) && w[0]) {
        int m = ap_method_number_of(w);
        if (m == M_INVALID) {
            return apr_pstrcat(cmd->pool, "Invalid Method '", w, "'", NULL);
        }

        *allowed |= (AP_METHOD_BIT << m);
    }

    *parsed_require_line = allowed;
    return NULL;
}

static const authz_provider authz_method_provider =
{
    &method_check_authorization,
    &method_parse_config,
};

/*
 * expr authz provider
 */

#define REQUIRE_EXPR_NOTE "Require_expr_info"
struct require_expr_info {
    ap_expr_info_t *expr;
    int want_user;
};

static int expr_lookup_fn(ap_expr_lookup_parms *parms)
{
    if (parms->type == AP_EXPR_FUNC_VAR
        && strcasecmp(parms->name, "REMOTE_USER") == 0) {
        struct require_expr_info *info;
        apr_pool_userdata_get((void**)&info, REQUIRE_EXPR_NOTE, parms->ptemp);
        AP_DEBUG_ASSERT(info != NULL);
        info->want_user = 1;
    }
    return ap_expr_lookup_default(parms);
}

static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
                                     const void **parsed_require_line)
{
    const char *expr_err = NULL;
    struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));

    /* if the expression happens to be surrounded by quotes, skip them */
    if (require_line[0] == '"') {
        apr_size_t len = strlen(require_line);

        if (require_line[len-1] == '"')
            require_line = apr_pstrndup(cmd->temp_pool,
                                        require_line + 1,
                                        len - 2);
    }

    apr_pool_userdata_setn(info, REQUIRE_EXPR_NOTE, apr_pool_cleanup_null,
                          cmd->temp_pool);
    info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
                                   expr_lookup_fn);

    if (expr_err)
        return apr_pstrcat(cmd->temp_pool,
                           "Cannot parse expression in require line: ",
                           expr_err, NULL);

    *parsed_require_line = info;

    return NULL;
}

static authz_status expr_check_authorization(request_rec *r,
                                             const char *require_line,
                                             const void *parsed_require_line)
{
    const char *err = NULL;
    const struct require_expr_info *info = parsed_require_line;
    int rc = ap_expr_exec(r, info->expr, &err);

    if (rc < 0) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320)
                      "Error evaluating expression in 'Require expr': %s",
                      err);
        return AUTHZ_GENERAL_ERROR;
    }
    else if (rc == 0) {
        if (info->want_user)
            return AUTHZ_DENIED_NO_USER;
        else
            return AUTHZ_DENIED;
    }
    else {
        return AUTHZ_GRANTED;
    }
}

static const authz_provider authz_expr_provider =
{
    &expr_check_authorization,
    &expr_parse_config,
};


static void register_hooks(apr_pool_t *p)
{
    APR_REGISTER_OPTIONAL_FN(authz_some_auth_required);

    ap_hook_pre_config(authz_core_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_check_config(authz_core_check_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_check_authz(authorize_user, NULL, NULL, APR_HOOK_LAST,
                        AP_AUTH_INTERNAL_PER_CONF);
    ap_hook_check_access_ex(authorize_userless, NULL, NULL, APR_HOOK_LAST,
                            AP_AUTH_INTERNAL_PER_CONF);

    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "env",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_env_provider, AP_AUTH_INTERNAL_PER_CONF);
    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "all",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_all_provider, AP_AUTH_INTERNAL_PER_CONF);
    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "method",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_method_provider, AP_AUTH_INTERNAL_PER_CONF);
    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "expr",
                              AUTHZ_PROVIDER_VERSION,
                              &authz_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
}

AP_DECLARE_MODULE(authz_core) =
{
    STANDARD20_MODULE_STUFF,
    create_authz_core_dir_config,   /* dir config creater */
    merge_authz_core_dir_config,    /* dir merger */
    create_authz_core_svr_config,   /* server config */
    merge_authz_core_svr_config ,   /* merge server config */
    authz_cmds,
    register_hooks                  /* register hooks */
};

