summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_netlogon.h1
-rw-r--r--source3/nsswitch/pam_winbind.c27
-rw-r--r--source3/nsswitch/pam_winbind.h2
-rw-r--r--source3/nsswitch/winbindd_pam.c8
4 files changed, 38 insertions, 0 deletions
diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h
index 5c9e4c00d7..7bbd9cc1cb 100644
--- a/source3/include/rpc_netlogon.h
+++ b/source3/include/rpc_netlogon.h
@@ -89,6 +89,7 @@
#define LOGON_RESOURCE_GROUPS 0x00000200
#define LOGON_PROFILE_PATH_RETURNED 0x00000400
#define LOGON_GRACE_LOGON 0x01000000
+#define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000
#define SE_GROUP_MANDATORY 0x00000001
#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index ec6361e52b..6734cba0c4 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -928,6 +928,30 @@ static void _pam_warn_logon_type(pam_handle_t *pamh, int ctrl, const char *usern
}
/**
+ * Send PAM_ERROR_MSG for krb5 errors.
+ *
+ * @param pamh PAM handle
+ * @param ctrl PAM winbind options.
+ * @param username User in PAM request.
+ * @param info3_user_flgs Info3 flags containing logon type bits.
+ *
+ * @return void.
+ */
+
+static void _pam_warn_krb5_failure(pam_handle_t *pamh, int ctrl, const char *username, uint32 info3_user_flgs)
+{
+ if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "Failed to establish your Kerberos Ticket cache "
+ "due time differences\n"
+ "with the domain controller. "
+ "Please verify the system time.\n");
+ _pam_log_debug(pamh, ctrl, LOG_DEBUG,
+ "User %s: Clock skew when getting Krb5 TGT\n", username);
+ }
+}
+
+/**
* Compose Password Restriction String for a PAM_ERROR_MSG conversation.
*
* @param response The struct winbindd_response.
@@ -1125,6 +1149,9 @@ static int winbind_auth_request(pam_handle_t * pamh,
/* inform about logon type */
_pam_warn_logon_type(pamh, ctrl, user, response.data.auth.info3.user_flgs);
+ /* inform about krb5 failures */
+ _pam_warn_krb5_failure(pamh, ctrl, user, response.data.auth.info3.user_flgs);
+
/* 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 73da2826ca..9015869a77 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -184,6 +184,8 @@ do { \
/* from include/rpc_netlogon.h */
#define LOGON_CACHED_ACCOUNT 0x00000004
#define LOGON_GRACE_LOGON 0x01000000
+#define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000
#define PAM_WB_CACHED_LOGON(x) (x & LOGON_CACHED_ACCOUNT)
+#define PAM_WB_KRB5_CLOCK_SKEW(x) (x & LOGON_KRB5_FAIL_CLOCK_SKEW)
#define PAM_WB_GRACE_LOGON(x) ((LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON) == ( x & (LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON)))
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index eb2da870c3..d9c9fe91cb 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -1326,6 +1326,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS krb5_result = NT_STATUS_OK;
fstring name_domain, name_user;
NET_USER_INFO_3 *info3 = NULL;
@@ -1365,6 +1366,9 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
if (domain->online && (state->request.flags & WBFLAG_PAM_KRB5)) {
result = winbindd_dual_pam_auth_kerberos(domain, state, &info3);
+ /* save for later */
+ krb5_result = result;
+
if (NT_STATUS_IS_OK(result)) {
DEBUG(10,("winbindd_dual_pam_auth_kerberos succeeded\n"));
@@ -1412,6 +1416,10 @@ sam_logon:
if (NT_STATUS_IS_OK(result)) {
DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n"));
+ /* add the Krb5 err if we have one */
+ if ( NT_STATUS_EQUAL(krb5_result, NT_STATUS_TIME_DIFFERENCE_AT_DC ) ) {
+ info3->user_flgs |= LOGON_KRB5_FAIL_CLOCK_SKEW;
+ }
goto process_result;
} else {
DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n", nt_errstr(result)));