summaryrefslogtreecommitdiff
path: root/source3/nsswitch/pam_winbind.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2007-02-22 13:35:01 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:08 -0500
commit9684e353a16cd18424f5b35a5d84ae3c2a03ae70 (patch)
treef254fcf8660eb7988d1b1f58168f1fbd7df7f81a /source3/nsswitch/pam_winbind.c
parentca229b0980b5c78f140180db764b3229d5ccb078 (diff)
downloadsamba-9684e353a16cd18424f5b35a5d84ae3c2a03ae70.tar.gz
samba-9684e353a16cd18424f5b35a5d84ae3c2a03ae70.tar.bz2
samba-9684e353a16cd18424f5b35a5d84ae3c2a03ae70.zip
r21500: Fix inappropriate creation of a krb5 ticket refreshing event when a user
changed a password via pam_chauthtok. Only do this if a) a user logs on using an expired password (or a password that needs to be changed immediately) or b) the user itself changes his password. Also make sure to delete the in-memory krb5 credential cache (when a user did not request a FILE based cred cache). Finally honor the krb5 settings in the first pam authentication in the chauthtok block (PAM_PRELIM_CHECK). This circumvents confusion when NTLM samlogon authentication is still possible with the old password after the password has been already changed (on w2k3 sp1 dcs). Guenther (This used to be commit c3005c48cd86bc1dd17fab80da05c2d34071b872)
Diffstat (limited to 'source3/nsswitch/pam_winbind.c')
-rw-r--r--source3/nsswitch/pam_winbind.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index d2979ed71c..ac87fcf32e 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -198,6 +198,7 @@ static void _pam_log_state(const pam_handle_t *pamh, int ctrl)
_PAM_LOG_STATE_DATA_STRING(pamh, ctrl, PAM_WINBIND_LOGONSERVER);
_PAM_LOG_STATE_DATA_STRING(pamh, ctrl, PAM_WINBIND_PROFILEPATH);
_PAM_LOG_STATE_DATA_STRING(pamh, ctrl, PAM_WINBIND_NEW_AUTHTOK_REQD); /* Use atoi to get PAM result code */
+ _PAM_LOG_STATE_DATA_STRING(pamh, ctrl, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH);
_PAM_LOG_STATE_DATA_POINTER(pamh, ctrl, PAM_WINBIND_PWD_LAST_SET);
}
@@ -1564,6 +1565,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
if (retval == PAM_NEW_AUTHTOK_REQD ||
retval == PAM_AUTHTOK_EXPIRED) {
+ char *new_authtok_required_during_auth = NULL;
+
if (!asprintf(&new_authtok_required, "%d", retval)) {
retval = PAM_BUF_ERR;
goto out;
@@ -1572,6 +1575,15 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, new_authtok_required, _pam_winbind_cleanup_func);
retval = PAM_SUCCESS;
+
+ if (!asprintf(&new_authtok_required_during_auth, "%d", True)) {
+ retval = PAM_BUF_ERR;
+ goto out;
+ }
+
+ pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
+ new_authtok_required_during_auth, _pam_winbind_cleanup_func);
+
goto out;
}
@@ -1851,6 +1863,49 @@ out:
return retval;
}
+/**
+ * evaluate whether we need to re-authenticate with kerberos after a password change
+ *
+ * @param pamh PAM handle
+ * @param ctrl PAM winbind options.
+ * @param user The username
+ *
+ * @return boolean Returns True if required, False if not.
+ */
+
+static BOOL _pam_require_krb5_auth_after_chauthtok(pam_handle_t *pamh, int ctrl, const char *user)
+{
+
+ /* Make sure that we only do this if
+ * a) the chauthtok got initiated during a logon attempt (authenticate->acct_mgmt->chauthtok)
+ * b) any later password change via the "passwd" command if done by the user itself
+ */
+
+ char *new_authtok_reqd_during_auth = NULL;
+ struct passwd *pwd = NULL;
+
+ if (!(ctrl & WINBIND_KRB5_AUTH)) {
+ return False;
+ }
+
+ _pam_get_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH, &new_authtok_reqd_during_auth);
+ pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH, NULL, NULL);
+
+ if (new_authtok_reqd_during_auth) {
+ return True;
+ }
+
+ pwd = getpwnam(user);
+ if (!pwd) {
+ return False;
+ }
+
+ if (getuid() == pwd->pw_uid) {
+ return True;
+ }
+
+ return False;
+}
PAM_EXTERN
@@ -1948,9 +2003,6 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
goto out;
}
- /* We don't need krb5 env set for password change test. */
- ctrl &= ~WINBIND_KRB5_AUTH;
-
/* verify that this is the password for this user */
ret = winbind_auth_request(pamh, ctrl, user, pass_old,
@@ -2042,9 +2094,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
goto out;
}
- /* just in case we need krb5 creds after a password change over msrpc */
-
- if (ctrl & WINBIND_KRB5_AUTH) {
+ if (_pam_require_krb5_auth_after_chauthtok(pamh, ctrl, user)) {
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);