[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Mon Nov 8 00:59:01 MST 2010


The branch, master has been updated
       via  cb3d6c4 heimdal Add clock-skew handling to DCE-style GSSAPI
       via  10c82d0 s4-auth Supply more useful error messages on Kerberos failure
       via  cd4c3d6 s4-auth Fix typos in samba4 auth code
       via  3c4376c s4-dsdb Explain why we may not use the GC name in some situations.
       via  e77e162 s4-selftest fix indentation
      from  11b4202 s4-repl: fixed replication notifications to RODCs

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cb3d6c407e9ab3e5e8dffeae5e2e77769056d75a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Nov 8 17:38:38 2010 +1100

    heimdal Add clock-skew handling to DCE-style GSSAPI
    
    The clock skew handling was previously only on properly wrapped
    GSSAPI, and was skipped for DCE-style.  This allows the ASN.1 errors
    from the krb5_rd_req to suggest parsing as a kerberos error packet.
    
    Andrew Bartlett
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Mon Nov  8 07:58:09 UTC 2010 on sn-devel-104

commit 10c82d0619f71e8c6dac5755d2b327c2a543cca4
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Nov 8 16:55:17 2010 +1100

    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

commit cd4c3d6d7ba987abf7b2ae7b826b9ef0c8cb0f2f
Author: Brad Hards <bradh at frogmouth.net>
Date:   Mon Nov 8 12:15:50 2010 +1100

    s4-auth Fix typos in samba4 auth code

commit 3c4376c4d8dbd7c5db52df7442ec410dbfb06e62
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Nov 8 12:13:32 2010 +1100

    s4-dsdb Explain why we may not use the GC name in some situations.
    
    This delicate balance caused us a bit of a puzzle when we could not work
    out why an DC join failed with the new python scripts.
    
    Andrew Bartlett

commit e77e162b973632b9717b48548b3b88e2ef2fd896
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Nov 6 13:48:31 2010 +1100

    s4-selftest fix indentation

-----------------------------------------------------------------------

Summary of changes:
 selftest/target/Samba4.pm                          |    6 +-
 source4/auth/gensec/gensec_gssapi.c                |   51 ++++++----
 source4/auth/gensec/gensec_gssapi.h                |    2 +
 source4/auth/gensec/spnego.c                       |    2 +
 source4/dsdb/repl/drepl_partitions.c               |    8 ++
 source4/heimdal/lib/gssapi/krb5/init_sec_context.c |  104 ++++++++++++--------
 6 files changed, 111 insertions(+), 62 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 56b6186..4242b86 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1377,11 +1377,11 @@ sub setup_rpc_proxy($$$)
 	my $env = $self->provision_rpc_proxy($path, $dc_vars);
 
 	if (defined $env) {
-	$self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 7500));
+	        $self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 7500));
 
-	$self->wait_for_start($env);
+		$self->wait_for_start($env);
 
-	$self->{vars}->{rpc_proxy} = $env;
+		$self->{vars}->{rpc_proxy} = $env;
 	}
 	return $env;
 }
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 4729ed6..a03cf9e 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;
@@ -553,9 +552,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
 				gensec_gssapi_state->sasl_state = STAGE_DONE;
 
 				if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
-					DEBUG(5, ("GSSAPI Connection will be cryptographicly sealed\n"));
+					DEBUG(5, ("GSSAPI Connection will be cryptographically sealed\n"));
 				} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-					DEBUG(5, ("GSSAPI Connection will be cryptographicly signed\n"));
+					DEBUG(5, ("GSSAPI Connection will be cryptographically signed\n"));
 				} else {
 					DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n"));
 				}
@@ -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:
@@ -688,11 +699,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
 			gensec_gssapi_state->sasl_state = STAGE_DONE;
 
 			if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
-				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n"));
+				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically sealed\n"));
 			} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n"));
+				DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically signed\n"));
 			} else {
-				DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n"));
+				DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographically protection\n"));
 			}
 
 			return NT_STATUS_OK;
@@ -816,9 +827,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
 		/* quirk:  This changes the value that gensec_have_feature returns, to be that after SASL negotiation */
 		gensec_gssapi_state->sasl_state = STAGE_DONE;
 		if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
-			DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n"));
+			DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically sealed\n"));
 		} else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-			DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n"));
+			DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically signed\n"));
 		} else {
 			DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n"));
 		}
diff --git a/source4/auth/gensec/gensec_gssapi.h b/source4/auth/gensec/gensec_gssapi.h
index b55b439..1b826b9 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 4902cd8..813bf0a 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) */
 					
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 70173fe..d4511f6 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -141,6 +141,14 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
 		return NT_STATUS_OK;
 	}
 
+	/* All DCs have the GC/hostname/realm name, but if some of the
+	 * preconditions are not satisfied, then we will fall back to
+	 * the
+	 * E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
+	 * name.  This means that if a AD server has a dnsHostName set
+	 * on it's record, it must also have GC/hostname/realm
+	 * servicePrincipalName */
+
 	*target_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
 					    hostname,
 					    lpcfg_dnsdomain(s->task->lp_ctx));
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index f4e103a..4538a53 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -698,6 +698,44 @@ failure:
     return ret;
 }
 
+static krb5_error_code
+handle_error_packet(krb5_context context,
+		    gsskrb5_ctx ctx,
+		    krb5_data indata)
+{
+    krb5_error_code kret;
+    KRB_ERROR error;
+
+    kret = krb5_rd_error(context, &indata, &error);
+    if (kret == 0) {
+	kret = krb5_error_from_rd_error(context, &error, NULL);
+
+	/* save the time skrew for this host */
+	if (kret == KRB5KRB_AP_ERR_SKEW) {
+	    krb5_data timedata;
+	    unsigned char p[4];
+	    int32_t t = error.stime - time(NULL);
+
+	    p[0] = (t >> 24) & 0xFF;
+	    p[1] = (t >> 16) & 0xFF;
+	    p[2] = (t >> 8)  & 0xFF;
+	    p[3] = (t >> 0)  & 0xFF;
+
+	    timedata.data = p;
+	    timedata.length = sizeof(p);
+
+	    krb5_cc_set_config(context, ctx->ccache, ctx->target,
+			       "time-offset", &timedata);
+
+	    if ((ctx->more_flags & RETRIED) == 0)
+		 ctx->state = INITIATOR_RESTART;
+	    ctx->more_flags |= RETRIED;
+	}
+	free_KRB_ERROR (&error);
+    }
+    return kret;
+}
+
 
 static OM_uint32
 repl_mutual
@@ -730,6 +768,24 @@ repl_mutual
 	/* There is no OID wrapping. */
 	indata.length	= input_token->length;
 	indata.data	= input_token->value;
+	kret = krb5_rd_rep (context,
+			    ctx->auth_context,
+			    &indata,
+			    &repl);
+	if (kret >= ASN1_BAD_TIMEFORMAT && kret <= ASN1_INDEF_EXTRA_DATA) {
+	    ret = _gsskrb5_decapsulate (minor_status,
+					input_token,
+					&indata,
+					"\x03\x00",
+					GSS_KRB5_MECHANISM);
+	    if (ret == GSS_S_COMPLETE) {
+		    *minor_status = handle_error_packet(context, ctx, indata);
+		    return GSS_S_FAILURE;
+	    }
+	} else if (kret) {
+	    *minor_status = kret;
+	    return GSS_S_FAILURE;
+	}
     } else {
 	ret = _gsskrb5_decapsulate (minor_status,
 				    input_token,
@@ -744,50 +800,20 @@ repl_mutual
 					"\x03\x00",
 					GSS_KRB5_MECHANISM);
 	    if (ret == GSS_S_COMPLETE) {
-		KRB_ERROR error;
-		
-		kret = krb5_rd_error(context, &indata, &error);
-		if (kret == 0) {
-		    kret = krb5_error_from_rd_error(context, &error, NULL);
-
-		    /* save the time skrew for this host */
-		    if (kret == KRB5KRB_AP_ERR_SKEW) {
-			krb5_data timedata;
-			unsigned char p[4];
-			int32_t t = error.stime - time(NULL);
-
-			p[0] = (t >> 24) & 0xFF;
-			p[1] = (t >> 16) & 0xFF;
-			p[2] = (t >> 8)  & 0xFF;
-			p[3] = (t >> 0)  & 0xFF;
-
-			timedata.data = p;
-			timedata.length = sizeof(p);
-
-			krb5_cc_set_config(context, ctx->ccache, ctx->target,
-					   "time-offset", &timedata);
-
-			if ((ctx->more_flags & RETRIED) == 0)
-			    ctx->state = INITIATOR_RESTART;
-			ctx->more_flags |= RETRIED;
-		    }
-		    free_KRB_ERROR (&error);
-		}
-		*minor_status = kret;
+		*minor_status = handle_error_packet(context, ctx, indata);
 		return GSS_S_FAILURE;
 	    }
-	    return ret;
+	}
+	kret = krb5_rd_rep (context,
+			    ctx->auth_context,
+			    &indata,
+			    &repl);
+	if (kret) {
+	    *minor_status = kret;
+	    return GSS_S_FAILURE;
 	}
     }
 
-    kret = krb5_rd_rep (context,
-			ctx->auth_context,
-			&indata,
-			&repl);
-    if (kret) {
-	*minor_status = kret;
-	return GSS_S_FAILURE;
-    }
     krb5_free_ap_rep_enc_part (context,
 			       repl);
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list