From a145ea3d4317f52b25ca44c14c4333d9a9e01bd9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mar 04 2017 00:47:47 +0000 Subject: If credentials changed try to store them This allows for efficient caching when new tickets are added on the proxy side when using memory ccaches. It also allows us to store changes in flags and other ccache ancillary modifications. Fix impersonate tests to cope with the acquire_cred behavior change. Signed-off-by: Simo Sorce [rharwood@redhat.com: fix induced merge conflict, hoist gssx_cred, tweak commit message body, fix extra argument to DEBUG in t_impersonate.c] Reviewed-by: Robbie Harwood --- diff --git a/src/mechglue/gpp_acquire_cred.c b/src/mechglue/gpp_acquire_cred.c index 5cdf7a6..d876699 100644 --- a/src/mechglue/gpp_acquire_cred.c +++ b/src/mechglue/gpp_acquire_cred.c @@ -170,7 +170,18 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, &out_cred_handle->remote, actual_mechs, time_rec); - if (maj == GSS_S_COMPLETE || behavior == GPP_REMOTE_ONLY) { + if (maj == GSS_S_COMPLETE) { + /* store back creds if they changed */ + if (out_cred_handle->remote && + !gpp_creds_are_equal(in_cred_remote, out_cred_handle->remote)) { + tmaj = gpp_store_remote_creds(&tmin, + out_cred_handle->default_creds, + &out_cred_handle->store, + out_cred_handle->remote); + if (tmaj != GSS_S_COMPLETE) { + maj = tmaj; + } + } goto done; } diff --git a/src/mechglue/gpp_creds.c b/src/mechglue/gpp_creds.c index 42d21c5..12709b2 100644 --- a/src/mechglue/gpp_creds.c +++ b/src/mechglue/gpp_creds.c @@ -355,6 +355,13 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, maj = gpm_acquire_cred(&min, premote, NULL, 0, NULL, cred_usage, false, &cred->remote, NULL, NULL); + if (maj == GSS_S_COMPLETE) { + if (premote && + !gpp_creds_are_equal(premote, cred->remote)) { + maj = gpp_store_remote_creds(&min, cred->default_creds, + &cred->store, cred->remote); + } + } xdr_free((xdrproc_t)xdr_gssx_cred, (char *)&remote); diff --git a/src/mechglue/gpp_init_sec_context.c b/src/mechglue/gpp_init_sec_context.c index 76e0311..94d9b01 100644 --- a/src/mechglue/gpp_init_sec_context.c +++ b/src/mechglue/gpp_init_sec_context.c @@ -62,6 +62,7 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, enum gpp_behavior behavior = GPP_UNINITIALIZED; struct gpp_context_handle *ctx_handle = NULL; struct gpp_cred_handle *cred_handle = NULL; + gssx_cred *out_cred = NULL; struct gpp_name_handle *name; OM_uint32 tmaj, tmin; OM_uint32 maj, min; @@ -167,8 +168,20 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, output_token, ret_flags, time_rec, - NULL); + &out_cred); if (maj == GSS_S_COMPLETE || maj == GSS_S_CONTINUE_NEEDED) { + if (out_cred) { + xdr_free((xdrproc_t)xdr_gssx_cred, + (char *)cred_handle->remote); + free(cred_handle->remote); + cred_handle->remote = out_cred; + out_cred = NULL; + /* failuire is not fatal */ + (void)gpp_store_remote_creds(&tmin, + cred_handle->default_creds, + &cred_handle->store, + cred_handle->remote); + } goto done; } diff --git a/tests/t_impersonate.c b/tests/t_impersonate.c index 42d59a4..8ca6e9c 100644 --- a/tests/t_impersonate.c +++ b/tests/t_impersonate.c @@ -22,9 +22,10 @@ int main(int argc, const char *argv[]) int ret = -1; bool selfhalf = false; bool proxyhalf = false; - const char *deleg_ccache = NULL; + gss_key_value_element_desc ccelement = { "ccache", NULL }; + gss_key_value_set_desc cred_store = { 1, &ccelement }; - if (argc < 4) return -1; + if (argc < 5) return -1; ret = t_string_to_name(argv[1], &user_name, GSS_C_NT_USER_NAME); if (ret) { @@ -49,29 +50,22 @@ int main(int argc, const char *argv[]) goto done; } - if (argc > 4) { - if (strcmp(argv[4], "s4u2self") == 0) { + ccelement.value = argv[4]; + + if (argc > 5) { + if (strcmp(argv[5], "s4u2self") == 0) { selfhalf = true; - } else if (strcmp(argv[4], "s4u2proxy") == 0) { + } else if (strcmp(argv[5], "s4u2proxy") == 0) { proxyhalf = true; } else { - DEBUG("Invalid argument 4: %s\n", argv[4]); - ret = -1; - goto done; - } - if (argc < 6) { - DEBUG("Option %s requires additional arguments\n", argv[4]); + DEBUG("Invalid argument 5: %s\n", argv[5]); ret = -1; goto done; } - deleg_ccache = argv[5]; - DEBUG("S4U2%s half [ccache %s]\n", selfhalf?"Self":"Proxy", argv[5]); + DEBUG("S4U2%s half\n", selfhalf ? "Self" : "Proxy"); } if (proxyhalf) { - gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; - gss_key_value_set_desc cred_store = { 1, &ccelement }; - ret_maj = gss_acquire_cred_from(&ret_min, user_name, GSS_C_INDEFINITE, @@ -90,15 +84,17 @@ int main(int argc, const char *argv[]) flags = GSS_C_MUTUAL_FLAG; } else { - ret_maj = gss_acquire_cred(&ret_min, - proxy_name, - GSS_C_INDEFINITE, - &oid_set, - GSS_C_BOTH, - &impersonator_cred_handle, - NULL, NULL); + ret_maj = gss_acquire_cred_from(&ret_min, + proxy_name, + GSS_C_INDEFINITE, + &oid_set, + GSS_C_BOTH, + &cred_store, + &impersonator_cred_handle, + NULL, NULL); if (ret_maj != GSS_S_COMPLETE) { - DEBUG("gss_acquire_cred() failed\n"); + DEBUG("gss_acquire_cred_from() [%s] failed\n", + selfhalf ? "s4u2self" : "impersonate"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; @@ -121,9 +117,6 @@ int main(int argc, const char *argv[]) } if (selfhalf) { - gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; - gss_key_value_set_desc cred_store = { 1, &ccelement }; - ret_maj = gss_store_cred_into(&ret_min, cred_handle, GSS_C_INITIATE, diff --git a/tests/t_impersonate.py b/tests/t_impersonate.py index 499b9a1..3e25962 100755 --- a/tests/t_impersonate.py +++ b/tests/t_impersonate.py @@ -75,40 +75,43 @@ def run(testdir, env, conf): # Test all permitted socket = os.path.join(testdir, 'impersonate.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate", socket, cmd, False) rets.append(r) #Test fail socket = os.path.join(testdir, 'impersonate-proxyonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate fail self", socket, cmd, True) rets.append(r) #Test fail socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate fail proxy", socket, cmd, True) rets.append(r) #Test s4u2self half succeed socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2self', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2self'] r = run_cmd(testdir, env, conf, "s4u2self delegation", socket, cmd, False) rets.append(r) #Test s4u2proxy half fail socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2proxy', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2proxy'] r = run_cmd(testdir, env, conf, "s4u2proxy fail", socket, cmd, True) rets.append(r) #Test s4u2proxy half succeed socket = os.path.join(testdir, 'impersonate-proxyonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2proxy', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2proxy'] r = run_cmd(testdir, env, conf, "s4u2proxy", socket, cmd, False) rets.append(r)