mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r23704: Add pam_pwd_expire feature as discussed on samba-technical.
This is a slightly modified version to set warn_pwd_expire to the default value if 0, no, or a broken value is set. This version also has one if statement less in get_config_item_int(). Thanks a lot to Andreas 'GlaDiaC' Schneider for this feature!
This commit is contained in:
parent
c85311b3a8
commit
d26914c978
@ -28,5 +28,8 @@
|
|||||||
# (can also take a name)
|
# (can also take a name)
|
||||||
;require_membership_of =
|
;require_membership_of =
|
||||||
|
|
||||||
|
# password expiry warning period in days
|
||||||
|
;warn_pwd_expire = 14
|
||||||
|
|
||||||
# omit pam conversations
|
# omit pam conversations
|
||||||
;silent = no
|
;silent = no
|
||||||
|
@ -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.
|
* @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;
|
int days = 0;
|
||||||
struct tm tm_now, tm_next_change;
|
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) ||
|
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;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +600,7 @@ static BOOL _pam_send_password_expiry_message(pam_handle_t *pamh, int ctrl, time
|
|||||||
return True;
|
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",
|
_make_remark_format(pamh, ctrl, PAM_TEXT_INFO, "Your password will expire in %d %s",
|
||||||
days, (days > 1) ? "days":"day");
|
days, (days > 1) ? "days":"day");
|
||||||
return True;
|
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,
|
static void _pam_warn_password_expiry(pam_handle_t *pamh,
|
||||||
int flags,
|
int flags,
|
||||||
const struct winbindd_response *response,
|
const struct winbindd_response *response,
|
||||||
|
int warn_pwd_expire,
|
||||||
BOOL *already_expired)
|
BOOL *already_expired)
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
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 */
|
/* check if the info3 must change timestamp has been set */
|
||||||
next_change = response->data.auth.info3.pass_must_change_time;
|
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)) {
|
already_expired)) {
|
||||||
return;
|
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 +
|
next_change = response->data.auth.info3.pass_last_set_time +
|
||||||
response->data.auth.policy.expire;
|
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)) {
|
already_expired)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1029,6 +1037,7 @@ static int winbind_auth_request(pam_handle_t * pamh,
|
|||||||
const char *pass,
|
const char *pass,
|
||||||
const char *member,
|
const char *member,
|
||||||
const char *cctype,
|
const char *cctype,
|
||||||
|
const int warn_pwd_expire,
|
||||||
struct winbindd_response *p_response,
|
struct winbindd_response *p_response,
|
||||||
time_t *pwd_last_set,
|
time_t *pwd_last_set,
|
||||||
char **user_ret)
|
char **user_ret)
|
||||||
@ -1134,7 +1143,9 @@ static int winbind_auth_request(pam_handle_t * pamh,
|
|||||||
if (ret == PAM_SUCCESS) {
|
if (ret == PAM_SUCCESS) {
|
||||||
|
|
||||||
/* warn a user if the password is about to expire soon */
|
/* 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) {
|
if (already_expired == True) {
|
||||||
_pam_log_debug(pamh, ctrl, LOG_DEBUG, "Password has expired "
|
_pam_log_debug(pamh, ctrl, LOG_DEBUG, "Password has expired "
|
||||||
@ -1519,6 +1530,52 @@ out:
|
|||||||
return parm_opt;
|
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)
|
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);
|
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);
|
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
|
PAM_EXTERN
|
||||||
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
||||||
int argc, const char **argv)
|
int argc, const char **argv)
|
||||||
@ -1542,6 +1615,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
|||||||
const char *password;
|
const char *password;
|
||||||
const char *member = NULL;
|
const char *member = NULL;
|
||||||
const char *cctype = NULL;
|
const char *cctype = NULL;
|
||||||
|
int warn_pwd_expire;
|
||||||
int retval = PAM_AUTH_ERR;
|
int retval = PAM_AUTH_ERR;
|
||||||
dictionary *d = NULL;
|
dictionary *d = NULL;
|
||||||
char *username_ret = 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);
|
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 */
|
/* Now use the username to look up password */
|
||||||
retval = winbind_auth_request(pamh, ctrl, username, password, member,
|
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 ||
|
if (retval == PAM_NEW_AUTHTOK_REQD ||
|
||||||
retval == PAM_AUTHTOK_EXPIRED) {
|
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 */
|
/* verify that this is the password for this user */
|
||||||
|
|
||||||
ret = winbind_auth_request(pamh, ctrl, user, pass_old,
|
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 &&
|
if (ret != PAM_ACCT_EXPIRED &&
|
||||||
ret != PAM_AUTHTOK_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 *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 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,
|
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_new);
|
||||||
_pam_overwrite(pass_old);
|
_pam_overwrite(pass_old);
|
||||||
pass_old = pass_new = NULL;
|
pass_old = pass_new = NULL;
|
||||||
@ -2166,7 +2249,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
|
|||||||
if (ret == PAM_SUCCESS) {
|
if (ret == PAM_SUCCESS) {
|
||||||
|
|
||||||
/* warn a user if the password is about to expire soon */
|
/* 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 */
|
/* set some info3 info for other modules in the stack */
|
||||||
_pam_set_data_info3(pamh, ctrl, &response);
|
_pam_set_data_info3(pamh, ctrl, &response);
|
||||||
|
@ -116,7 +116,7 @@ do { \
|
|||||||
|
|
||||||
#define SECONDS_PER_DAY 86400
|
#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"
|
#include "winbind_client.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user