From dca7a82f793178c4a51bdd40a173748c3eb2c2a5 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Fri, 21 Sep 2012 15:03:41 -0400 Subject: [PATCH] Resolve verifier cred in accept_sec_context If the verifier cred handle is of type GSS_C_BOTH, we need to resolve the initiator part of it in order to create a s4u2proxy delegated credential handle. (If it's of type GSS_C_ACCEPT, kg_resolve_cred won't do anything beyond locking and validating the credential.) ticket: 7356 --- src/lib/gssapi/krb5/accept_sec_context.c | 5 ++-- src/tests/gssapi/t_s4u.py | 6 ++--- src/tests/gssapi/t_s4u2proxy_krb5.c | 33 ++++++++++++------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 957f86031c..975df14aa7 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -514,13 +514,14 @@ kg_accept_krb5(minor_status, context_handle, goto fail; } } else { - major_status = krb5_gss_validate_cred(minor_status, - verifier_cred_handle); + major_status = kg_cred_resolve(minor_status, context, + verifier_cred_handle, GSS_C_NO_NAME); if (GSS_ERROR(major_status)) { code = *minor_status; goto fail; } cred_handle = verifier_cred_handle; + k5_mutex_unlock(&((krb5_gss_cred_id_t)cred_handle)->lock); } cred = (krb5_gss_cred_id_t) cred_handle; diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py index d6a0f2b8d4..cd67591019 100644 --- a/src/tests/gssapi/t_s4u.py +++ b/src/tests/gssapi/t_s4u.py @@ -25,7 +25,7 @@ realm.kinit(service1, None, ['-f', '-k']) # support for allowing it. realm.kinit(realm.user_princ, password('user'), ['-f', '-c', usercache]) output = realm.run_as_server(['./t_s4u2proxy_krb5', usercache, storagecache, - pservice1, pservice2], expected_code=1) + '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'NOT_ALLOWED_TO_DELEGATE' not in output): fail('krb5 -> s4u2proxy') @@ -33,7 +33,7 @@ if ('auth1: ' + realm.user_princ not in output or # Again with SPNEGO. Bug #7045 prevents us from checking the error # message, but we can at least exercise the code. output = realm.run_as_server(['./t_s4u2proxy_krb5', '--spnego', usercache, - storagecache, pservice1, pservice2], + storagecache, '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output): fail('krb5 -> s4u2proxy (SPNEGO)') @@ -43,7 +43,7 @@ if ('auth1: ' + realm.user_princ not in output): # accept_sec_context. realm.kinit(realm.user_princ, password('user'), ['-c', usercache]) output = realm.run_as_server(['./t_s4u2proxy_krb5', usercache, storagecache, - pservice1, pservice2]) + pservice1, pservice1, pservice2]) if 'no credential delegated' not in output: fail('krb5 -> no delegated cred') diff --git a/src/tests/gssapi/t_s4u2proxy_krb5.c b/src/tests/gssapi/t_s4u2proxy_krb5.c index 36267302b5..4de6ed1c6c 100644 --- a/src/tests/gssapi/t_s4u2proxy_krb5.c +++ b/src/tests/gssapi/t_s4u2proxy_krb5.c @@ -32,7 +32,7 @@ /* * Usage: ./t_s4u2proxy_krb5 [--spnego] client_cache storage_cache - * service1 service2 + * [accname|-] service1 service2 * * This program performs a regular Kerberos or SPNEGO authentication from the * default principal of client_cache to service1. If that authentication @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { - const char *client_ccname, *storage_ccname, *service1, *service2; + const char *client_ccname, *storage_ccname, *accname, *service1, *service2; krb5_context context = NULL; krb5_error_code ret; krb5_boolean use_spnego = FALSE; @@ -58,9 +58,7 @@ main(int argc, char *argv[]) gss_buffer_desc buf = GSS_C_EMPTY_BUFFER, token = GSS_C_EMPTY_BUFFER; gss_OID mech; gss_OID_set mechs; - gss_name_t service1_name = GSS_C_NO_NAME; - gss_name_t service2_name = GSS_C_NO_NAME; - gss_name_t client_name = GSS_C_NO_NAME; + gss_name_t acceptor_name, service1_name, service2_name, client_name; gss_cred_id_t service1_cred = GSS_C_NO_CREDENTIAL; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT; @@ -72,33 +70,33 @@ main(int argc, char *argv[]) argc--; argv++; } - if (argc != 5) { - fprintf(stderr, "./t_s4u2proxy_krb5 [--spnego] client_cache " - "storage_ccache service1 service2\n"); + if (argc != 6) { + fprintf(stderr, "./t_s4u2proxy_krb5 [--spnego] client_ccache " + "storage_ccache [accname|-] service1 service2\n"); return 1; } client_ccname = argv[1]; storage_ccname = argv[2]; - service1 = argv[3]; - service2 = argv[4]; + accname = argv[3]; + service1 = argv[4]; + service2 = argv[5]; mech = use_spnego ? &mech_spnego : &mech_krb5; mechs = use_spnego ? &mechset_spnego : &mechset_krb5; ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); - /* Get GSS name and GSS_C_BOTH cred for service1, using the default - * ccache. */ - service1_name = import_name(service1); - major = gss_acquire_cred(&minor, service1_name, GSS_C_INDEFINITE, + /* Get GSS_C_BOTH acceptor credentials, using the default ccache. */ + acceptor_name = GSS_C_NO_NAME; + if (strcmp(accname, "-") != 0) + acceptor_name = import_name(service1); + major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &service1_cred, NULL, NULL); check_gsserr("gss_acquire_cred(service1)", major, minor); - /* Get GSS name for service2. */ - service2_name = import_name(service2); - /* Create initiator context and get the first token, using the client * ccache. */ + service1_name = import_name(service1); major = gss_krb5_ccache_name(&minor, client_ccname, NULL); check_gsserr("gss_krb5_ccache_name(1)", major, minor); major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, @@ -146,6 +144,7 @@ main(int argc, char *argv[]) /* Create initiator context and get the first token, using the storage * ccache. */ + service2_name = import_name(service2); major = gss_krb5_ccache_name(&minor, storage_ccname, NULL); check_gsserr("gss_krb5_ccache_name(2)", major, minor); major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, -- 2.47.3