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 <abart...@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 <tri...@samba.org>
    Autobuild-Date: Mon Nov  8 07:58:09 UTC 2010 on sn-devel-104

commit 10c82d0619f71e8c6dac5755d2b327c2a543cca4
Author: Andrew Bartlett <abart...@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 <br...@frogmouth.net>
Date:   Mon Nov 8 12:15:50 2010 +1100

    s4-auth Fix typos in samba4 auth code

commit 3c4376c4d8dbd7c5db52df7442ec410dbfb06e62
Author: Andrew Bartlett <abart...@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 <abart...@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",
+               gensec_gssapi_state->target_principal = 
talloc_asprintf(gensec_gssapi_state, "%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

Reply via email to