diff options
author | Jan Pazdziora <jpazdziora@redhat.com> | 2022-01-23 09:04:21 +0100 |
---|---|---|
committer | Jan Pazdziora <jpazdziora@redhat.com> | 2022-01-23 09:52:22 +0100 |
commit | 3575243b49923894bea86f74f5c4ae31793b8479 (patch) | |
tree | 65c976d1a53f2a330571779d8c56a0155c8d9f8d | |
parent | 79170d640088d972e0853269715ef419038b8b4c (diff) | |
download | mod_authnz_pam-3575243b49923894bea86f74f5c4ae31793b8479.tar.gz mod_authnz_pam-3575243b49923894bea86f74f5c4ae31793b8479.tar.xz mod_authnz_pam-3575243b49923894bea86f74f5c4ae31793b8479.zip |
Change default redirect status for AuthPAMExpiredRedirect to 303 See Other, make it configurable.
Redirect to reset password typically goes to different system,
so repeating for example POST which 307 Temporary Redirect does
is not that useful; the 303 See Other will do plain GET.
The redirect status can be overriden with an optional second parameter
to AuthPAMExpiredRedirect.
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | mod_authnz_pam.c | 48 | ||||
-rw-r--r-- | tests/auth.conf | 10 | ||||
-rwxr-xr-x | tests/run.sh | 3 |
4 files changed, 52 insertions, 14 deletions
@@ -95,7 +95,7 @@ two separate account PAM checks during the Basic Authentication. Handling expired password: - AuthPAMExpiredRedirect <URL> + AuthPAMExpiredRedirect <URL> [<status>] For both the authorization and HTTP Basic authentication case, if the password the user has presented has expired (PAM return codes @@ -117,6 +117,9 @@ For example for FreeIPA 4.1+, the value can actually be https://<IPA-server>/ipa/ui/reset_password.html?url=%s +By default the redirect is done using 303 See Other. The redirect +status can be specified as numerical value in the 3xx range. + SELinux: On SELinux enabled systems, boolean httpd_mod_auth_pam needs to diff --git a/mod_authnz_pam.c b/mod_authnz_pam.c index 7da820f..71db4ea 100644 --- a/mod_authnz_pam.c +++ b/mod_authnz_pam.c @@ -32,9 +32,16 @@ #include "mod_auth.h" +#ifdef APLOG_USE_MODULE +#define SHOW_MODULE "" +#else +#define SHOW_MODULE "mod_authnz_pam: " +#endif + typedef struct { char * pam_service; char * expired_redirect_url; + int expired_redirect_status; } authnz_pam_config_rec; static void * create_dir_conf(apr_pool_t * pool, char * dir) { @@ -42,13 +49,36 @@ static void * create_dir_conf(apr_pool_t * pool, char * dir) { return cfg; } +static const char * set_redirect_and_status(cmd_parms * cmd, void * conf_void, char * url, char * status) { + authnz_pam_config_rec * cfg = (authnz_pam_config_rec *) conf_void; + if (cfg) { + cfg->expired_redirect_url = apr_pstrdup(cmd->pool, url); + cfg->expired_redirect_status = HTTP_SEE_OTHER; + if (status) { + cfg->expired_redirect_status = apr_atoi64(status); + if (cfg->expired_redirect_status == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + SHOW_MODULE "AuthPAMExpiredRedirect status has to be a number, setting to %d", + HTTP_SEE_OTHER); + cfg->expired_redirect_status = HTTP_SEE_OTHER; + } else if (cfg->expired_redirect_status < 300 || cfg->expired_redirect_status > 399) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + SHOW_MODULE "AuthPAMExpiredRedirect status has to be in the 3xx range, setting to %d", + HTTP_SEE_OTHER); + cfg->expired_redirect_status = HTTP_SEE_OTHER; + } + } + } + return NULL; +} + static const command_rec authnz_pam_cmds[] = { AP_INIT_TAKE1("AuthPAMService", ap_set_string_slot, (void *)APR_OFFSETOF(authnz_pam_config_rec, pam_service), OR_AUTHCFG, "PAM service to authenticate against"), - AP_INIT_TAKE1("AuthPAMExpiredRedirect", ap_set_string_slot, - (void *)APR_OFFSETOF(authnz_pam_config_rec, expired_redirect_url), - OR_AUTHCFG, "URL to redirect to user credentials expired have expired"), + AP_INIT_TAKE12("AuthPAMExpiredRedirect", set_redirect_and_status, + NULL, + ACCESS_CONF|OR_AUTHCFG, "URL (and optional status) to redirect to should user have expired credentials"), {NULL} }; @@ -138,12 +168,6 @@ static const char * format_location(request_rec * r, const char * url, const cha module AP_MODULE_DECLARE_DATA authnz_pam_module; -#ifdef APLOG_USE_MODULE -#define SHOW_MODULE "" -#else -#define SHOW_MODULE "mod_authnz_pam: " -#endif - #if AP_MODULE_MAGIC_AT_LEAST(20100625,0) static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL; @@ -210,10 +234,10 @@ static authn_status pam_authenticate_with_login_password(request_rec * r, const authnz_pam_config_rec * conf = ap_get_module_config(r->per_dir_config, &authnz_pam_module); if (conf && conf->expired_redirect_url) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - SHOW_MODULE "PAM_NEW_AUTHTOK_REQD: redirect to [%s]", - conf->expired_redirect_url); + SHOW_MODULE "PAM_NEW_AUTHTOK_REQD: redirect to [%s] using [%d]", + conf->expired_redirect_url, conf->expired_redirect_status); apr_table_addn(r->headers_out, "Location", format_location(r, conf->expired_redirect_url, login)); - r->status = HTTP_TEMPORARY_REDIRECT; + r->status = conf->expired_redirect_status; ap_send_error_response(r, 0); return AUTH_DENIED; } diff --git a/tests/auth.conf b/tests/auth.conf index 2ee519e..c728d91 100644 --- a/tests/auth.conf +++ b/tests/auth.conf @@ -54,3 +54,13 @@ ScriptAlias /authnp4 /var/www/cgi-bin/auth.cgi AuthPAMExpiredRedirect http://localhost/fix-password?return=%s&percent=%%&user=%u Require pam-account webl </LocationMatch> + +ScriptAlias /authnp5 /var/www/cgi-bin/auth.cgi +<LocationMatch ^/authnp5> + AuthType Basic + AuthName "private area" + AuthBasicProvider PAM + AuthPAMService webl + AuthPAMExpiredRedirect http://localhost/login?realm=ježek&return=%s 307 + Require pam-account webl +</LocationMatch> diff --git a/tests/run.sh b/tests/run.sh index 28235f8..3b24f9b 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -55,7 +55,8 @@ curl -u user1:heslo1 -s http://localhost/authnp3 | tee /dev/stderr | grep 'User curl -u user1:heslo1 -s http://localhost/authnp4 | tee /dev/stderr | grep 'User user1' chage -d $(date -d -2days +%Y-%m-%d) -M 1 user1 curl -u user1:heslo1 -s http://localhost/authnp3 | tee /dev/stderr | grep 401 -curl -i -u user1:heslo1 -s 'http://localhost/authnp4?id=123&data=M%26M' | tee /dev/stderr | grep -F -e 'Location: http://localhost/fix-password?return=http%3a%2f%2flocalhost%2fauthnp4%3fid%3d123%26data%3dM%2526M&percent=%25&user=user1' -e 'HTTP/1.1 307 Temporary Redirect' | wc -l | grep 2 +curl -i -u user1:heslo1 -s 'http://localhost/authnp4?id=123&data=M%26M' | tee /dev/stderr | grep -F -e 'Location: http://localhost/fix-password?return=http%3a%2f%2flocalhost%2fauthnp4%3fid%3d123%26data%3dM%2526M&percent=%25&user=user1' -e 'HTTP/1.1 303 See Other' | wc -l | grep 2 +curl -i -u user1:heslo1 -s 'http://localhost/authnp5?data=křížala' | tee /dev/stderr | grep -F -e 'Location: http://localhost/login?realm=ježek&return=http%3a%2f%2flocalhost%2fauthnp5%3fdata%3dk%c5%99%c3%ad%c5%beala' -e 'HTTP/1.1 307 Temporary Redirect' | wc -l | grep 2 chage -d $(date -d -2days +%Y-%m-%d) -M 3 user1 curl -u user1:heslo1 -s http://localhost/authnp3 | tee /dev/stderr | grep 'User user1' curl -u user1:heslo1 -s http://localhost/authnp4 | tee /dev/stderr | grep 'User user1' |