diff --git a/lib/gssapi/acquire_cred.c b/lib/gssapi/acquire_cred.c index 197336594..79a4a692c 100644 --- a/lib/gssapi/acquire_cred.c +++ b/lib/gssapi/acquire_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -48,21 +48,67 @@ OM_uint32 gss_acquire_cred { gss_cred_id_t handle; OM_uint32 ret; + krb5_principal def_princ; + krb5_ccache ccache; + krb5_error_code pret = -1, kret = 0; + krb5_keytab kt; + krb5_creds cred; + krb5_get_init_creds_opt opt; handle = (gss_cred_id_t)malloc(sizeof(*handle)); if (handle == GSS_C_NO_CREDENTIAL) { return GSS_S_FAILURE; } + memset(handle, 0, sizeof (*handle)); ret = gss_duplicate_name(minor_status, desired_name, &handle->principal); if (ret) { return ret; } + if (krb5_cc_default(gssapi_krb5_context, &ccache) == 0 && + (pret = krb5_cc_get_principal(gssapi_krb5_context, ccache, + &def_princ)) == 0 && + krb5_principal_compare(gssapi_krb5_context, handle->principal, + def_princ) == TRUE) { + handle->ccache = ccache; + handle->keytab = NULL; + } else { + kret = krb5_kt_default(gssapi_krb5_context, &kt); + if (kret != 0) + goto out; + krb5_get_init_creds_opt_init(&opt); + memset(&cred, 0, sizeof(cred)); + kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred, + handle->principal, kt, 0, NULL, &opt); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + goto out; + } + kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops, &ccache); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + goto out; + } + kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + krb5_cc_close(gssapi_krb5_context, ccache); + goto out; + } + kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + krb5_cc_close(gssapi_krb5_context, ccache); + goto out; + } + handle->ccache = ccache; + handle->keytab = kt; + } + + /* XXX */ handle->lifetime = time_req; - - handle->keytab = NULL; handle->usage = cred_usage; ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); @@ -83,5 +129,14 @@ OM_uint32 gss_acquire_cred *output_cred_handle = handle; +out: + if (pret == 0) + krb5_free_principal(gssapi_krb5_context, def_princ); + + if (kret != 0) { + *minor_status = kret; + return GSS_S_FAILURE; + } + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/init_sec_context.c b/lib/gssapi/init_sec_context.c index 93924dcdd..6cfe7a87a 100644 --- a/lib/gssapi/init_sec_context.c +++ b/lib/gssapi/init_sec_context.c @@ -256,12 +256,15 @@ init_auth if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; + if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) { kret = krb5_cc_default (gssapi_krb5_context, &ccache); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } + } else + ccache = initiator_cred_handle->ccache; kret = krb5_cc_get_principal (gssapi_krb5_context, ccache, diff --git a/lib/gssapi/krb5/acquire_cred.c b/lib/gssapi/krb5/acquire_cred.c index 197336594..79a4a692c 100644 --- a/lib/gssapi/krb5/acquire_cred.c +++ b/lib/gssapi/krb5/acquire_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -48,21 +48,67 @@ OM_uint32 gss_acquire_cred { gss_cred_id_t handle; OM_uint32 ret; + krb5_principal def_princ; + krb5_ccache ccache; + krb5_error_code pret = -1, kret = 0; + krb5_keytab kt; + krb5_creds cred; + krb5_get_init_creds_opt opt; handle = (gss_cred_id_t)malloc(sizeof(*handle)); if (handle == GSS_C_NO_CREDENTIAL) { return GSS_S_FAILURE; } + memset(handle, 0, sizeof (*handle)); ret = gss_duplicate_name(minor_status, desired_name, &handle->principal); if (ret) { return ret; } + if (krb5_cc_default(gssapi_krb5_context, &ccache) == 0 && + (pret = krb5_cc_get_principal(gssapi_krb5_context, ccache, + &def_princ)) == 0 && + krb5_principal_compare(gssapi_krb5_context, handle->principal, + def_princ) == TRUE) { + handle->ccache = ccache; + handle->keytab = NULL; + } else { + kret = krb5_kt_default(gssapi_krb5_context, &kt); + if (kret != 0) + goto out; + krb5_get_init_creds_opt_init(&opt); + memset(&cred, 0, sizeof(cred)); + kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred, + handle->principal, kt, 0, NULL, &opt); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + goto out; + } + kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops, &ccache); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + goto out; + } + kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + krb5_cc_close(gssapi_krb5_context, ccache); + goto out; + } + kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred); + if (kret != 0) { + krb5_kt_close(gssapi_krb5_context, kt); + krb5_cc_close(gssapi_krb5_context, ccache); + goto out; + } + handle->ccache = ccache; + handle->keytab = kt; + } + + /* XXX */ handle->lifetime = time_req; - - handle->keytab = NULL; handle->usage = cred_usage; ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms); @@ -83,5 +129,14 @@ OM_uint32 gss_acquire_cred *output_cred_handle = handle; +out: + if (pret == 0) + krb5_free_principal(gssapi_krb5_context, def_princ); + + if (kret != 0) { + *minor_status = kret; + return GSS_S_FAILURE; + } + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/krb5/init_sec_context.c b/lib/gssapi/krb5/init_sec_context.c index 93924dcdd..6cfe7a87a 100644 --- a/lib/gssapi/krb5/init_sec_context.c +++ b/lib/gssapi/krb5/init_sec_context.c @@ -256,12 +256,15 @@ init_auth if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; + if (initiator_cred_handle == GSS_C_NO_CREDENTIAL) { kret = krb5_cc_default (gssapi_krb5_context, &ccache); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } + } else + ccache = initiator_cred_handle->ccache; kret = krb5_cc_get_principal (gssapi_krb5_context, ccache, diff --git a/lib/gssapi/krb5/release_cred.c b/lib/gssapi/krb5/release_cred.c index f95d8c717..eeb0ff6a8 100644 --- a/lib/gssapi/krb5/release_cred.c +++ b/lib/gssapi/krb5/release_cred.c @@ -49,6 +49,8 @@ OM_uint32 gss_release_cred krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); if ((*cred_handle)->keytab != NULL) krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab); + if ((*cred_handle)->ccache != NULL) + krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); free(*cred_handle); *cred_handle = GSS_C_NO_CREDENTIAL; diff --git a/lib/gssapi/release_cred.c b/lib/gssapi/release_cred.c index f95d8c717..eeb0ff6a8 100644 --- a/lib/gssapi/release_cred.c +++ b/lib/gssapi/release_cred.c @@ -49,6 +49,8 @@ OM_uint32 gss_release_cred krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); if ((*cred_handle)->keytab != NULL) krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab); + if ((*cred_handle)->ccache != NULL) + krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); free(*cred_handle); *cred_handle = GSS_C_NO_CREDENTIAL;