summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Pazdziora <jpazdziora@redhat.com>2022-01-23 09:04:21 +0100
committerJan Pazdziora <jpazdziora@redhat.com>2022-01-23 09:52:22 +0100
commit3575243b49923894bea86f74f5c4ae31793b8479 (patch)
tree65c976d1a53f2a330571779d8c56a0155c8d9f8d
parent79170d640088d972e0853269715ef419038b8b4c (diff)
downloadmod_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--README5
-rw-r--r--mod_authnz_pam.c48
-rw-r--r--tests/auth.conf10
-rwxr-xr-xtests/run.sh3
4 files changed, 52 insertions, 14 deletions
diff --git a/README b/README
index 96b7575..e1db8e6 100644
--- a/README
+++ b/README
@@ -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'