summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorwyllys <none@none>2005-07-13 10:02:39 -0700
committerwyllys <none@none>2005-07-13 10:02:39 -0700
commit354d1447ce995f3923a8f53d41c49fd3e6543282 (patch)
treeb3380cb1588026a43df9055acffff2ed4428a11a /usr/src/lib
parentf3f5a4dd0d8a3e3659add4eeca8b25772c3b35a2 (diff)
downloadillumos-gate-354d1447ce995f3923a8f53d41c49fd3e6543282.tar.gz
6259944 call gss_acquire_cred() with SPNEGO OID, it returns GSS_S_COMPLETE but did not return any credential
6260520 Call gss_context_time() with a handle of an un-established SPNEGO context, it will core dump. 6285582 gss_add_cred() is broken when input_cred_handle == GSS_C_NO_CREDENTIAL, assumes GSS_C_NO_NAME 6287358 SPNEGO init_sec_context fails when given 'actual_mechs' parameter 6290437 gss_accept_sec_context needs better handling of delegated credentials 6293338 call gss_create_empty_oid_set() with oid_set=NULL, it will seg fault.
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h27
-rw-r--r--usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c157
-rw-r--r--usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec6
-rw-r--r--usr/src/lib/libgss/g_accept_sec_context.c180
-rw-r--r--usr/src/lib/libgss/g_acquire_cred.c62
-rw-r--r--usr/src/lib/libgss/g_inquire_cred.c41
-rw-r--r--usr/src/lib/libgss/oid_ops.c33
7 files changed, 316 insertions, 190 deletions
diff --git a/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h b/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h
index 7954eca49f..df3d980c3d 100644
--- a/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h
+++ b/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h
@@ -91,17 +91,8 @@ typedef enum {NO_TOKEN_SEND, INIT_TOKEN_SEND, CONT_TOKEN_SEND,
typedef void *spnego_token_t;
-/* spnego name structure for internal representation. */
-typedef struct {
- gss_OID type;
- gss_buffer_t buffer;
- gss_OID mech_type;
- gss_name_t mech_name;
-} spnego_name_desc, *spnego_name_t;
-
/* Structure for context handle */
typedef struct {
- OM_uint32 magic_num;
gss_buffer_desc DER_mechTypes;
gss_OID internal_mech;
gss_ctx_id_t ctx_handle;
@@ -111,12 +102,6 @@ typedef struct {
OM_uint32 last_status;
} spnego_gss_ctx_id_rec, *spnego_gss_ctx_id_t;
-/*
- * The magic number must be less than a standard pagesize
- * to avoid a possible collision with a real address.
- */
-#define SPNEGO_MAGIC_ID 0x00000fed
-
/* SPNEGO oid structure */
static const gss_OID_desc spnego_oids[] = {
{SPNEGO_OID_LENGTH, SPNEGO_OID},
@@ -353,6 +338,18 @@ OM_uint32 spnego_gss_verify
int *qop_state
);
+OM_uint32 spnego_gss_inquire_cred
+(
+ void *context,
+ OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t *name,
+ OM_uint32 *lifetime,
+ gss_cred_usage_t *cred_usage,
+ gss_OID_set *mechanisms
+);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c b/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c
index 2fc3c3141a..dc8619c3b3 100644
--- a/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c
+++ b/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c
@@ -106,7 +106,7 @@ static struct gss_config spnego_mechanism =
spnego_gss_display_name,
spnego_gss_import_name,
spnego_gss_release_name,
- NULL, /* gss_inquire_cred */
+ spnego_gss_inquire_cred, /* gss_inquire_cred */
NULL, /* gss_add_cred */
/* EXPORT DELETE START */ /* CRYPT DELETE START */
spnego_gss_seal, /* gss_seal */
@@ -253,7 +253,6 @@ create_spnego_ctx(void)
return (NULL);
}
- spnego_ctx->magic_num = SPNEGO_MAGIC_ID;
spnego_ctx->ctx_handle = GSS_C_NO_CONTEXT;
spnego_ctx->internal_mech = NULL;
spnego_ctx->optionStr = NULL;
@@ -312,7 +311,7 @@ spnego_gss_init_sec_context(void *ct,
dsyslog("Entering init_sec_context\n");
if (context_handle == NULL)
- return (GSS_S_FAILURE);
+ return (GSS_S_NO_CONTEXT);
*minor_status = 0;
output_token->length = 0;
@@ -362,7 +361,7 @@ spnego_gss_init_sec_context(void *ct,
}
if (input_token != NULL && input_token->value != NULL) {
- ret = GSS_S_FAILURE;
+ ret = GSS_S_DEFECTIVE_TOKEN;
goto cleanup;
}
@@ -380,7 +379,7 @@ spnego_gss_init_sec_context(void *ct,
spnego_ctx = (spnego_gss_ctx_id_t)(*context_handle);
if (input_token == NULL || input_token->value == NULL) {
- ret = GSS_S_FAILURE;
+ ret = GSS_S_DEFECTIVE_TOKEN;
goto cleanup;
}
ptr = (unsigned char *) input_token->value;
@@ -536,13 +535,6 @@ spnego_gss_init_sec_context(void *ct,
}
}
- if (actual_mech) {
- (void) generic_gss_release_oid(&mstat, actual_mech);
- ret = generic_gss_copy_oid(&mstat,
- (gss_OID) gss_mech_spnego, actual_mech);
- if (ret != GSS_S_COMPLETE)
- goto cleanup;
- }
if (send_token == NO_TOKEN_SEND) {
output_token->length = 0;
@@ -633,12 +625,6 @@ spnego_gss_init_sec_context(void *ct,
if ((status == GSS_S_COMPLETE) &&
(ret == GSS_S_COMPLETE)) {
- /*
- * Now, switch the output context to refer to the
- * negotiated mechanism's context.
- */
- *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle;
-
if (actual_mech) {
(void) generic_gss_release_oid(&mstat, actual_mech);
ret = generic_gss_copy_oid(&mstat,
@@ -647,7 +633,6 @@ spnego_gss_init_sec_context(void *ct,
goto cleanup;
}
- release_spnego_ctx(&spnego_ctx);
} else if (ret == GSS_S_CONTINUE_NEEDED) {
if (make_spnego_tokenInit_msg(spnego_ctx,
mechSet,
@@ -664,7 +649,8 @@ cleanup:
ret != GSS_S_CONTINUE_NEEDED) {
if (spnego_ctx != NULL &&
spnego_ctx->ctx_handle != NULL)
- free(spnego_ctx->ctx_handle);
+ gss_delete_sec_context(&mstat, &spnego_ctx->ctx_handle,
+ GSS_C_NO_BUFFER);
if (spnego_ctx != NULL)
release_spnego_ctx(&spnego_ctx);
@@ -739,7 +725,7 @@ spnego_gss_accept_sec_context(void *ct,
dsyslog("Entering accept_sec_context\n");
if (context_handle == NULL)
- return (GSS_S_FAILURE);
+ return (GSS_S_NO_CONTEXT);
if (src_name)
*src_name = (gss_name_t)NULL;
@@ -1047,14 +1033,7 @@ spnego_gss_accept_sec_context(void *ct,
}
ret = status;
- /*
- * If we got this far OK, then switch the
- * returned context handle to reference the
- * "real" context handle for the mech.
- */
if (status == GSS_S_COMPLETE) {
- *context_handle =
- (gss_ctx_id_t)spnego_ctx->ctx_handle;
if (internal_name != NULL && src_name != NULL)
*src_name = internal_name;
}
@@ -1099,7 +1078,6 @@ senderror:
} else {
(void) gss_release_buffer(&mstat, output_token);
}
- release_spnego_ctx(&spnego_ctx);
cleanup:
if (ret != GSS_S_COMPLETE &&
@@ -1226,6 +1204,23 @@ spnego_gss_display_name(void *ctx,
/*ARGSUSED*/
OM_uint32
+spnego_gss_inquire_cred(void *ctx,
+ OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t *name,
+ OM_uint32 *lifetime,
+ gss_cred_usage_t *cred_usage,
+ gss_OID_set *mechanisms)
+{
+ /* A SPNEGO cred is just a standard libgss cred record */
+ return (gss_inquire_cred(minor_status,
+ cred_handle, name,
+ lifetime, cred_usage,
+ mechanisms));
+}
+
+/*ARGSUSED*/
+OM_uint32
spnego_gss_inquire_names_for_mech(void *ctx,
OM_uint32 *minor_status,
gss_OID mechanism,
@@ -1278,8 +1273,14 @@ spnego_gss_unseal(void *context,
int *qop_state)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_unseal(minor_status,
- context_handle,
+ ctx->ctx_handle,
input_message_buffer,
output_message_buffer,
conf_state,
@@ -1299,8 +1300,14 @@ spnego_gss_seal(void *context,
gss_buffer_t output_message_buffer)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_seal(minor_status,
- context_handle,
+ ctx->ctx_handle,
conf_req_flag,
qop_req,
input_message_buffer,
@@ -1317,8 +1324,14 @@ spnego_gss_process_context_token(void *context,
const gss_buffer_t token_buffer)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_process_context_token(minor_status,
- context_handle,
+ ctx->ctx_handle,
token_buffer);
return (ret);
@@ -1334,18 +1347,17 @@ spnego_gss_delete_sec_context(void *context,
spnego_gss_ctx_id_t *ctx =
(spnego_gss_ctx_id_t *)context_handle;
- if (context_handle == NULL)
- return (GSS_S_FAILURE);
+ if (context_handle == NULL || *ctx == NULL)
+ return (GSS_S_NO_CONTEXT);
/*
- * If this is still an SPNEGO mech, release it locally.
+ * If this is still a SPNEGO mech, release it locally.
*/
- if (*ctx != NULL &&
- (*ctx)->magic_num == SPNEGO_MAGIC_ID) {
+ if ((*ctx)->ctx_handle == GSS_C_NO_CONTEXT) {
(void) release_spnego_ctx(ctx);
} else {
ret = gss_delete_sec_context(minor_status,
- context_handle,
+ &(*ctx)->ctx_handle,
output_token);
}
@@ -1359,9 +1371,16 @@ spnego_gss_context_time(void *context,
OM_uint32 *time_rec)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_context_time(minor_status,
- context_handle,
+ ctx->ctx_handle,
time_rec);
+
return (ret);
}
@@ -1372,8 +1391,14 @@ spnego_gss_export_sec_context(void *context,
gss_buffer_t interprocess_token)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t *ctx =
+ (spnego_gss_ctx_id_t *)context_handle;
+
+ if (context_handle == NULL || *ctx == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_export_sec_context(minor_status,
- context_handle,
+ &(*ctx)->ctx_handle,
interprocess_token);
return (ret);
}
@@ -1385,9 +1410,16 @@ spnego_gss_import_sec_context(void *context,
gss_ctx_id_t *context_handle)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t *ctx =
+ (spnego_gss_ctx_id_t *)context_handle;
+
+ if (context_handle == NULL || *ctx == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_import_sec_context(minor_status,
interprocess_token,
- context_handle);
+ &(*ctx)->ctx_handle);
+
return (ret);
}
@@ -1404,9 +1436,14 @@ spnego_gss_inquire_context(void *context,
int *open)
{
OM_uint32 ret = GSS_S_COMPLETE;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
ret = gss_inquire_context(minor_status,
- context_handle,
+ ctx->ctx_handle,
src_name,
targ_name,
lifetime_rec,
@@ -1428,8 +1465,14 @@ spnego_gss_wrap_size_limit(void *context,
OM_uint32 *max_input_size)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_wrap_size_limit(minor_status,
- context_handle,
+ ctx->ctx_handle,
conf_req_flag,
qop_req,
req_output_size,
@@ -1446,11 +1489,18 @@ spnego_gss_sign(void *context,
gss_buffer_t message_token)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_sign(minor_status,
- context_handle,
+ ctx->ctx_handle,
qop_req,
message_buffer,
message_token);
+
return (ret);
}
@@ -1463,8 +1513,14 @@ spnego_gss_verify(void *context,
int *qop_state)
{
OM_uint32 ret;
+ spnego_gss_ctx_id_t ctx =
+ (spnego_gss_ctx_id_t)context_handle;
+
+ if (context_handle == NULL)
+ return (GSS_S_NO_CONTEXT);
+
ret = gss_verify_mic(minor_status,
- context_handle,
+ ctx->ctx_handle,
msg_buffer,
token_buffer,
(uint32_t *)qop_state);
@@ -1482,7 +1538,11 @@ release_spnego_ctx(spnego_gss_ctx_id_t *ctx)
{
spnego_gss_ctx_id_t context;
OM_uint32 minor_stat;
- context = *ctx;
+
+ if (ctx != NULL)
+ context = *ctx;
+ else
+ return;
if (context != NULL) {
(void) gss_release_buffer(&minor_stat,
@@ -1495,6 +1555,11 @@ release_spnego_ctx(spnego_gss_ctx_id_t *ctx)
free(context->optionStr);
context->optionStr = NULL;
}
+ if (context->ctx_handle != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_stat,
+ &context->ctx_handle,
+ GSS_C_NO_BUFFER);
+
free(context);
*ctx = NULL;
}
diff --git a/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec b/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec
index 3eeab98af1..acd14eb89a 100644
--- a/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec
+++ b/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec
@@ -105,3 +105,9 @@ end
function spnego_gss_verify
version SUNWprivate
end
+
+function spnego_gss_inquire_cred
+version SUNWprivate
+end
+
+
diff --git a/usr/src/lib/libgss/g_accept_sec_context.c b/usr/src/lib/libgss/g_accept_sec_context.c
index 442d472f47..cf2ed8696b 100644
--- a/usr/src/lib/libgss/g_accept_sec_context.c
+++ b/usr/src/lib/libgss/g_accept_sec_context.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,7 +63,7 @@ OM_uint32 *time_rec;
gss_cred_id_t *d_cred; /* delegated cred handle */
{
- OM_uint32 status, temp_status, temp_minor_status;
+ OM_uint32 status, temp_status, t_minstat;
gss_union_ctx_id_t union_ctx_id;
gss_union_cred_t union_cred;
gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
@@ -72,6 +72,8 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
gss_name_t tmp_src_name = GSS_C_NO_NAME;
gss_OID_desc token_mech_type_desc;
gss_OID token_mech_type = &token_mech_type_desc;
+ gss_OID actual_mech = GSS_C_NO_OID;
+ OM_uint32 flags;
gss_mechanism mech;
/* check parameters first */
@@ -119,7 +121,7 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
return (GSS_S_FAILURE);
union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
- status = generic_gss_copy_oid(&temp_minor_status,
+ status = generic_gss_copy_oid(&t_minstat,
token_mech_type,
&union_ctx_id->mech_type);
if (status != GSS_S_COMPLETE) {
@@ -158,9 +160,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
input_token_buffer,
input_chan_bindings,
&internal_name,
- mech_type,
+ &actual_mech,
output_token,
- ret_flags,
+ &flags,
time_rec,
d_cred ? &tmp_d_cred : NULL);
@@ -172,6 +174,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
if (status != GSS_S_COMPLETE)
goto error_out;
+ if (mech_type != NULL)
+ *mech_type = actual_mech;
+
/*
* if src_name is non-NULL,
* convert internal_name into a union name equivalent
@@ -181,18 +186,18 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
*/
if (internal_name != NULL) {
temp_status = __gss_convert_name_to_union_name(
- &temp_minor_status, mech,
+ &t_minstat, mech,
internal_name, &tmp_src_name);
if (temp_status != GSS_S_COMPLETE) {
- *minor_status = temp_minor_status;
+ *minor_status = t_minstat;
if (output_token->length)
(void) gss_release_buffer(
- &temp_minor_status,
+ &t_minstat,
output_token);
if (internal_name != GSS_C_NO_NAME)
mech->gss_release_name(
mech->context,
- &temp_minor_status,
+ &t_minstat,
&internal_name);
return (temp_status);
}
@@ -204,88 +209,107 @@ gss_cred_id_t *d_cred; /* delegated cred handle */
}
/* Ensure we're returning correct creds format */
- if ((ret_flags && GSS_C_DELEG_FLAG) &&
- tmp_d_cred != GSS_C_NO_CREDENTIAL) {
- gss_union_cred_t d_u_cred = NULL;
-
- d_u_cred = malloc(sizeof (gss_union_cred_desc));
- if (d_u_cred == NULL) {
- status = GSS_S_FAILURE;
- goto error_out;
- }
- (void) memset(d_u_cred, 0,
- sizeof (gss_union_cred_desc));
+ if ((flags & GSS_C_DELEG_FLAG) &&
+ tmp_d_cred != GSS_C_NO_CREDENTIAL) {
+ /*
+ * If we got back an OID different from the original
+ * token OID, assume the delegated_cred is already
+ * a proper union_cred and just return it. Don't
+ * try to re-wrap it. This is for SPNEGO or other
+ * pseudo-mechanisms.
+ */
+ if (actual_mech != GSS_C_NO_OID &&
+ token_mech_type != GSS_C_NO_OID &&
+ !g_OID_equal(actual_mech, token_mech_type)) {
+ *d_cred = tmp_d_cred;
+ } else {
+ gss_union_cred_t d_u_cred = NULL;
- d_u_cred->count = 1;
+ d_u_cred = malloc(sizeof (gss_union_cred_desc));
+ if (d_u_cred == NULL) {
+ status = GSS_S_FAILURE;
+ goto error_out;
+ }
+ (void) memset(d_u_cred, 0,
+ sizeof (gss_union_cred_desc));
- status = generic_gss_copy_oid(&temp_minor_status,
- token_mech_type,
- &d_u_cred->mechs_array);
+ d_u_cred->count = 1;
- if (status != GSS_S_COMPLETE) {
- free(d_u_cred);
- goto error_out;
- }
+ status = generic_gss_copy_oid(
+ &t_minstat,
+ actual_mech,
+ &d_u_cred->mechs_array);
- d_u_cred->cred_array = malloc(sizeof (gss_cred_id_t));
- if (d_u_cred->cred_array != NULL) {
- d_u_cred->cred_array[0] = tmp_d_cred;
- } else {
- free(d_u_cred);
- status = GSS_S_FAILURE;
- goto error_out;
- }
+ if (status != GSS_S_COMPLETE) {
+ free(d_u_cred);
+ goto error_out;
+ }
- if (status != GSS_S_COMPLETE) {
- free(d_u_cred->cred_array);
- free(d_u_cred);
- goto error_out;
- }
+ d_u_cred->cred_array = malloc(
+ sizeof (gss_cred_id_t));
+ if (d_u_cred->cred_array != NULL) {
+ d_u_cred->cred_array[0] = tmp_d_cred;
+ } else {
+ free(d_u_cred);
+ status = GSS_S_FAILURE;
+ goto error_out;
+ }
- internal_name = GSS_C_NO_NAME;
+ if (status != GSS_S_COMPLETE) {
+ free(d_u_cred->cred_array);
+ free(d_u_cred);
+ goto error_out;
+ }
- d_u_cred->auxinfo.creation_time = time(0);
- d_u_cred->auxinfo.time_rec = 0;
+ internal_name = GSS_C_NO_NAME;
- if (mech->gss_inquire_cred) {
- status = mech->gss_inquire_cred(mech->context,
- minor_status,
- tmp_d_cred,
- &internal_name,
- &d_u_cred->auxinfo.time_rec,
- &d_u_cred->auxinfo.cred_usage,
- NULL);
- }
+ d_u_cred->auxinfo.creation_time = time(0);
+ d_u_cred->auxinfo.time_rec = 0;
- if (internal_name != NULL) {
- temp_status = __gss_convert_name_to_union_name(
- &temp_minor_status, mech,
- internal_name, &tmp_src_name);
- if (temp_status != GSS_S_COMPLETE) {
- *minor_status = temp_minor_status;
- if (output_token->length)
- (void) gss_release_buffer(
- &temp_minor_status,
- output_token);
- free(d_u_cred->cred_array);
- free(d_u_cred);
- return (temp_status);
+ if (mech->gss_inquire_cred) {
+ status = mech->gss_inquire_cred(
+ mech->context,
+ minor_status,
+ tmp_d_cred,
+ &internal_name,
+ &d_u_cred->auxinfo.time_rec,
+ &d_u_cred->auxinfo.cred_usage,
+ NULL);
}
- }
- if (tmp_src_name != NULL) {
- status = gss_display_name(
- &temp_minor_status,
- tmp_src_name,
- &d_u_cred->auxinfo.name,
- &d_u_cred->auxinfo.name_type);
- }
+ if (internal_name != NULL) {
+ temp_status =
+ __gss_convert_name_to_union_name(
+ &t_minstat, mech,
+ internal_name, &tmp_src_name);
+ if (temp_status != GSS_S_COMPLETE) {
+ *minor_status = t_minstat;
+ if (output_token->length)
+ (void) gss_release_buffer(
+ &t_minstat,
+ output_token);
+ free(d_u_cred->cred_array);
+ free(d_u_cred);
+ return (temp_status);
+ }
+ }
- *d_cred = (gss_cred_id_t)d_u_cred;
+ if (tmp_src_name != NULL) {
+ status = gss_display_name(
+ &t_minstat,
+ tmp_src_name,
+ &d_u_cred->auxinfo.name,
+ &d_u_cred->auxinfo.name_type);
+ }
+
+ *d_cred = (gss_cred_id_t)d_u_cred;
+ }
+ if (ret_flags != NULL)
+ *ret_flags = flags;
}
if (src_name == NULL && tmp_src_name != NULL)
- (void) gss_release_name(&temp_minor_status,
+ (void) gss_release_name(&t_minstat,
&tmp_src_name);
return (status);
} else {
@@ -305,13 +329,13 @@ error_out:
}
if (output_token->length)
- (void) gss_release_buffer(&temp_minor_status, output_token);
+ (void) gss_release_buffer(&t_minstat, output_token);
if (src_name)
*src_name = GSS_C_NO_NAME;
if (tmp_src_name != GSS_C_NO_NAME)
- (void) gss_release_buffer(&temp_minor_status,
+ (void) gss_release_buffer(&t_minstat,
(gss_buffer_t)tmp_src_name);
return (status);
diff --git a/usr/src/lib/libgss/g_acquire_cred.c b/usr/src/lib/libgss/g_acquire_cred.c
index a6ecd5a533..9fffa3c63d 100644
--- a/usr/src/lib/libgss/g_acquire_cred.c
+++ b/usr/src/lib/libgss/g_acquire_cred.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,7 +29,6 @@
/*
* glue routine for gss_acquire_cred
*/
-
#include <mechglueP.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
@@ -274,33 +273,52 @@ gss_add_cred(minor_status, input_cred_handle,
return (GSS_S_FAILURE);
(void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
-
- /* for default credentials we will use GSS_C_NO_NAME */
- internal_name = GSS_C_NO_NAME;
} else {
+ /* Input Cred is non-NULL */
union_cred = (gss_union_cred_t)input_cred_handle;
+
if (__gss_get_mechanism_cred(union_cred, desired_mech) !=
- GSS_C_NO_CREDENTIAL)
- return (GSS_S_DUPLICATE_ELEMENT);
+ GSS_C_NO_CREDENTIAL) {
+ status = GSS_S_DUPLICATE_ELEMENT;
+ goto errout;
+ }
- /* may need to create a mechanism specific name */
- if (desired_name) {
- union_name = (gss_union_name_t)desired_name;
- if (union_name->mech_type &&
- g_OID_equal(union_name->mech_type,
- &mech->mech_type))
- internal_name = union_name->mech_name;
- else {
- if (__gss_import_internal_name(minor_status,
- &mech->mech_type, union_name,
- &allocated_name) != GSS_S_COMPLETE)
- return (GSS_S_BAD_NAME);
+ /*
+ * If no name was given, determine the name from the
+ * existing credential.
+ */
+ if (desired_name == GSS_C_NO_NAME) {
+ if (gss_import_name(minor_status,
+ &union_cred->auxinfo.name,
+ union_cred->auxinfo.name_type,
+ &allocated_name) == GSS_S_COMPLETE &&
+ (gss_canonicalize_name(minor_status,
+ allocated_name,
+ &mech->mech_type,
+ NULL) == GSS_S_COMPLETE)) {
internal_name = allocated_name;
}
+ } /* else, get the name from the desired_name below */
+ }
+ if (desired_name != GSS_C_NO_NAME) {
+ /* may need to create a mechanism specific name */
+ union_name = (gss_union_name_t)desired_name;
+
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type,
+ &mech->mech_type))
+ internal_name = union_name->mech_name;
+ else {
+ if (__gss_import_internal_name(minor_status,
+ &mech->mech_type, union_name,
+ &allocated_name) != GSS_S_COMPLETE) {
+ status = GSS_S_BAD_NAME;
+ goto errout;
+ }
+ internal_name = allocated_name;
}
}
-
if (cred_usage == GSS_C_ACCEPT)
time_req = acceptor_time_req;
else if (cred_usage == GSS_C_INITIATE)
@@ -317,7 +335,7 @@ gss_add_cred(minor_status, input_cred_handle,
if (status != GSS_S_COMPLETE)
goto errout;
- /* may need to set credential auxinfo strucutre */
+ /* may need to set credential auxinfo structure */
if (union_cred->auxinfo.creation_time == 0) {
union_cred->auxinfo.creation_time = time(NULL);
union_cred->auxinfo.time_rec = time_rec;
@@ -327,7 +345,7 @@ gss_add_cred(minor_status, input_cred_handle,
* we must set the name; if name is not supplied
* we must do inquire cred to get it
*/
- if (internal_name == NULL) {
+ if (internal_name == GSS_C_NO_NAME) {
if (mech->gss_inquire_cred == NULL ||
((status = mech->gss_inquire_cred(
mech->context,
diff --git a/usr/src/lib/libgss/g_inquire_cred.c b/usr/src/lib/libgss/g_inquire_cred.c
index 78fc641b74..f7b4d025c4 100644
--- a/usr/src/lib/libgss/g_inquire_cred.c
+++ b/usr/src/lib/libgss/g_inquire_cred.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -234,26 +234,31 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
if (mech_cred == NULL)
return (GSS_S_DEFECTIVE_CREDENTIAL);
- status = mech->gss_inquire_cred_by_mech(mech->context, minor_status,
- mech_cred, mech_type,
- name ? &internal_name : NULL,
- initiator_lifetime,
- acceptor_lifetime, cred_usage);
-
- if (status != GSS_S_COMPLETE)
- return (status);
+ if (mech->gss_inquire_cred_by_mech != NULL) {
+ status = mech->gss_inquire_cred_by_mech(mech->context,
+ minor_status,
+ mech_cred, mech_type,
+ name ? &internal_name : NULL,
+ initiator_lifetime,
+ acceptor_lifetime, cred_usage);
- if (name) {
- /*
- * Convert internal_name into a union_name equivalent.
- */
- status = __gss_convert_name_to_union_name(
- &temp_minor_status, mech,
- internal_name, name);
- if (status != GSS_S_COMPLETE) {
- *minor_status = temp_minor_status;
+ if (status != GSS_S_COMPLETE)
return (status);
+
+ if (name) {
+ /*
+ * Convert internal_name into a union_name equivalent.
+ */
+ status = __gss_convert_name_to_union_name(
+ &temp_minor_status, mech,
+ internal_name, name);
+ if (status != GSS_S_COMPLETE) {
+ *minor_status = temp_minor_status;
+ return (status);
+ }
}
+ } else {
+ return (GSS_S_UNAVAILABLE);
}
return (GSS_S_COMPLETE);
diff --git a/usr/src/lib/libgss/oid_ops.c b/usr/src/lib/libgss/oid_ops.c
index 135b45deea..3e806b510b 100644
--- a/usr/src/lib/libgss/oid_ops.c
+++ b/usr/src/lib/libgss/oid_ops.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,6 +103,12 @@ generic_gss_copy_oid(minor_status, oid, new_oid)
if (minor_status)
*minor_status = 0;
+ if (new_oid == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (oid == GSS_C_NO_OID)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
p = (gss_OID) malloc(sizeof (gss_OID_desc));
if (!p) {
return (GSS_S_FAILURE);
@@ -127,6 +133,9 @@ gss_OID_set *oid_set;
if (minor_status)
*minor_status = 0;
+ if (oid_set == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) {
(void) memset(*oid_set, 0, sizeof (gss_OID_set_desc));
return (GSS_S_COMPLETE);
@@ -147,30 +156,34 @@ gss_OID_set *oid_set;
if (minor_status)
*minor_status = 0;
- if (member_oid == NULL || member_oid->length == 0 ||
+ if (member_oid == GSS_C_NO_OID || member_oid->length == 0 ||
member_oid->elements == NULL)
return (GSS_S_CALL_INACCESSIBLE_READ);
+ if (oid_set == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
elist = (*oid_set)->elements;
/* Get an enlarged copy of the array */
if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
sizeof (gss_OID_desc)))) {
- /* Copy in the old junk */
+ /* Copy in the old junk */
if (elist)
(void) memcpy((*oid_set)->elements, elist,
((*oid_set)->count * sizeof (gss_OID_desc)));
- /* Duplicate the input element */
+ /* Duplicate the input element */
lastel = &(*oid_set)->elements[(*oid_set)->count];
if ((lastel->elements =
(void *) malloc(member_oid->length))) {
- /* Success - copy elements */
+
+ /* Success - copy elements */
(void) memcpy(lastel->elements, member_oid->elements,
member_oid->length);
- /* Set length */
+ /* Set length */
lastel->length = member_oid->length;
- /* Update count */
+ /* Update count */
(*oid_set)->count++;
if (elist)
free(elist);
@@ -196,7 +209,7 @@ generic_gss_test_oid_set_member(minor_status, member, set, present)
if (minor_status)
*minor_status = 0;
- if (member == NULL || set == NULL)
+ if (member == GSS_C_NO_OID || set == NULL)
return (GSS_S_CALL_INACCESSIBLE_READ);
if (present == NULL)
@@ -235,14 +248,12 @@ gss_buffer_t oid_str;
if (minor_status)
*minor_status = 0;
- if (oid == NULL || oid->length == 0 || oid->elements == NULL)
+ if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL)
return (GSS_S_CALL_INACCESSIBLE_READ);
if (oid_str == NULL)
return (GSS_S_CALL_INACCESSIBLE_WRITE);
- /* Decoded according to krb5/gssapi_krb5.c */
-
/* First determine the size of the string */
string_length = 0;
number = 0;