r22969: fix some more places where we could end up with more than one event
[sfrench/samba-autobuild/.git] / source4 / auth / gensec / gensec_gssapi.c
index 8140cfa44b5187ff9cc8b663462aaacd6a70758a..b8040df7eb8c084766648c9e9ffd627915902d47 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include "includes.h"
+#include "lib/events/events.h"
 #include "system/kerberos.h"
 #include "heimdal/lib/gssapi/gssapi/gssapi.h"
 #include "auth/kerberos/kerberos.h"
@@ -106,7 +107,7 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx,
 }
 
 
-static int gensec_gssapi_destory(struct gensec_gssapi_state *gensec_gssapi_state)
+static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state)
 {
        OM_uint32 maj_stat, min_stat;
        
@@ -178,7 +179,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
 
        gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
 
-       talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory); 
+       talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
 
        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
                gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG;
@@ -218,7 +219,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
        }
 
        /* don't do DNS lookups of any kind, it might/will fail for a netbios name */
-       ret = gsskrb5_set_dns_canonicalize(FALSE);
+       ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(-1, "krb5", "set_dns_canonicalize", false));
        if (ret) {
                DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
                talloc_free(gensec_gssapi_state);
@@ -226,6 +227,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
        }
 
        ret = smb_krb5_init_context(gensec_gssapi_state, 
+                                   gensec_security->event_ctx,
                                    &gensec_gssapi_state->smb_krb5_context);
        if (ret) {
                DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
@@ -320,20 +322,17 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
 
        principal = gensec_get_target_principal(gensec_security);
        if (principal && lp_client_use_spnego_principal()) {
-               name_token.value  = discard_const_p(uint8_t, principal);
-               name_token.length = strlen(principal);
-
                name_type = GSS_C_NULL_OID;
        } else {
                principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", 
                                            gensec_get_target_service(gensec_security), 
                                            hostname);
 
-               name_token.value  = discard_const_p(uint8_t, principal);
-               name_token.length = strlen(principal);
-
                name_type = GSS_C_NT_HOSTBASED_SERVICE;
        }               
+       name_token.value  = discard_const_p(uint8_t, principal);
+       name_token.length = strlen(principal);
+
 
        maj_stat = gss_import_name (&min_stat,
                                    &name_token,
@@ -350,8 +349,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
        switch (ret) {
        case 0:
                break;
+       case KRB5KDC_ERR_PREAUTH_FAILED:
+               return NT_STATUS_LOGON_FAILURE;
        case KRB5_KDC_UNREACH:
-               DEBUG(3, ("Cannot reach a KDC we require\n"));
+               DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
        default:
                DEBUG(1, ("Aquiring initiator credentails failed\n"));
@@ -1342,6 +1343,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                }
 
                cli_credentials_set_conf(session_info->credentials);
+               /* Just so we don't segfault trying to get at a username */
+               cli_credentials_set_anonymous(session_info->credentials);
                
                ret = cli_credentials_set_client_gss_creds(session_info->credentials, 
                                                           gensec_gssapi_state->delegated_cred_handle,
@@ -1350,6 +1353,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                        talloc_free(mem_ctx);
                        return NT_STATUS_NO_MEMORY;
                }
+               
+               /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
+               cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS);
+
                /* It has been taken from this place... */
                gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
        }
@@ -1361,8 +1368,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
 }
 
 static const char *gensec_gssapi_krb5_oids[] = { 
-       GENSEC_OID_KERBEROS5,
        GENSEC_OID_KERBEROS5_OLD,
+       GENSEC_OID_KERBEROS5,
        NULL 
 };