On Thu, Mar 06, 2008 at 03:36:27AM +0100, Josip Rodin wrote: > On Sat, Jul 21, 2007 at 06:08:23PM +0200, joy wrote: > > Is the mod_auth_radius-2.0.c supposed to work properly with Apache 2.2.x? > > > > I can compile it just fine, but can't get it to work on runtime. > > > > Maybe, like LDAP, this module should become a an AuthBasicProvider? > > I took a hint from mod_auth_xradius' changes for Apache 2.1+, and made the > patch which is attached... but it still doesn't work. Apache is so annoying > to debug, I need to compile the server with debugging symbols and run it > through gdb... :(
Okay, I debugged it a bit further (no help from gdb), and managed to produce a working patch. The problem that threw me off was the early DECLINED handling in the authenticate_basic_user() function, which got activated both when the module was inactive and when the RADIUS server definition was missing. However, these two conditions are functionally quite different, so I split the handling in two, with the latter case leaving a warning in the log file. The working patch is attached. It allows people to define: AuthBasicProvider radius and everything appears to be working well after that. -- 2. That which causes joy or happiness.
--- libapache-mod-auth-radius-1.5.7.orig/mod_auth_radius-2.0.c +++ libapache-mod-auth-radius-1.5.7/mod_auth_radius-2.0.c @@ -300,6 +300,9 @@ #include "apr_general.h" #include "apr_tables.h" #include "apr_strings.h" +/* Apache 2.1+ */ +#include "ap_provider.h" +#include "mod_auth.h" module AP_MODULE_DECLARE_DATA radius_auth_module; @@ -1122,8 +1125,11 @@ * basic authentication... */ -static int -authenticate_basic_user(request_rec *r) +/* common stuff for both Apache 2.0 and 2.1+ */ +int +authenticate_basic_user_common(request_rec *r, + const char* user, + const char* sent_pw) { radius_dir_config_rec *rec = (radius_dir_config_rec *)ap_get_module_config (r->per_dir_config, &radius_auth_module); @@ -1131,21 +1137,25 @@ radius_server_config_rec *scr = (radius_server_config_rec *) ap_get_module_config (s->module_config, &radius_auth_module); conn_rec *c = r->connection; - const char *sent_pw; char errstr[MAX_STRING_LEN]; - int res, min; + int min; char *cookie; char *state = NULL; char message[256]; time_t expires; struct stat buf; - if (!rec->active || !scr->radius_ip) /* not active here, or no radius */ - return DECLINED; /* server declared, decline */ + /* not active here, just decline */ + if (!rec->active) + return DECLINED; + + /* no server declared, decline but note for debugging purposes -joy */ + if (!scr->radius_ip) { + ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, r->server, + "AuthRadiusActive set, but no RADIUS server IP - missing AddRadiusAuth in this context?"); + return DECLINED; + } - if ((res = ap_get_basic_auth_pw(r, &sent_pw))) - return res; - if (r->user[0] == 0) /* NUL users can never be let in */ return HTTP_UNAUTHORIZED; @@ -1227,9 +1237,57 @@ return OK; } +/* Apache 2.1+ */ +static authn_status +authenticate_basic_user_newargs(request_rec *r, + const char *user, + const char *password) +{ + int normalreturnvalue = authenticate_basic_user_common(r, user, password); + + if (normalreturnvalue == OK) + return AUTH_GRANTED; + else if (normalreturnvalue == HTTP_UNAUTHORIZED) + return AUTH_DENIED; + else + return AUTH_GENERAL_ERROR; + /* AUTH_USER_NOT_FOUND would be nice, but the typical RADIUS server + never gives any such information, it just sends an Access-Reject + packet, no reasons given + */ +} + +/* Apache 2.0 */ +static int +authenticate_basic_user(request_rec *r) +{ + int res; + const char *sent_pw; + + /* this used to say just if ((res=...)), which relied on the fact that + OK is defined as 0, and the other states are non-0, which is then + used in a typical C fashion... but it's a bad idea, really, we should + explicitly check if it's not OK, whatever that may be -joy + */ + res = ap_get_basic_auth_pw(r, &sent_pw); + if (res != OK) + return res; + + return authenticate_basic_user_common(r, r->user, sent_pw); +} + +/* Apache 2.1+ */ +static const authn_provider authn_radius_provider = { + &authenticate_basic_user_newargs, + NULL +}; + static void register_hooks(apr_pool_t *p) { - ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,APR_HOOK_MIDDLE); +/* Apache 2.1+ */ + static const char * const aszPost[]={ "mod_authz_user.c", NULL }; + ap_register_provider(p, AUTHN_PROVIDER_GROUP, "radius", "0", &authn_radius_provider); + ap_hook_check_user_id(authenticate_basic_user,NULL,aszPost,APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA radius_auth_module =