]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:gse: Correctly handle external trusts with MIT
authorAndreas Schneider <asn@samba.org>
Thu, 9 Mar 2017 07:18:27 +0000 (08:18 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Fri, 10 Mar 2017 10:37:22 +0000 (11:37 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/librpc/crypto/gse.c

index 83e152f7239dfbce83f2b1d0f60942f7c8f89509..1d9e8dc5b2cf3b3efe5b1ac419b0a17f3e2463fc 100644 (file)
@@ -348,6 +348,7 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
        const char *client_realm = cli_credentials_get_realm(cli_creds);
        char *server_principal = NULL;
        char *server_realm = NULL;
+       bool fallback = false;
 
        in_data.value = token_in->data;
        in_data.length = token_in->length;
@@ -394,6 +395,50 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
         * want to autodetect support for transitive forest trusts, would have
         * to do the fallback ourself.
         */
+#ifndef SAMBA4_USES_HEIMDAL
+       if (gse_ctx->server_name == NULL) {
+               OM_uint32 gss_min2 = 0;
+
+               status = gse_setup_server_principal(mem_ctx,
+                                                   target_principal,
+                                                   service,
+                                                   hostname,
+                                                   client_realm,
+                                                   &server_principal,
+                                                   &gse_ctx->server_name);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               gss_maj = gss_init_sec_context(&gss_min,
+                                              gse_ctx->creds,
+                                              &gse_ctx->gssapi_context,
+                                              gse_ctx->server_name,
+                                              &gse_ctx->gss_mech,
+                                              gse_ctx->gss_want_flags,
+                                              0,
+                                              GSS_C_NO_CHANNEL_BINDINGS,
+                                              &in_data,
+                                              NULL,
+                                              &out_data,
+                                              &gse_ctx->gss_got_flags,
+                                              &time_rec);
+               if (gss_maj != GSS_S_FAILURE) {
+                       goto init_sec_context_done;
+               }
+               if (gss_min != (OM_uint32)KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
+                       goto init_sec_context_done;
+               }
+               if (target_principal != NULL) {
+                       goto init_sec_context_done;
+               }
+
+               fallback = true;
+               TALLOC_FREE(server_principal);
+               gss_release_name(&gss_min2, &gse_ctx->server_name);
+       }
+#endif /* !SAMBA4_USES_HEIMDAL */
+
        if (gse_ctx->server_name == NULL) {
                server_realm = smb_krb5_get_realm_from_hostname(mem_ctx,
                                                                hostname,
@@ -402,6 +447,11 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                }
 
+               if (fallback &&
+                   strequal(client_realm, server_realm)) {
+                       goto init_sec_context_done;
+               }
+
                status = gse_setup_server_principal(mem_ctx,
                                                    target_principal,
                                                    service,
@@ -426,6 +476,10 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
                                        0, GSS_C_NO_CHANNEL_BINDINGS,
                                        &in_data, NULL, &out_data,
                                        &gse_ctx->gss_got_flags, &time_rec);
+       goto init_sec_context_done;
+       /* JUMP! */
+init_sec_context_done:
+
        switch (gss_maj) {
        case GSS_S_COMPLETE:
                /* we are done with it */