From: jan@unixpapa.com Date: Fri, 15 May 2009 15:04:56 +0000 (+0000) Subject: Modified AuthExternal directive to be able to take more than one authenticator name. X-Git-Tag: mod_authnz_external-3.2.4~5 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e23e7b76a803f9ce7a175e5b2db912a81d6eec2;p=apache-authnz-external Modified AuthExternal directive to be able to take more than one authenticator name. --- diff --git a/mod_authnz_external/CHANGES b/mod_authnz_external/CHANGES index 7c78996..ca2b2c5 100644 --- a/mod_authnz_external/CHANGES +++ b/mod_authnz_external/CHANGES @@ -1,3 +1,11 @@ +v3.2.4 (Jan Wolter - May 15, 2009) +----------------------------------------------- + * Modified AuthExternal directive to be able to take more than one + authenticator name. If more than one is defined, then each authenticator + is run in turn, until one succeeds or all have failed. Probably a similar + change should be made to GroupExternal, but it hasn't been done yet because + it's a more complex change and nobody has asked for it. + v3.2.3 (Jan Wolter - Feb 26, 2009) ----------------------------------------------- * Added GroupExternalError directive, which allows you to specify the diff --git a/mod_authnz_external/INSTALL b/mod_authnz_external/INSTALL index 5f93d28..9201510 100644 --- a/mod_authnz_external/INSTALL +++ b/mod_authnz_external/INSTALL @@ -402,7 +402,7 @@ instructions to your server configuration. Require valid-user Here identifies what we are authenticating for - it usually - appears in the browser's pop-up login windown. matches a + appears in the browser's pop-up login window. matches a keyword you defined with DefineExternalAuth or AddExternalAuth in step 2. If you only want some users to have access to the directory, as opposed @@ -417,6 +417,16 @@ instructions to your server configuration. Require file-owner + It is possible to list more than one authenticator on the AuthExternal + command: + + AuthExternal ... + + Here each keyword should match an authenticator defined with the + DefineExternalAuth command. If the first authenticator fails, then + the second one will be run, and so on, until either one authenticator + accepts the user's login/password combination or all reject it. + * EXTERNAL GROUP CHECKING: If you want to use the external group check program to allow only @@ -449,6 +459,9 @@ instructions to your server configuration. Require file-group + The GroupExternal cannot (yet?) be used with multiple external + authenticators. + * PASSING CONTEXT INFORMATION INTO AUTHENTICATORS: If you want the authentication to work slightly differently in @@ -551,7 +564,7 @@ instructions to your server configuration. - Miscellaneous odd behaviors. - Did you restart the httpd after the last time you editted the + Did you restart the httpd after the last time you edited the httpd.conf file or recompiled Apache? Confirm that an "Apache configured -- resuming normal operations" message appeared in the error log when you restarted. diff --git a/mod_authnz_external/README b/mod_authnz_external/README index fd4a53a..345626c 100644 --- a/mod_authnz_external/README +++ b/mod_authnz_external/README @@ -1,4 +1,4 @@ - Mod_Authnz_External version 3.2.3 + Mod_Authnz_External version 3.2.4 Original Coder: Nathan Neulinger Previous Maintainer: Tyler Allison diff --git a/mod_authnz_external/mod_authnz_external.c b/mod_authnz_external/mod_authnz_external.c index 2129ea9..867ee4f 100644 --- a/mod_authnz_external/mod_authnz_external.c +++ b/mod_authnz_external/mod_authnz_external.c @@ -115,7 +115,7 @@ module AP_MODULE_DECLARE_DATA authnz_external_module; typedef struct { - char *auth_name; /* Auth keyword for current dir */ + apr_array_header_t *auth_name; /* Auth keyword for current dir */ char *group_name; /* Group keyword for current dir */ char *context; /* Context string from AuthExternalContext */ int authoritative; /* Are we authoritative in current dir? */ @@ -148,7 +148,7 @@ static void *create_authnz_external_dir_config(apr_pool_t *p, char *d) authnz_external_dir_config_rec *dir= (authnz_external_dir_config_rec *) apr_palloc(p, sizeof(authnz_external_dir_config_rec)); - dir->auth_name= NULL; /* no default */ + dir->auth_name= apr_array_make(p,2,sizeof(const char *)); /* no default */ dir->group_name= NULL; /* no default */ dir->context= NULL; /* no default */ dir->authoritative= 1; /* strong by default */ @@ -281,6 +281,19 @@ static const char *set_extgroup_method(cmd_parms *cmd, void *dummy, return NULL; } +/* Append an argument to an array defined by the offset */ +static const char *append_array_slot(cmd_parms *cmd, void *struct_ptr, + const char *arg) +{ + int offset = (int)(long)cmd->info; + apr_array_header_t *array= + *(apr_array_header_t **)((char *)struct_ptr + offset); + + *(const char **)apr_array_push(array)= apr_pstrdup(array->pool, arg); + + return NULL; +} + /* * Config file commands that this module can handle @@ -288,11 +301,11 @@ static const char *set_extgroup_method(cmd_parms *cmd, void *dummy, static const command_rec authnz_external_cmds[] = { - AP_INIT_TAKE1("AuthExternal", - ap_set_string_slot, + AP_INIT_ITERATE("AuthExternal", + append_array_slot, (void *)APR_OFFSETOF(authnz_external_dir_config_rec,auth_name), OR_AUTHCFG, - "a keyword indicating which authenticator to use"), + "one (or more) keywords indicating which authenticators to use"), AP_INIT_TAKE3("DefineExternalAuth", def_extauth, @@ -722,47 +735,53 @@ static int authz_external_check_user_access(request_rec *r) static authn_status authn_external_check_password(request_rec *r, const char *user, const char *password) { - const char *extpath, *extmethod; + const char *extname, *extpath, *extmethod; + int i; authnz_external_dir_config_rec *dir= (authnz_external_dir_config_rec *) ap_get_module_config(r->per_dir_config, &authnz_external_module); authnz_external_svr_config_rec *svr= (authnz_external_svr_config_rec *) ap_get_module_config(r->server->module_config, &authnz_external_module); - const char *extname= dir->auth_name; int code= 1; /* Check if we are supposed to handle this authentication */ - if ( extname == NULL ) + if (dir->auth_name->nelts == 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "No AuthExternal name has been set"); return AUTH_GENERAL_ERROR; } - /* Get the path associated with that external */ - if (!(extpath= apr_table_get(svr->auth_path, extname))) + for (i= 0; i < dir->auth_name->nelts; i++) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Invalid AuthExternal keyword (%s)", extname); - return AUTH_GENERAL_ERROR; - } + extname= ((const char **)dir->auth_name->elts)[i]; - /* Do the authentication, by the requested method */ - extmethod= apr_table_get(svr->auth_method, extname); - if ( extmethod && !strcasecmp(extmethod, "function") ) - code= exec_hardcode(r, extpath, password); - else - code= exec_external(extpath, extmethod, r, ENV_PASS, password); + /* Get the path associated with that external */ + if (!(extpath= apr_table_get(svr->auth_path, extname))) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid AuthExternal keyword (%s)", extname); + return AUTH_GENERAL_ERROR; + } - /* If return code was zero, authentication succeeded */ - if (code == 0) return AUTH_GRANTED; + /* Do the authentication, by the requested method */ + extmethod= apr_table_get(svr->auth_method, extname); + if ( extmethod && !strcasecmp(extmethod, "function") ) + code= exec_hardcode(r, extpath, password); + else + code= exec_external(extpath, extmethod, r, ENV_PASS, password); - /* Otherwise it failed */ - errno= 0; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "AuthExtern %s [%s]: Failed (%d) for user %s", - extname, extpath, code, r->user); + /* If return code was zero, authentication succeeded */ + if (code == 0) return AUTH_GRANTED; + + /* Log a failed authentication */ + errno= 0; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "AuthExtern %s [%s]: Failed (%d) for user %s", + extname, extpath, code, r->user); + } + /* If no authenticators succeed, refuse authentication */ return AUTH_DENIED; }