From 8d639be6897b31d69389f03d0d5679aadaa76b11 Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 2 Dec 2016 07:23:25 -0700 Subject: [PATCH] s3:winbindd: Active Directory account locked when using winbind refresh tickets This is to resolve an issue where user accounts get locked out due to winbind refreshing tickets using cached passwords (after the password has been modified, but the wrong password is still cached). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12443 Signed-off-by: David Mulder --- docs-xml/smbdotconf/winbind/winbindpasswordkinit.xml | 18 ++++++++++++++++++ source3/param/loadparm.c | 2 ++ source3/winbindd/winbindd_cred_cache.c | 19 +++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 docs-xml/smbdotconf/winbind/winbindpasswordkinit.xml diff --git a/docs-xml/smbdotconf/winbind/winbindpasswordkinit.xml b/docs-xml/smbdotconf/winbind/winbindpasswordkinit.xml new file mode 100644 index 00000000000..8ee2961a017 --- /dev/null +++ b/docs-xml/smbdotconf/winbind/winbindpasswordkinit.xml @@ -0,0 +1,18 @@ + + + + This parameter controls which user for which Winbind will use + cached passwords to refresh Kerberos Tickets retrieved using the + pam_winbind module. This option + requires that also be + enabled. + + + + +* +tux, affe + diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 096c23f4fb3..293633bdd9e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -821,6 +821,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.winbind_expand_groups = 0; Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL); Globals.winbind_refresh_tickets = false; + Globals.winbind_password_kinit = + str_list_make_v3_const(NULL, "*", NULL); Globals.winbind_offline_logon = false; Globals.winbind_scan_trusted_domains = true; diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c index 5e019dfce0c..40fc916c2e7 100644 --- a/source3/winbindd/winbindd_cred_cache.c +++ b/source3/winbindd/winbindd_cred_cache.c @@ -128,11 +128,19 @@ static void krb5_ticket_refresh_handler(struct tevent_context *event_ctx, /* Kinit again if we have the user password and we can't renew the old * tgt anymore * NB - * This happens when machine are put to sleep for a very long time. */ + * This happens when machines are put to sleep for a very long time. + * + * Optionally disable this, since using cached passwords to kinit can + * lockout a user account if their password has changed. */ if (entry->renew_until < time(NULL)) { rekinit: - if (cred_ptr && cred_ptr->pass) { + const char **pwd_users = lp_winbind_password_kinit(); + int len_pwd_users = str_list_length(pwd_users); + + if (cred_ptr && cred_ptr->pass && + ((len_pwd_users == 1 && str_list_check(pwd_users, "*")) || + (str_list_check(pwd_users, entry->principal_name)))) { set_effective_uid(entry->uid); @@ -308,6 +316,8 @@ static void krb5_ticket_gain_handler(struct tevent_context *event_ctx, struct timeval t; struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr; struct winbindd_domain *domain = NULL; + const char **pwd_users = lp_winbind_password_kinit(); + int len_pwd_users = str_list_length(pwd_users); #endif DBG_DEBUG("event called for: %s, %s\n", @@ -317,6 +327,11 @@ static void krb5_ticket_gain_handler(struct tevent_context *event_ctx, #ifdef HAVE_KRB5 + if ((len_pwd_users == 1 && str_list_check(pwd_users, "*")) || + str_list_check(pwd_users, entry->principal_name)) { + return; + } + if (!cred_ptr || !cred_ptr->pass) { DEBUG(10,("krb5_ticket_gain_handler: no memory creds\n")); return;