return pam_winbind_request_log(ctx, ret, username, fn);
}
+static bool _pam_winbind_change_pwd(struct pwb_context *ctx)
+{
+ struct pam_message msg, *pmsg;
+ struct pam_response *resp = NULL;
+ const char *prompt;
+ int ret;
+ bool retval = false;
+ prompt = _("Do you want to change your password now?");
+ pmsg = &msg;
+ msg.msg_style = PAM_RADIO_TYPE;
+ msg.msg = prompt;
+ ret = converse(ctx->pamh, 1, &pmsg, &resp);
+ if (resp == NULL) {
+ if (ret == PAM_SUCCESS) {
+ _pam_log(ctx, LOG_CRIT, "pam_winbind: system error!\n");
+ return false;
+ }
+ }
+ if (ret != PAM_SUCCESS) {
+ return false;
+ }
+ _pam_log(ctx, LOG_CRIT, "Received [%s] reply from application.\n", resp->resp);
+
+ if (strcasecmp(resp->resp, "yes") == 0) {
+ retval = true;
+ }
+
+ _pam_drop_reply(resp, 1);
+ return retval;
+}
+
/**
* send a password expiry message if required
time_t next_change,
time_t now,
int warn_pwd_expire,
- bool *already_expired)
+ bool *already_expired,
+ bool *change_pwd)
{
int days = 0;
struct tm tm_now, tm_next_change;
+ bool retval = false;
+ int ret;
if (already_expired) {
*already_expired = false;
}
+ if (change_pwd) {
+ *change_pwd = false;
+ }
+
if (next_change <= now) {
PAM_WB_REMARK_DIRECT(ctx, "NT_STATUS_PASSWORD_EXPIRED");
if (already_expired) {
(tm_now.tm_yday+tm_now.tm_year*365);
if (days == 0) {
- _make_remark(ctx, PAM_TEXT_INFO,
- _("Your password expires today"));
+ ret = _make_remark(ctx, PAM_TEXT_INFO,
+ _("Your password expires today.\n"));
+
+ /*
+ * If change_pwd and already_expired is null.
+ * We are just sending a notification message.
+ * We don't expect any response in this case.
+ */
+
+ if (!change_pwd && !already_expired) {
+ return true;
+ }
+
+ /*
+ * successfully sent the warning message.
+ * Give the user a chance to change pwd.
+ */
+ if (ret == PAM_SUCCESS) {
+ if (change_pwd) {
+ retval = _pam_winbind_change_pwd(ctx);
+ if (retval) {
+ *change_pwd = true;
+ }
+ }
+ }
return true;
}
if (days > 0 && days < warn_pwd_expire) {
- _make_remark_format(ctx, PAM_TEXT_INFO,
- _("Your password will expire in %d %s"),
- days, (days > 1) ? _("days"):_("day"));
+
+ ret = _make_remark_format(ctx, PAM_TEXT_INFO,
+ _("Your password will expire in %d %s.\n"),
+ days, (days > 1) ? _("days"):_("day"));
+ /*
+ * If change_pwd and already_expired is null.
+ * We are just sending a notification message.
+ * We don't expect any response in this case.
+ */
+
+ if (!change_pwd && !already_expired) {
+ return true;
+ }
+
+ /*
+ * successfully sent the warning message.
+ * Give the user a chance to change pwd.
+ */
+ if (ret == PAM_SUCCESS) {
+ if (change_pwd) {
+ retval = _pam_winbind_change_pwd(ctx);
+ if (retval) {
+ *change_pwd = true;
+ }
+ }
+ }
return true;
}
const struct wbcAuthUserInfo *info,
const struct wbcUserPasswordPolicyInfo *policy,
int warn_pwd_expire,
- bool *already_expired)
+ bool *already_expired,
+ bool *change_pwd)
{
time_t now = time(NULL);
time_t next_change = 0;
*already_expired = false;
}
+ if (change_pwd) {
+ *change_pwd = false;
+ }
+
/* accounts with WBC_ACB_PWNOEXP set never receive a warning */
if (info->acct_flags & WBC_ACB_PWNOEXP) {
return;
if (_pam_send_password_expiry_message(ctx, next_change, now,
warn_pwd_expire,
- already_expired)) {
+ already_expired,
+ change_pwd)) {
return;
}
if (_pam_send_password_expiry_message(ctx, next_change, now,
warn_pwd_expire,
- already_expired)) {
+ already_expired,
+ change_pwd)) {
return;
}
if ((ret == PAM_SUCCESS) && user_info && policy && info) {
bool already_expired = false;
+ bool change_pwd = false;
/* warn a user if the password is about to expire soon */
_pam_warn_password_expiry(ctx, user_info, policy,
warn_pwd_expire,
- &already_expired);
+ &already_expired,
+ &change_pwd);
if (already_expired == true) {
return PAM_AUTHTOK_EXPIRED;
}
+ if (change_pwd) {
+ ret = PAM_NEW_AUTHTOK_REQD;
+ goto done;
+ }
+
/* inform about logon type */
_pam_warn_logon_type(ctx, user, user_info->user_flags);
* expire soon */
_pam_warn_password_expiry(ctx, user_info, policy,
warn_pwd_expire,
- NULL);
+ NULL, NULL);
/* set some info3 info for other modules in the
* stack */