简体   繁体   中英

Can AuthnProviderAlias ldap work with Apache2.4.x?

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:

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?

The bug is due to the providers and their usage being in different server contexts.

  • mod_authn_core provides AuthType, which causes a per-server config to be created for authn_core in for the VH
  • The module implements no merge function
  • server->module_config which will always be empty.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM