summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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'