At 11:13 PM 3/2/2005, William A. Rowe, Jr. wrote: >x>>No - simply create a per-dir config, and use dirconfig to represent; >>> >>>> <AuthConfig> >>>> AuthFile users1 >>>> </AuthConfig> >> >>How does that work? The issue here is that we want to use the same module >>multiple times in the same location/directory/file. So, there'd only be one >>per-dir-config instance. -- justin > >I found an hour to hack it, but it will take two more to wrap it.
And attached is the module for comment. I have no time till this weekend if then, so I've got the build system changes and will commit if we like. Bill
/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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. */ #include "httpd.h" #include "http_request.h" #include "apr_strings.h" #define CORE_PRIVATE #include "http_config.h" module AP_MODULE_DECLARE_DATA auth_config_module; typedef struct auth_dir_conf { apr_array_header_t *sec_auth; } auth_dir_conf; static void *create_auth_dir_config(apr_pool_t *p, char *dummy) { auth_dir_conf *conf = (auth_dir_conf *) apr_palloc(p, sizeof(auth_dir_conf)); /* Created in authsection, when invoked */ conf->sec_auth = NULL; return (void *) conf; } static void *merge_auth_dir_config(apr_pool_t *p, void *basev, void *addv) { auth_dir_conf *conf = (auth_dir_conf *) apr_palloc(p, sizeof(auth_dir_conf)); auth_dir_conf *base = (auth_dir_conf *) basev; auth_dir_conf *add = (auth_dir_conf *) addv; if (add->sec_auth) { conf->sec_auth = add->sec_auth; } else { conf->sec_auth = base->sec_auth; } /* The logic; * conf->auth_dir_conf = apr_array_append(p, base->sec_auth, add->sec_auth); * would be useful, if we had a way to distinguish when <AuthConfig > should * override <AuthConfig> from a lower scope. */ return conf; } static const char *authsection(cmd_parms *cmd, void *confv, const char *arg) { int old_overrides = cmd->override; auth_dir_conf *conf = (auth_dir_conf *)confv; ap_conf_vector_t *new_auth_config = ap_create_per_dir_config(cmd->pool); const char *endp = ap_strrchr_c(arg, '>'); const char *errmsg = ap_check_cmd_context(cmd, NOT_IN_LIMIT); if (errmsg != NULL) return errmsg; if (endp == NULL) return apr_pstrcat(cmd->pool, cmd->cmd->name, "> directive missing closing '>'", NULL); if (arg) return apr_pstrcat(cmd->pool, "<AuthConfig> takes no options, ", arg, " is invalid", NULL); /* Create the sec_auth array on demand */ if (!conf->sec_auth) conf->sec_auth = apr_array_make(cmd->pool, 2, sizeof(ap_conf_vector_t *)); cmd->override = ACCESS_CONF; errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_auth_config); *((void **)apr_array_push(conf->sec_auth)) = new_auth_config; cmd->override = old_overrides; /* Hopefully NULL */ return errmsg; } static int auth_check_user_id(request_rec *r) { int access_status; void *recurse; auth_dir_conf *conf = ap_get_module_config(r->per_dir_config, &auth_config_module); ap_conf_vector_t *orig_dir_config = r->per_dir_config; ap_conf_vector_t **auth_elt; int auth_nelt; if (!conf->sec_auth) return DECLINED; if ((apr_pool_userdata_get((void**)&recurse, "mod_auth_config::recurse", r->pool) != APR_SUCCESS) && recurse) return DONE; auth_elt = (ap_conf_vector_t **)conf->sec_auth->elts; auth_nelt = conf->sec_auth->nelts; apr_pool_userdata_setn((void*) -1, "mod_auth_config::recurse", apr_pool_cleanup_null, r->pool); while (auth_nelt && *auth_elt) { r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config, *auth_elt); access_status = ap_run_check_user_id(r); /* We contine on DONE, only auth_config returns it */ if ((access_status != DONE) && (access_status != DECLINED)) { apr_pool_userdata_setn(NULL, "mod_auth_config::recurse", apr_pool_cleanup_null, r->pool); return access_status; } --auth_nelt; ++auth_elt; } apr_pool_userdata_setn(NULL, "mod_auth_config::recurse", apr_pool_cleanup_null, r->pool); r->per_dir_config = orig_dir_config; return access_status; } static const command_rec auth_config_cmds[] = { AP_INIT_RAW_ARGS("<AuthConfig", authsection, NULL, RSRC_CONF, "Container for directives offering alternately acceptable auth"), {NULL} }; static void register_hooks(apr_pool_t *p) { /* Priority immediately before anon */ ap_hook_check_user_id(auth_check_user_id,NULL,NULL,APR_HOOK_LAST+1); } module AP_MODULE_DECLARE_DATA auth_config_module = { STANDARD20_MODULE_STUFF, create_auth_dir_config, /* dir config creater */ merge_auth_dir_config, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ auth_config_cmds, /* command apr_table_t */ register_hooks /* register hooks */ };
