summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/pam_winbind/pam_winbind.conf3
-rw-r--r--source3/nsswitch/pam_winbind.c104
-rw-r--r--source3/nsswitch/pam_winbind.h2
3 files changed, 98 insertions, 11 deletions
diff --git a/examples/pam_winbind/pam_winbind.conf b/examples/pam_winbind/pam_winbind.conf
index 8caf02d0d0..a9e02a833a 100644
--- a/examples/pam_winbind/pam_winbind.conf
+++ b/examples/pam_winbind/pam_winbind.conf
@@ -28,5 +28,8 @@
# (can also take a name)
;require_membership_of =
+# password expiry warning period in days
+;warn_pwd_expire = 14
+
# omit pam conversations
;silent = no
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 81b9c0bc6c..836822a8a9 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -561,7 +561,12 @@ static int pam_winbind_request_log(pam_handle_t * pamh,
* @return boolean Returns True if message has been sent, False if not.
*/
-static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time_t next_change, time_t now, BOOL *already_expired)
+static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh,
+ int ctrl,
+ time_t next_change,
+ time_t now,
+ int warn_pwd_expire,
+ BOOL *already_expired)
{
int days = 0;
struct tm tm_now, tm_next_change;
@@ -579,7 +584,7 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time
}
if ((next_change < 0) ||
- (next_change > now + DAYS_TO_WARN_BEFORE_PWD_EXPIRES * SECONDS_PER_DAY)) {
+ (next_change > now + warn_pwd_expire * SECONDS_PER_DAY)) {
return False;
}
@@ -595,7 +600,7 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time
return True;
}
- if (days > 0 && days < DAYS_TO_WARN_BEFORE_PWD_EXPIRES) {
+ if (days > 0 && days < warn_pwd_expire) {
_make_remark_format(pamh, ctrl, PAM_TEXT_INFO, "Your password will expire in %d %s",
days, (days > 1) ? "days":"day");
return True;
@@ -618,6 +623,7 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time
static void _pam_warn_password_expiry(pam_handle_t *pamh,
int flags,
const struct winbindd_response *response,
+ int warn_pwd_expire,
BOOL *already_expired)
{
time_t now = time(NULL);
@@ -640,7 +646,8 @@ static void _pam_warn_password_expiry(pam_handle_t *pamh,
/* check if the info3 must change timestamp has been set */
next_change = response->data.auth.info3.pass_must_change_time;
- if (_pam_send_password_expiry_message(pamh, flags, next_change, now,
+ if (_pam_send_password_expiry_message(pamh, flags, next_change, now,
+ warn_pwd_expire,
already_expired)) {
return;
}
@@ -655,7 +662,8 @@ static void _pam_warn_password_expiry(pam_handle_t *pamh,
next_change = response->data.auth.info3.pass_last_set_time +
response->data.auth.policy.expire;
- if (_pam_send_password_expiry_message(pamh, flags, next_change, now,
+ if (_pam_send_password_expiry_message(pamh, flags, next_change, now,
+ warn_pwd_expire,
already_expired)) {
return;
}
@@ -1029,6 +1037,7 @@ static int winbind_auth_request(pam_handle_t * pamh,
const char *pass,
const char *member,
const char *cctype,
+ const int warn_pwd_expire,
struct winbindd_response *p_response,
time_t *pwd_last_set,
char **user_ret)
@@ -1134,7 +1143,9 @@ static int winbind_auth_request(pam_handle_t * pamh,
if (ret == PAM_SUCCESS) {
/* warn a user if the password is about to expire soon */
- _pam_warn_password_expiry(pamh, ctrl, &response, &already_expired);
+ _pam_warn_password_expiry(pamh, ctrl, &response,
+ warn_pwd_expire,
+ &already_expired);
if (already_expired == True) {
_pam_log_debug(pamh, ctrl, LOG_DEBUG, "Password has expired "
@@ -1519,6 +1530,52 @@ out:
return parm_opt;
}
+int get_config_item_int(const pam_handle_t *pamh,
+ int argc,
+ const char **argv,
+ int ctrl,
+ dictionary *d,
+ const char *item)
+{
+ int parm_opt = -1, i = 0;
+ char *key = NULL;
+
+ /* let the pam opt take precedence over the pam_winbind.conf option */
+ for (i = 0; i < argc; i++) {
+
+ if ((strncmp(argv[i], item, strlen(item)) == 0)) {
+ char *p;
+
+ if ( (p = strchr( argv[i], '=' )) == NULL) {
+ _pam_log(pamh, ctrl, LOG_INFO,
+ "no \"=\" delimiter for \"%s\" found\n",
+ item);
+ goto out;
+ }
+ parm_opt = atoi(p + 1);
+ _pam_log_debug(pamh, ctrl, LOG_INFO,
+ "PAM config: %s '%d'\n",
+ item, parm_opt);
+ return parm_opt;
+ }
+ }
+
+ if (d != NULL) {
+ if (!asprintf(&key, "global:%s", item)) {
+ goto out;
+ }
+
+ parm_opt = iniparser_getint(d, key, -1);
+ SAFE_FREE(key);
+
+ _pam_log_debug(pamh, ctrl, LOG_INFO,
+ "CONFIG file: %s '%d'\n",
+ item, parm_opt);
+ }
+out:
+ return parm_opt;
+}
+
const char *get_krb5_cc_type_from_config(const pam_handle_t *pamh, int argc, const char **argv, int ctrl, dictionary *d)
{
return get_conf_item_string(pamh, argc, argv, ctrl, d, "krb5_ccache_type", WINBIND_KRB5_CCACHE_TYPE);
@@ -1534,6 +1591,22 @@ const char *get_member_from_config(const pam_handle_t *pamh, int argc, const cha
return get_conf_item_string(pamh, argc, argv, ctrl, d, "require-membership-of", WINBIND_REQUIRED_MEMBERSHIP);
}
+int get_warn_pwd_expire_from_config(const pam_handle_t *pamh,
+ int argc,
+ const char **argv,
+ int ctrl,
+ dictionary *d)
+{
+ int ret;
+ ret = get_config_item_int(pamh, argc, argv, ctrl, d,
+ "warn_pwd_expire");
+ /* no or broken setting */
+ if (ret <= 0) {
+ return DEFAULT_DAYS_TO_WARN_BEFORE_PWD_EXPIRES;
+ }
+ return ret;
+}
+
PAM_EXTERN
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char **argv)
@@ -1542,6 +1615,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
const char *password;
const char *member = NULL;
const char *cctype = NULL;
+ int warn_pwd_expire;
int retval = PAM_AUTH_ERR;
dictionary *d = NULL;
char *username_ret = NULL;
@@ -1612,9 +1686,13 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
cctype = get_krb5_cc_type_from_config(pamh, argc, argv, ctrl, d);
+ warn_pwd_expire = get_warn_pwd_expire_from_config(pamh, argc, argv,
+ ctrl, d);
+
/* Now use the username to look up password */
retval = winbind_auth_request(pamh, ctrl, username, password, member,
- cctype, NULL, NULL, &username_ret);
+ cctype, warn_pwd_expire, NULL, NULL,
+ &username_ret);
if (retval == PAM_NEW_AUTHTOK_REQD ||
retval == PAM_AUTHTOK_EXPIRED) {
@@ -2064,7 +2142,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
/* verify that this is the password for this user */
ret = winbind_auth_request(pamh, ctrl, user, pass_old,
- NULL, NULL, &response, &pwdlastset_prelim, NULL);
+ NULL, NULL, 0, &response,
+ &pwdlastset_prelim, NULL);
if (ret != PAM_ACCT_EXPIRED &&
ret != PAM_AUTHTOK_EXPIRED &&
@@ -2156,9 +2235,13 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
const char *member = get_member_from_config(pamh, argc, argv, ctrl, d);
const char *cctype = get_krb5_cc_type_from_config(pamh, argc, argv, ctrl, d);
+ const int warn_pwd_expire =
+ get_warn_pwd_expire_from_config(pamh, argc, argv, ctrl,
+ d);
ret = winbind_auth_request(pamh, ctrl, user, pass_new,
- member, cctype, &response, NULL, &username_ret);
+ member, cctype, 0, &response,
+ NULL, &username_ret);
_pam_overwrite(pass_new);
_pam_overwrite(pass_old);
pass_old = pass_new = NULL;
@@ -2166,7 +2249,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
if (ret == PAM_SUCCESS) {
/* warn a user if the password is about to expire soon */
- _pam_warn_password_expiry(pamh, ctrl, &response, NULL);
+ _pam_warn_password_expiry(pamh, ctrl, &response,
+ warn_pwd_expire , NULL);
/* set some info3 info for other modules in the stack */
_pam_set_data_info3(pamh, ctrl, &response);
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
index 0e7688be15..159cb28059 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -116,7 +116,7 @@ do { \
#define SECONDS_PER_DAY 86400
-#define DAYS_TO_WARN_BEFORE_PWD_EXPIRES 5
+#define DEFAULT_DAYS_TO_WARN_BEFORE_PWD_EXPIRES 14
#include "winbind_client.h"