aboutsummaryrefslogtreecommitdiff
path: root/lib/libgssapi/gss_inquire_cred.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libgssapi/gss_inquire_cred.c')
-rw-r--r--lib/libgssapi/gss_inquire_cred.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/lib/libgssapi/gss_inquire_cred.c b/lib/libgssapi/gss_inquire_cred.c
index 60b746f53f6f..c51f07e55841 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);
}