From 12ce46a02237a7168515176bb10d5c49d9492618 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Dec 2016 08:46:21 +0100 Subject: [PATCH 1/3] s3:librpc/gse: include ccache_name in DEBUG message if krb5_cc_resolve() fails BUG: https://bugzilla.samba.org/show_bug.cgi?id=12480 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- source3/librpc/crypto/gse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index e4ceed1..459cf12 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -172,8 +172,8 @@ static NTSTATUS gse_context_init(TALLOC_CTX *mem_ctx, k5ret = krb5_cc_resolve(gse_ctx->k5ctx, ccache_name, &gse_ctx->ccache); if (k5ret) { - DEBUG(1, ("Failed to resolve credential cache! (%s)\n", - error_message(k5ret))); + DEBUG(1, ("Failed to resolve credential cache '%s'! (%s)\n", + ccache_name, error_message(k5ret))); status = NT_STATUS_INTERNAL_ERROR; goto err_out; } -- 1.9.1 From 978434e11a861a7b990bf585b818af9cb5ed5359 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Dec 2016 08:47:32 +0100 Subject: [PATCH 2/3] s3:librpc/gse: remove unused #ifdef HAVE_GSS_KRB5_IMPORT_CRED We always have gss_krb5_import_cred(), it available in heimdal and also the oldest version (1.9) of MIT krb5 that we support. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12480 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- source3/librpc/crypto/gse.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 459cf12..1c812f8 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -390,8 +390,6 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, goto done; } -#ifdef HAVE_GSS_KRB5_IMPORT_CRED - /* This creates a GSSAPI cred_id_t with the keytab set */ gss_maj = gss_krb5_import_cred(&gss_min, NULL, NULL, gse_ctx->keytab, &gse_ctx->creds); @@ -410,7 +408,6 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, * principal in request'. Work around the issue by * falling back to the alternate approach below. */ } else if (gss_maj == (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) -#endif /* FIXME!!! * This call sets the default keytab for the whole server, not * just for this context. Need to find a way that does not alter -- 1.9.1 From 69723ac36d31effd5c1949de0ce693d2face7b2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Dec 2016 08:49:38 +0100 Subject: [PATCH 3/3] s3:librpc/gse: make use of gss_krb5_import_cred() instead of gss_acquire_cred() This avoids the usage of the ccselect_realm logic in MIT krb5, which leads to unpredictable results. The problem is the usage of gss_acquire_cred(), that just creates a credential handle without ccache. As result gss_init_sec_context() will trigger a code path where it use "ccselect" plugins. And the ccselect_realm module just chooses a random ccache from a global list where the realm of the provides target principal matches the realm of the ccache user principal. In the winbindd case we're using MEMORY:cliconnect to setup the smb connection to the DC. For ldap connections we use MEMORY:winbind_ccache. The typical case is that we do the smb connection first. If we try to create a new ldap connection, while the credentials in MEMORY:cliconnect are expired, we'll do the required kinit into MEMORY:winbind_ccache, but the ccselect_realm module will select MEMORY:cliconnect and tries to get a service ticket for the ldap server using the already expired TGT from MEMORY:cliconnect. The solution will be to use gss_krb5_import_cred() and explicitly pass the desired ccache, which avoids the ccselect logic. We could also use gss_acquire_cred_from(), but that's only available in modern MIT krb5 versions, while gss_krb5_import_cred() is available in heimdal and all supported MIT versions (>=1.9). As far as I can see both call the same internal function in MIT (at least for the ccache case). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12480 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- source3/librpc/crypto/gse.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 1c812f8..792700e 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -204,7 +204,6 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx; OM_uint32 gss_maj, gss_min; gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; - gss_OID_set_desc mech_set; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); @@ -253,20 +252,26 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, /* TODO: get krb5 ticket using username/password, if no valid * one already available in ccache */ - mech_set.count = 1; - mech_set.elements = &gse_ctx->gss_mech; - - gss_maj = gss_acquire_cred(&gss_min, - GSS_C_NO_NAME, - GSS_C_INDEFINITE, - &mech_set, - GSS_C_INITIATE, - &gse_ctx->creds, - NULL, NULL); + gss_maj = gss_krb5_import_cred(&gss_min, + gse_ctx->ccache, + NULL, /* keytab_principal */ + NULL, /* keytab */ + &gse_ctx->creds); if (gss_maj) { - DEBUG(5, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s] -" + char *ccache = NULL; + int kret; + + kret = krb5_cc_get_full_name(gse_ctx->k5ctx, + gse_ctx->ccache, + &ccache); + if (kret != 0) { + ccache = NULL; + } + + DEBUG(5, ("gss_krb5_import_cred ccache[%s] failed with [%s] -" "the caller may retry after a kinit.\n", - gse_errstr(gse_ctx, gss_maj, gss_min))); + ccache, gse_errstr(gse_ctx, gss_maj, gss_min))); + SAFE_FREE(ccache); status = NT_STATUS_INTERNAL_ERROR; goto err_out; } -- 1.9.1