/* 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;
    ap_method_mask_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;

    /* 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;
            authz_status ret;

            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;

            return ret;
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02305)
                  "no alias provider found for '%s' (BUG?)",
                  provider_name ? provider_name : "n/a");

    return AUTHZ_DENIED;
}

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, *extra_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);
    extra_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);
    }
    
    /* We only handle one "Require-Parameters" parameter.  If several parameters
       are needed, they must be enclosed between quotes */
    if (extra_args && *extra_args) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(10142)
                     "When several arguments (%s %s...) are passed to a %s directive, "
                     "they must be enclosed in quotation marks.  Otherwise, only the "
                     "first one is taken into account",
                     provider_args, extra_args, cmd->cmd->name);
    }

    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;
    ap_method_mask_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 everybody,
     * 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 ap_method_mask_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;
    ap_method_mask_t *allowed = apr_pcalloc(cmd->pool, sizeof *allowed);

    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 */
};

