00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "apr_strings.h"
00018 #define APR_WANT_STRFUNC
00019 #include "apr_want.h"
00020
00021 #define CORE_PRIVATE
00022 #include "ap_config.h"
00023 #include "httpd.h"
00024 #include "http_config.h"
00025 #include "http_core.h"
00026 #include "http_request.h"
00027 #include "ap_provider.h"
00028
00029 #include "mod_auth.h"
00030
00031 typedef struct provider_alias_rec {
00032 char *provider_name;
00033 char *provider_alias;
00034 ap_conf_vector_t *sec_auth;
00035 const authn_provider *provider;
00036 } provider_alias_rec;
00037
00038 typedef struct authn_alias_srv_conf {
00039 apr_hash_t *alias_rec;
00040 } authn_alias_srv_conf;
00041
00042 module AP_MODULE_DECLARE_DATA authn_alias_module;
00043
00044 static authn_status authn_alias_check_password(request_rec *r, const char *user,
00045 const char *password)
00046 {
00047
00048
00049
00050
00051
00052 const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
00053 authn_status ret = AUTH_USER_NOT_FOUND;
00054 authn_alias_srv_conf *authcfg =
00055 (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config,
00056 &authn_alias_module);
00057
00058 if (provider_name) {
00059 provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec,
00060 provider_name, APR_HASH_KEY_STRING);
00061 ap_conf_vector_t *orig_dir_config = r->per_dir_config;
00062
00063
00064
00065 if (prvdraliasrec) {
00066 r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config,
00067 prvdraliasrec->sec_auth);
00068 ret = prvdraliasrec->provider->check_password(r,user,password);
00069 r->per_dir_config = orig_dir_config;
00070 }
00071 }
00072
00073 return ret;
00074 }
00075
00076 static authn_status authn_alias_get_realm_hash(request_rec *r, const char *user,
00077 const char *realm, char **rethash)
00078 {
00079
00080
00081
00082
00083
00084 const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
00085 authn_status ret = AUTH_USER_NOT_FOUND;
00086 authn_alias_srv_conf *authcfg =
00087 (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config,
00088 &authn_alias_module);
00089
00090 if (provider_name) {
00091 provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec,
00092 provider_name, APR_HASH_KEY_STRING);
00093 ap_conf_vector_t *orig_dir_config = r->per_dir_config;
00094
00095
00096
00097 if (prvdraliasrec) {
00098 r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config,
00099 prvdraliasrec->sec_auth);
00100 ret = prvdraliasrec->provider->get_realm_hash(r,user,realm,rethash);
00101 r->per_dir_config = orig_dir_config;
00102 }
00103 }
00104
00105 return ret;
00106 }
00107
00108 static void *create_authn_alias_svr_config(apr_pool_t *p, server_rec *s)
00109 {
00110
00111 authn_alias_srv_conf *authcfg;
00112
00113 authcfg = (authn_alias_srv_conf *) apr_pcalloc(p, sizeof(authn_alias_srv_conf));
00114 authcfg->alias_rec = apr_hash_make(p);
00115
00116 return (void *) authcfg;
00117 }
00118
00119 static const authn_provider authn_alias_provider =
00120 {
00121 &authn_alias_check_password,
00122 &authn_alias_get_realm_hash,
00123 };
00124
00125 static const char *authaliassection(cmd_parms *cmd, void *mconfig, const char *arg)
00126 {
00127 int old_overrides = cmd->override;
00128 const char *endp = ap_strrchr_c(arg, '>');
00129 const char *args;
00130 char *provider_alias;
00131 char *provider_name;
00132 const char *errmsg;
00133 const authn_provider *provider = NULL;
00134 ap_conf_vector_t *new_auth_config = ap_create_per_dir_config(cmd->pool);
00135 authn_alias_srv_conf *authcfg =
00136 (authn_alias_srv_conf *)ap_get_module_config(cmd->server->module_config,
00137 &authn_alias_module);
00138
00139 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
00140 if (err != NULL) {
00141 return err;
00142 }
00143
00144 if (endp == NULL) {
00145 return apr_pstrcat(cmd->pool, cmd->cmd->name,
00146 "> directive missing closing '>'", NULL);
00147 }
00148
00149 args = apr_pstrndup(cmd->pool, arg, endp - arg);
00150
00151 if (!args[0]) {
00152 return apr_pstrcat(cmd->pool, cmd->cmd->name,
00153 "> directive requires additional arguments", NULL);
00154 }
00155
00156
00157 provider_name = ap_getword_conf(cmd->pool, &args);
00158 provider_alias = ap_getword_conf(cmd->pool, &args);
00159
00160 if (!provider_name[0] || !provider_alias[0]) {
00161 return apr_pstrcat(cmd->pool, cmd->cmd->name,
00162 "> directive requires additional arguments", NULL);
00163 }
00164
00165 if (strcasecmp(provider_name, provider_alias) == 0) {
00166 return apr_pstrcat(cmd->pool,
00167 "The alias provider name must be different from the base provider name.", NULL);
00168 }
00169
00170
00171 provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_alias, "0");
00172 if (provider) {
00173 return apr_pstrcat(cmd->pool, "The alias provider ", provider_alias,
00174 " has already be registered previously as either a base provider or an alias provider.",
00175 NULL);
00176 }
00177
00178
00179
00180 cmd->override = OR_ALL|ACCESS_CONF;
00181 errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_auth_config);
00182
00183 if (!errmsg) {
00184 provider_alias_rec *prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(provider_alias_rec));
00185 provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_name, "0");
00186
00187
00188
00189 prvdraliasrec->sec_auth = new_auth_config;
00190 prvdraliasrec->provider_name = provider_name;
00191 prvdraliasrec->provider_alias = provider_alias;
00192 prvdraliasrec->provider = provider;
00193 apr_hash_set(authcfg->alias_rec, provider_alias, APR_HASH_KEY_STRING, prvdraliasrec);
00194
00195
00196 ap_register_provider(cmd->pool, AUTHN_PROVIDER_GROUP, provider_alias, "0",
00197 &authn_alias_provider);
00198 }
00199
00200 cmd->override = old_overrides;
00201
00202 return errmsg;
00203 }
00204
00205 static const command_rec authn_alias_cmds[] =
00206 {
00207 AP_INIT_RAW_ARGS("<AuthnProviderAlias", authaliassection, NULL, RSRC_CONF,
00208 "Container for authentication directives grouped under "
00209 "a provider alias"),
00210 {NULL}
00211 };
00212
00213
00214 module AP_MODULE_DECLARE_DATA authn_alias_module =
00215 {
00216 STANDARD20_MODULE_STUFF,
00217 NULL,
00218 NULL,
00219 create_authn_alias_svr_config,
00220 NULL,
00221 authn_alias_cmds,
00222 NULL
00223 };