diff options
Diffstat (limited to 'lib/libgssapi/gss_inquire_cred.c')
-rw-r--r-- | lib/libgssapi/gss_inquire_cred.c | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/lib/libgssapi/gss_inquire_cred.c b/lib/libgssapi/gss_inquire_cred.c index 60b746f..c51f07e 100644 --- a/lib/libgssapi/gss_inquire_cred.c +++ b/lib/libgssapi/gss_inquire_cred.c @@ -35,6 +35,20 @@ #include "name.h" #include "cred.h" +#define AUSAGE 1 +#define IUSAGE 2 + +static void +updateusage(gss_cred_usage_t usage, int *usagemask) +{ + if (usage == GSS_C_BOTH) + *usagemask |= AUSAGE | IUSAGE; + else if (usage == GSS_C_ACCEPT) + *usagemask |= AUSAGE; + else if (usage == GSS_C_INITIATE) + *usagemask |= IUSAGE; +} + OM_uint32 gss_inquire_cred(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, @@ -46,29 +60,35 @@ gss_inquire_cred(OM_uint32 *minor_status, OM_uint32 major_status; struct _gss_mech_switch *m; struct _gss_cred *cred = (struct _gss_cred *) cred_handle; - struct _gss_mechanism_cred *mc; struct _gss_name *name; struct _gss_mechanism_name *mn; OM_uint32 min_lifetime; + int found = 0; + int usagemask = 0; + gss_cred_usage_t usage; + + _gss_load_mech(); *minor_status = 0; if (name_ret) - *name_ret = 0; + *name_ret = GSS_C_NO_NAME; if (lifetime) *lifetime = 0; if (cred_usage) *cred_usage = 0; + if (mechanisms) + *mechanisms = GSS_C_NO_OID_SET; if (name_ret) { name = malloc(sizeof(struct _gss_name)); - if (!name) { + if (name == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } memset(name, 0, sizeof(struct _gss_name)); SLIST_INIT(&name->gn_mn); } else { - name = 0; + name = NULL; } if (mechanisms) { @@ -82,16 +102,19 @@ gss_inquire_cred(OM_uint32 *minor_status, min_lifetime = GSS_C_INDEFINITE; if (cred) { + struct _gss_mechanism_cred *mc; + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { gss_name_t mc_name; OM_uint32 mc_lifetime; major_status = mc->gmc_mech->gm_inquire_cred(minor_status, - mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL); + mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL); if (major_status) continue; - if (name) { + updateusage(usage, &usagemask); + if (name && mc_name) { mn = malloc(sizeof(struct _gss_mechanism_name)); if (!mn) { mc->gmc_mech->gm_release_name(minor_status, @@ -102,7 +125,7 @@ gss_inquire_cred(OM_uint32 *minor_status, mn->gmn_mech_oid = mc->gmc_mech_oid; mn->gmn_name = mc_name; SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); - } else { + } else if (mc_name) { mc->gmc_mech->gm_release_name(minor_status, &mc_name); } @@ -113,6 +136,7 @@ gss_inquire_cred(OM_uint32 *minor_status, if (mechanisms) gss_add_oid_set_member(minor_status, mc->gmc_mech_oid, mechanisms); + found++; } } else { SLIST_FOREACH(m, &_gss_mechs, gm_link) { @@ -121,24 +145,25 @@ gss_inquire_cred(OM_uint32 *minor_status, major_status = m->gm_inquire_cred(minor_status, GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime, - cred_usage, NULL); + &usage, NULL); if (major_status) continue; + updateusage(usage, &usagemask); if (name && mc_name) { mn = malloc( sizeof(struct _gss_mechanism_name)); if (!mn) { - mc->gmc_mech->gm_release_name( + m->gm_release_name( minor_status, &mc_name); continue; } - mn->gmn_mech = mc->gmc_mech; - mn->gmn_mech_oid = mc->gmc_mech_oid; + mn->gmn_mech = m; + mn->gmn_mech_oid = &m->gm_mech_oid; mn->gmn_name = mc_name; SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); } else if (mc_name) { - mc->gmc_mech->gm_release_name(minor_status, + m->gm_release_name(minor_status, &mc_name); } @@ -148,13 +173,17 @@ gss_inquire_cred(OM_uint32 *minor_status, if (mechanisms) gss_add_oid_set_member(minor_status, &m->gm_mech_oid, mechanisms); + found++; } + } - if ((*mechanisms)->count == 0) { - gss_release_oid_set(minor_status, mechanisms); - *minor_status = 0; - return (GSS_S_NO_CRED); - } + if (found == 0) { + gss_name_t n = (gss_name_t)name; + if (n) + gss_release_name(minor_status, &n); + gss_release_oid_set(minor_status, mechanisms); + *minor_status = 0; + return (GSS_S_NO_CRED); } *minor_status = 0; @@ -162,7 +191,13 @@ gss_inquire_cred(OM_uint32 *minor_status, *name_ret = (gss_name_t) name; if (lifetime) *lifetime = min_lifetime; - if (cred && cred_usage) - *cred_usage = cred->gc_usage; + if (cred_usage) { + if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE)) + *cred_usage = GSS_C_BOTH; + else if (usagemask & IUSAGE) + *cred_usage = GSS_C_INITIATE; + else if (usagemask & AUSAGE) + *cred_usage = GSS_C_ACCEPT; + } return (GSS_S_COMPLETE); } |