summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-11-08 16:55:17 +1100
committerAndrew Tridgell <tridge@samba.org>2010-11-08 18:15:23 +1100
commit10c82d0619f71e8c6dac5755d2b327c2a543cca4 (patch)
tree5f398da1e1631b1f76df4322d72edf16aaf8a5a6
parentcd4c3d6d7ba987abf7b2ae7b826b9ef0c8cb0f2f (diff)
downloadsamba-10c82d0619f71e8c6dac5755d2b327c2a543cca4.tar.gz
samba-10c82d0619f71e8c6dac5755d2b327c2a543cca4.tar.bz2
samba-10c82d0619f71e8c6dac5755d2b327c2a543cca4.zip
s4-auth Supply more useful error messages on Kerberos failure
The practice of returning only NT_STATUS_INVALID_PARAMETER hasn't helped our users to debug problems effectivly, and so we now return more errors and try and give a more useful debug message when then happen. Andrew Bartlett
-rw-r--r--source4/auth/gensec/gensec_gssapi.c37
-rw-r--r--source4/auth/gensec/gensec_gssapi.h2
-rw-r--r--source4/auth/gensec/spnego.c2
3 files changed, 28 insertions, 13 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 3c579fee50..a03cf9edd7 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -315,7 +315,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
gss_OID name_type;
OM_uint32 maj_stat, min_stat;
const char *hostname = gensec_get_target_hostname(gensec_security);
- const char *principal;
struct gssapi_creds_container *gcc;
const char *error_string;
@@ -339,18 +338,18 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
- principal = gensec_get_target_principal(gensec_security);
- if (principal) {
+ gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
+ if (gensec_gssapi_state->target_principal) {
name_type = GSS_C_NULL_OID;
} else {
- principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
+ gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
gensec_get_target_service(gensec_security),
hostname, lpcfg_realm(gensec_security->settings->lp_ctx));
name_type = GSS_C_NT_USER_NAME;
}
- name_token.value = discard_const_p(uint8_t, principal);
- name_token.length = strlen(principal);
+ name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
+ name_token.length = strlen(gensec_gssapi_state->target_principal);
maj_stat = gss_import_name (&min_stat,
@@ -373,12 +372,12 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
case KRB5KDC_ERR_PREAUTH_FAILED:
return NT_STATUS_LOGON_FAILURE;
case KRB5_KDC_UNREACH:
- DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", principal, error_string));
- return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
+ DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
+ return NT_STATUS_NO_LOGON_SERVERS;
case KRB5_CC_NOTFOUND:
case KRB5_CC_END:
- DEBUG(3, ("Error preparing credentials we require to contact %s : %s\n", principal, error_string));
- return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
+ DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string));
+ return NT_STATUS_TIME_DIFFERENCE_AT_DC;
default:
DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string));
return NT_STATUS_UNSUCCESSFUL;
@@ -569,12 +568,24 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
return NT_STATUS_MORE_PROCESSING_REQUIRED;
} else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
switch (min_stat) {
+ case KRB5KRB_AP_ERR_TKT_NYV:
+ DEBUG(1, ("Error with ticket to contact %s: possible clock skew between us and the KDC or target server: %s\n",
+ gensec_gssapi_state->target_principal,
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+ return NT_STATUS_TIME_DIFFERENCE_AT_DC; /* Make SPNEGO ignore us, we can't go any further here */
+ case KRB5KRB_AP_ERR_TKT_EXPIRED:
+ DEBUG(1, ("Error with ticket to contact %s: ticket is expired, possible clock skew between us and the KDC or target server: %s\n",
+ gensec_gssapi_state->target_principal,
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+ return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
case KRB5_KDC_UNREACH:
- DEBUG(3, ("Cannot reach a KDC we require: %s\n",
+ DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n",
+ gensec_gssapi_state->target_principal,
gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
- return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
+ return NT_STATUS_NO_LOGON_SERVERS; /* Make SPNEGO ignore us, we can't go any further here */
case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
- DEBUG(3, ("Server is not registered with our KDC: %s\n",
+ DEBUG(3, ("Server %s is not registered with our KDC: %s\n",
+ gensec_gssapi_state->target_principal,
gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
case KRB5KRB_AP_ERR_MSG_TYPE:
diff --git a/source4/auth/gensec/gensec_gssapi.h b/source4/auth/gensec/gensec_gssapi.h
index b55b4391e0..1b826b963d 100644
--- a/source4/auth/gensec/gensec_gssapi.h
+++ b/source4/auth/gensec/gensec_gssapi.h
@@ -64,5 +64,7 @@ struct gensec_gssapi_state {
size_t max_wrap_buf_size;
int gss_exchange_count;
size_t sig_size;
+
+ const char *target_principal;
};
diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c
index 4902cd8ee1..813bf0a730 100644
--- a/source4/auth/gensec/spnego.c
+++ b/source4/auth/gensec/spnego.c
@@ -495,6 +495,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
* of this mech */
if (spnego_state->state_position != SPNEGO_SERVER_START) {
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) ||
+ NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS) ||
+ NT_STATUS_EQUAL(nt_status, NT_STATUS_TIME_DIFFERENCE_AT_DC) ||
NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
/* Pretend we never started it (lets the first run find some incompatible demand) */