Reputation: 1326832
This works perfectly in Apache2.2, but not in 2.4 (and I need to use 2.4 now):
<AuthnProviderAlias ldap myldap>
AuthLDAPBindDN cn=Manager,dc=example,dc=com
AuthLDAPBindPassword xxxx
AuthLDAPURL ldap://localhost:9011/dc=example,dc=com?uid?sub?(objectClass=*)
</AuthnProviderAlias>
Listen 48443
<VirtualHost myserver:48443>
<Directory /path/to/a/folder>
Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
AllowOverride All
order allow,deny
Allow from all
AuthBasicProvider myldap mySecondLdap myThirdLdap ...
AuthType Basic
AuthName "LDAP authentication for folder"
Require valid-user
...
</Directory>
</VirtualHost>
Using directly the directives from Apache 2.4 mod_authnz_ldap works in the <Directory >
section:
AuthLDAPBindDN cn=Manager,dc=example,dc=com
AuthLDAPBindPassword xxx
AuthLDAPURL ldap://localhost:9011/dc=example,dc=com?uid?sub?(objectClass=*)
AuthBasicProvider ldap
But that allows an authentication against only one LDAP server, and I have to authenticate against at least two.
Hence the use of AuthnProviderAlias
, which is now (2.4) part of mod_authn_core
core authentication module, instead of the old 2.2 LDAP authentication module mod_authn_alias
.
I have compiled all 2.4.x versions (from 2.4.1 to 2.4.6, and even current), with APR 1.4.8, and APR-util 1.5.2, in debug mode (-g -O0
)
What I tried is a debug session ( gdb --command=debug
, with 'debug
' a gdb parameter file as follow):
file /home/vonc/usr/local/apps/apache/bin/httpd
set logging file /home/vonc/gdb.txt
set logging on
set args -X
show args
set breakpoint pending on
# authn_alias_check_password
b mod_authn_core.c:115
# authaliassection
b mod_authn_core.c:203
b mod_authn_core.c:255
run
wh
fs next
where
What I see is:
authaliassection
function of mod_authn_core
is called twice, probably because of server/main.c
calls ap_process_config_tree
twice (once here, and once there) in the same main()
function.That function gets the authcfg
authn_alias_srv_conf *authcfg =
(authn_alias_srv_conf *)ap_get_module_config(r->server->module_config,
&authn_core_module);
And sets the provider with the right name 'ldap
' and right alias 'myldap
'
apr_hash_set(authcfg->alias_rec, provider_alias, APR_HASH_KEY_STRING, prvdraliasrec);
BUT: when the password needs to be checked (in authn_alias_check_password
, it gets authcfg
again, and fetch the provider:
provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec,
provider_name, APR_HASH_KEY_STRING);
It uses the right provider_name
'myldap
', ... and that always returns null
.
that means prvdraliasrec->provider->check_password
never get called.
A similar question in the http-dev mailing list (August 23, 2013 "Is AuthnProviderAlias subtly broken in 2.4?") was... unanswered.
How would you troubleshoot this bug?
Upvotes: 12
Views: 3787
Reputation: 17886
The bug is due to the providers and their usage being in different server contexts.
Workaround: Define your auth outside of VH context, or try this patch if you can rebuild easily: http://people.apache.org/~covener/patches/authprovider.diff
Index: modules/aaa/mod_authn_core.c
===================================================================
--- modules/aaa/mod_authn_core.c (revision 40703)
+++ modules/aaa/mod_authn_core.c (working copy)
@@ -179,6 +179,12 @@
return (void *) authcfg;
}
+/* Only per-server directive we have is GLOBAL_ONLY */
+static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv)
+{
+ return basev;
+}
+
static const authn_provider authn_alias_provider =
{
&authn_alias_check_password,
@@ -373,7 +379,7 @@
create_authn_core_dir_config, /* dir config creater */
merge_authn_core_dir_config, /* dir merger --- default is to override */
create_authn_alias_svr_config, /* server config */
- NULL, /* merge server config */
+ merge_authn_alias_svr_config, /* merge server config */
authn_cmds,
register_hooks /* register hooks */
};
Upvotes: 4
Reputation: 1326832
The only working solution I found is to patch mod_authn_core.c
, adding 2 global variables, one for each LDAP alias I want to work with.
That seems ugly: the two LDAP alias names are hardcoded in the code.
See commit 2f691a6
provider_alias_rec *prvdraliasrec_myldap;
provider_alias_rec *prvdraliasrec_companyldap;
That way, merge_authn_core_dir_config()
looks for those two alias names specifically to register them.
if (!prvdraliasrec && strcmp(provider_name,"myldap")==0) {
prvdraliasrec=prvdraliasrec_myldap;
}
if (!prvdraliasrec && strcmp(provider_name,"companyldap")==0) {
prvdraliasrec=prvdraliasrec_companyldap;
}
And authaliassection()
get those alias definition back
if ( strcmp(provider_alias,"myldap") == 0 ) {
prvdraliasrec_myldap = prvdraliasrec;
}
if ( strcmp(provider_alias,"companyldap") == 0 ) {
prvdraliasrec_companyldap = prvdraliasrec;
}
It works, but it certainly isn't the "right" solution.
Upvotes: 0