Commit 241716d5 authored by Stefan Fritsch's avatar Stefan Fritsch
Browse files

Check during config test that directories for access logs exist

PR 29941


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1243651 13f79535-47bb-0310-9956-ffa450edef68
parent d0a0e26c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_log_config: Check during config test that directories for access logs
     exist. PR 29941. [Stefan Fritsch]

  *) mod_authnz_ldap: Don't try a potentially expensive nested groups
     search before exhausting all AuthLDAPGroupAttribute checks on the
     current group. PR52464 [Eric Covener]
+1 −1
Original line number Diff line number Diff line
2296
2298
+53 −0
Original line number Diff line number Diff line
@@ -263,6 +263,8 @@ typedef struct {
    void *log_writer;
    char *condition_var;
    ap_expr_info_t *condition_expr;
    /** place of definition or NULL if already checked */
    const ap_directive_t *directive;
} config_log_state;

/*
@@ -1271,6 +1273,7 @@ static const char *add_custom_log(cmd_parms *cmd, void *dummy, const char *fn,

    cls->fname = fn;
    cls->format_string = fmt;
    cls->directive = cmd->directive;
    if (fmt == NULL) {
        cls->format = NULL;
    }
@@ -1678,9 +1681,59 @@ static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
    return OK;
}

static int check_log_dir(apr_pool_t *p, server_rec *s, config_log_state *cls)
{
    if (!cls->fname || cls->fname[0] == '|' || !cls->directive) {
        return OK;
    }
    else {
        char *abs = ap_server_root_relative(p, cls->fname);
        char *dir = ap_make_dirstr_parent(p, abs);
        apr_finfo_t finfo;
        const ap_directive_t *directive = cls->directive;
        apr_status_t rv = apr_stat(&finfo, dir, APR_FINFO_TYPE, p);
        cls->directive = NULL; /* Don't check this config_log_state again */
        if (rv == APR_SUCCESS && finfo.filetype != APR_DIR)
            rv = APR_ENOTDIR;
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, rv, s,
                         APLOGNO(02297)
                         "Cannot access directory '%s' for log file '%s' "
                         "defined at %s:%d", dir, cls->fname,
                         directive->filename, directive->line_num);
            return !OK;
        }
    }
    return OK;
}

static int log_check_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
    int rv = OK;
    while (s) {
        multi_log_state *mls = ap_get_module_config(s->module_config,
                                                    &log_config_module);
        /*
         * We don't need to check mls->server_config_logs because it just
         * points to the parent server's mls->config_logs.
         */
        apr_array_header_t *log_list = mls->config_logs;
        config_log_state *clsarray = (config_log_state *) log_list->elts;
        int i;
        for (i = 0; i < log_list->nelts; ++i) {
            if (check_log_dir(ptemp, s, &clsarray[i]) != OK)
                rv = !OK;
        }

        s = s->next;
    }
    return rv;
}

static void register_hooks(apr_pool_t *p)
{
    ap_hook_pre_config(log_pre_config,NULL,NULL,APR_HOOK_REALLY_FIRST);
    ap_hook_check_config(log_check_config,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_child_init(init_child,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_open_logs(init_config_log,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_log_transaction(multi_log_transaction,NULL,NULL,APR_HOOK_MIDDLE);