You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Javier Sagrera <sa...@lycos.com> on 2006/10/09 14:13:16 UTC
Clarification on how check_user_id hook works
Hi,
I wonder if someone can clarify how the check_user_id hook is suppose to
work.
Let say i have two small modules:
Module 1 (x.so) writes in the error_log file a simple message and returns
"DECLINED", this is register with the APR_HOOK_MIDDLE
Module 2 (r_d.so) just returns "DECLINED" to allow other functions in the
chain to be call, but is register with APR_HOOK_FIRST
The issue i see and i can't really understand is that the check function in
the first module is only called if the second module is registered with
HOOK_FIRsT.
I'm using the mod_auth to do a basic authentication based on AuthUserFile,
the module is included in my httpd binary.
For what i can see in the source code for mod_auth, the check functions in
the chain are only called
if a function return DECLINED, if it returns something else, it stop the
chain.
So i guess that when i only have the first module (the one register with
MIDDLE), the authenticate_basic_user() in mod_auth.c is been called first,
and becouse the user/passw
is correct, and i dont have the auth_autoritative flag in there, it just
return a OK and my check func
in my module is not been called.
But, why when registering the second module as first, it doesnt behave in
the same way?
How can you control the order of the modules if the module is linked inside
the httpd? I was
under the impression that with Ap2 the order is not set by the order of
LoadModule, but this is
not quite right here (i've done some test using mod_auth externally and the
order matters)
When having the second module registered with FIRST, i guess that the first
check function been call is the one in the second module,this returns
"DECLINED" and cause the call to the check function in the first one.
if this is so, why it doesnt call function in mod_auth instead?
Please, can someone thow some light here 8)
Cheers,
Jav
# ./httpd -V
Server version: Apache/2.0.59
Server built: Sep 26 2006 18:23:43
Server's Module Magic Number: 20020903:12
Server loaded: APR 0.9.12, APR-UTIL 0.9.12
Compiled using: APR 0.9.12, APR-UTIL 0.9.12
Architecture: 32-bit
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_FCNTL_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D HTTPD_ROOT="/www/apache2"
-D SUEXEC_BIN="/www/apache2/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
# ./httpd -l
Compiled in modules:
core.c
mod_access.c
mod_auth.c
mod_include.c
mod_log_config.c
mod_env.c
mod_setenvif.c
prefork.c
http_core.c
mod_mime.c
mod_status.c
mod_autoindex.c
mod_asis.c
mod_cgi.c
mod_negotiation.c
mod_dir.c
mod_imap.c
mod_actions.c
mod_userdir.c
mod_alias.c
mod_so.c
#
# grep LoadModule httpd.conf
# have to place corresponding `LoadModule' lines at this location so the
# LoadModule foo_module modules/mod_foo.so
LoadModule hw_module2 infx/x.so
LoadModule hw_module infx/r_d.so
#
- - - httpd.conf - - - -
<Location /auth>
AuthType Basic
AuthName test
require valid-user
AuthUserFile /tmp/users.txt
</Location>
- - - httpd.conf - - - -
# tail -f error_log
check_user_id() called.
[Mon Oct 09 12:00:51 2006] [error] [client 9.69.30.174] File does not exist:
/www/apache2/htdocs/auth
- - - - x.c - - - -
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
int ifx_auth(request_rec *r)
{
fprintf(stderr,"check_user_id() called.\n");
fflush(stderr);
return (DECLINED);
}
static void hw_register_hooks(apr_pool_t* p)
{
ap_hook_check_user_id(ifx_auth,NULL,NULL,APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA hw_module2 =
{
STANDARD20_MODULE_STUFF,
NULL, /* create per-directory config structures */
NULL, /* merge per-directory config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* command handlers */
hw_register_hooks /* register hooks */
};
- - - - x.c - - - -
- - - - r_d.c - - - -
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
int ifx_auth(request_rec *r)
{
return (DECLINED);
}
static void hw_register_hooks(apr_pool_t* p)
{
ap_hook_check_user_id(ifx_auth,NULL,NULL,APR_HOOK_FIRST);
}
module AP_MODULE_DECLARE_DATA hw_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create per-directory config structures */
NULL, /* merge per-directory config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* command handlers */
hw_register_hooks /* register hooks */
};
- - - - r_d.c - - - -
--------mod_auth.c---------
/* These functions return 0 if client is OK, and proper error status
* if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
* HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
* couldn't figure out how to tell if the client is authorized or not.
*
* If they return DECLINED, and all other modules also decline, that's
* treated by the server core as a configuration error, logged and
* reported as such.
*/
/* Determine user ID, and check if it really is that user, for HTTP
* basic authentication...
*/
static int authenticate_basic_user(request_rec *r)
{
auth_config_rec *conf = ap_get_module_config(r->per_dir_config,
&auth_module);
const char *sent_pw;
char *real_pw;
apr_status_t invalid_pw;
int res;
if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
return res;
}
if (!conf->auth_pwfile) {
return DECLINED;
}
if (!(real_pw = get_pw(r, r->user, conf->auth_pwfile))) {
if (!(conf->auth_authoritative)) {
return DECLINED;
}
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"user %s not found: %s", r->user, r->uri);
ap_note_basic_auth_failure(r);
return HTTP_UNAUTHORIZED;
}
invalid_pw = apr_password_validate(sent_pw, real_pw);
if (invalid_pw != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"user %s: authentication failure for \"%s\": "
"Password Mismatch",
r->user, r->uri);
ap_note_basic_auth_failure(r);
return HTTP_UNAUTHORIZED;
}
return OK;
}
--------mod_auth.c---------
Re: Clarification on how check_user_id hook works
Posted by Javier Sagrera <sa...@lycos.com>.
Hi,
I think i got a clear picture now, it is true that by saying MIDDLE you
really can expect any specific to be followed.
I guess that the new directives in 2.2 would help me to have a little more
control over the sequence of execution.
Thanks to all for taking some time in responding my emails.
Cheers,
Javier
"Brad Nicholes" <bn...@novell.com> wrote in message
news:452BBEEE.3235.00AC.0@novell.com...
>>>> On 10/10/2006 at 8:58 AM, in message
> <14...@mail.gmail.com>, "Eric
> Covener"
> <co...@gmail.com> wrote:
>> On 10/10/06, Javier Sagrera <sa...@lycos.com> wrote:
>>> So, i can write my modules, based on modules that i know will have a
>>> "conflict" with mine using the "if ..."
>>> but that is a little limited, i just find strange that you dont have
>>> control
>>> of the order in which the functions are call,
>>
>> Your example is a little contrived because an auth module already
>> checked and accepted the userid.
>>
>>> And even more strange, that the inclusion of a function registered with
>>> FIRST, will change the order too.
>>
>> You're sorting a list and have specified that you don't care about the
>> position of two things relative to eachother. Seems reasonable that
>> their position would change as the overall contents of the list
>> changes based on implementation of the sort.
>>
>> Don't get me wrong, being able to influence the hook ordering with
>> configuration directives sounds cool (e.g. DirectiveXYZ hook_name
>> mod_homegrown.c after mod_thirdparty.c) but it doesn't look like
>> there's a practical problem.
>
>
> The order in which the check_user_id hooks are called, isn't as big of an
> issue as you might think. In most cases, even if another module is called
> before yours, the first thing that it will do is check to make sure that
> it is configured for that <Directory> or <Location> and DECLINE to handle
> the request if not. Keep in mind that this is an Apache 2.0 and before
> issue. Apache 2.2 has solved this problem with providers. Using the
> AuthBasicProvider or AuthdigestProvider directives, you can specify which
> authentication providers will be called for a specific <directory> or
> <location> and in what order. Apache 2.3 goes even further to allow the
> same type of thing for authorization.
>
> Brad
>
Re: Clarification on how check_user_id hook works
Posted by Brad Nicholes <bn...@novell.com>.
>>> On 10/10/2006 at 8:58 AM, in message
<14...@mail.gmail.com>, "Eric Covener"
<co...@gmail.com> wrote:
> On 10/10/06, Javier Sagrera <sa...@lycos.com> wrote:
>> So, i can write my modules, based on modules that i know will have a
>> "conflict" with mine using the "if ..."
>> but that is a little limited, i just find strange that you dont have control
>> of the order in which the functions are call,
>
> Your example is a little contrived because an auth module already
> checked and accepted the userid.
>
>> And even more strange, that the inclusion of a function registered with
>> FIRST, will change the order too.
>
> You're sorting a list and have specified that you don't care about the
> position of two things relative to eachother. Seems reasonable that
> their position would change as the overall contents of the list
> changes based on implementation of the sort.
>
> Don't get me wrong, being able to influence the hook ordering with
> configuration directives sounds cool (e.g. DirectiveXYZ hook_name
> mod_homegrown.c after mod_thirdparty.c) but it doesn't look like
> there's a practical problem.
The order in which the check_user_id hooks are called, isn't as big of an issue as you might think. In most cases, even if another module is called before yours, the first thing that it will do is check to make sure that it is configured for that <Directory> or <Location> and DECLINE to handle the request if not. Keep in mind that this is an Apache 2.0 and before issue. Apache 2.2 has solved this problem with providers. Using the AuthBasicProvider or AuthdigestProvider directives, you can specify which authentication providers will be called for a specific <directory> or <location> and in what order. Apache 2.3 goes even further to allow the same type of thing for authorization.
Brad
Re: Clarification on how check_user_id hook works
Posted by Eric Covener <co...@gmail.com>.
On 10/10/06, Javier Sagrera <sa...@lycos.com> wrote:
> So, i can write my modules, based on modules that i know will have a
> "conflict" with mine using the "if ..."
> but that is a little limited, i just find strange that you dont have control
> of the order in which the functions are call,
Your example is a little contrived because an auth module already
checked and accepted the userid.
> And even more strange, that the inclusion of a function registered with
> FIRST, will change the order too.
You're sorting a list and have specified that you don't care about the
position of two things relative to eachother. Seems reasonable that
their position would change as the overall contents of the list
changes based on implementation of the sort.
Don't get me wrong, being able to influence the hook ordering with
configuration directives sounds cool (e.g. DirectiveXYZ hook_name
mod_homegrown.c after mod_thirdparty.c) but it doesn't look like
there's a practical problem.
--
Eric Covener
covener@gmail.com
Re: Clarification on how check_user_id hook works
Posted by Javier Sagrera <sa...@lycos.com>.
So, i can write my modules, based on modules that i know will have a
"conflict" with mine using the "if ..."
but that is a little limited, i just find strange that you dont have control
of the order in which the functions are call,
And even more strange, that the inclusion of a function registered with
FIRST, will change the order too.
Javier
"Nick Kew" <ni...@webthing.com> wrote in message
news:200610101046.34045.nick@webthing.com...
> On Tuesday 10 October 2006 09:33, Javier Sagrera wrote:
>
>> I can't see that using the 2nd and 3rd argument would be a proper
>> solution,
>> then you will need to write
>> you module based in what other module you have loaded in your apache
>> which
>> doesnt look quite good idea to me.
>
> Nope. Those are to say "if mod_foo is loaded, then be sure to run
> mod_foo's
> hook in this position before|after mine". It'll work perfectly well (and
> just
> not do anything) if mod_foo is not loaded.
>
> --
> Nick Kew
>
> Application Development with Apache - the Apache Modules Book
> http://www.prenhallprofessional.com/title/0132409674
>
Re: Clarification on how check_user_id hook works
Posted by Nick Kew <ni...@webthing.com>.
On Tuesday 10 October 2006 09:33, Javier Sagrera wrote:
> I can't see that using the 2nd and 3rd argument would be a proper solution,
> then you will need to write
> you module based in what other module you have loaded in your apache which
> doesnt look quite good idea to me.
Nope. Those are to say "if mod_foo is loaded, then be sure to run mod_foo's
hook in this position before|after mine". It'll work perfectly well (and just
not do anything) if mod_foo is not loaded.
--
Nick Kew
Application Development with Apache - the Apache Modules Book
http://www.prenhallprofessional.com/title/0132409674
Re: Clarification on how check_user_id hook works
Posted by Javier Sagrera <sa...@lycos.com>.
Thanks for the reply,
So basically, you have no control what so ever of when the function will be
called if you
register it with MIDDLE? You need to rely on other functions to return a
DECLINED?
I can't see that using the 2nd and 3rd argument would be a proper solution,
then you will need to write
you module based in what other module you have loaded in your apache which
doesnt look quite good idea to me.
And sill, if mod_auth is registered with MIDDLE too (as per source code),
why is this one not executed after the FIRST
,why it changes order when there is a FIRST in the chain?
I still see the behaivour a little 'strange'
Cheers,
Javier
"Eric Covener" <co...@gmail.com> wrote in message
news:1404e5910610091928u2cdab77g3a19422b4b8f1818@mail.gmail.com...
> On 10/9/06, Javier Sagrera <sa...@lycos.com> wrote:
>> Module 1 (x.so) writes in the error_log file a simple message and returns
>> "DECLINED", this is register with the APR_HOOK_MIDDLE
>
> This is the same position as mod_auth, so you can't have any
> expectation on when Module 1/mod_auth run with respect to eachother
>
>> Module 2 (r_d.so) just returns "DECLINED" to allow other functions in the
>> chain to be call, but is register with APR_HOOK_FIRST
>
>> The issue i see and i can't really understand is that the check function
>> in
>> the first module is only called if the second module is registered with
>> HOOK_FIRsT.
>
> Look at the 2nd and 3rd arguments to ap_hook_check_user_id() if you
> want "Module 1" to run in some predictable order relative to mod_auth.
>
> --
> Eric Covener
> covener@gmail.com
>
Re: Clarification on how check_user_id hook works
Posted by Eric Covener <co...@gmail.com>.
On 10/9/06, Javier Sagrera <sa...@lycos.com> wrote:
> Module 1 (x.so) writes in the error_log file a simple message and returns
> "DECLINED", this is register with the APR_HOOK_MIDDLE
This is the same position as mod_auth, so you can't have any
expectation on when Module 1/mod_auth run with respect to eachother
> Module 2 (r_d.so) just returns "DECLINED" to allow other functions in the
> chain to be call, but is register with APR_HOOK_FIRST
> The issue i see and i can't really understand is that the check function in
> the first module is only called if the second module is registered with
> HOOK_FIRsT.
Look at the 2nd and 3rd arguments to ap_hook_check_user_id() if you
want "Module 1" to run in some predictable order relative to mod_auth.
--
Eric Covener
covener@gmail.com