Problem with kerberos and ssh.

Eric eric at nospam.org
Mon Feb 27 20:11:24 EST 2006


Jeffrey Altman wrote:
> 
> What is gss_union_name_t defined as?   This is not a GSS type.
> 
> gss_accept_sec_context() exports a gss_name_t object and
> gss_export_name() takes a gss_name_t as input.  gss_name_t when produced
> by a krb5 gss mechanism will be a krb5_principal.  However, gss_name_t
> is not required be a krb5_principal.

It appears to be a type internally used by gss, and it is created 
directly by gss_accept_sec_context().  I found the structure definitions in:

	krb5-1.4.3/src/lib/gssapi/mechglue/mglueP.h

and also in:

	libgssapi-0.7/src/mglueP.h

the odd thing is that the two definitions are substantively different. 
THe one from krb5-1.4.3 looks like:

/*
  * Generic GSSAPI names.  A name can either be a generic name, or a
  * mechanism specific name....
  */
typedef struct gss_union_name_t {
	gss_OID			name_type;
	gss_buffer_t		external_name;
	/*
	 * These last two fields are only filled in for mechanism
	 * names.
	 */
	gss_OID			mech_type;
	gss_name_t		mech_name;
} gss_union_name_desc, *gss_union_name_t;


The one from libgssapi-0.7 looks like:

typedef struct gss_union_name_t {
	gss_mechanism		gss_mech;
	gss_OID			name_type;
	gss_buffer_t		external_name;
	/*
	 * These last two fields are only filled in for mechanism
	 * names.
	 */
	gss_OID			mech_type;
	gss_name_t		mech_name;
} gss_union_name_desc, *gss_union_name_t;

The place where this datatype is externally exposed (albeit through an 
opaque pointer) is here:

gss_accept_sec_context() in libgssapi-0.7:g_accept_sec_context.c

=================================

	    status = mech->gss_accept_sec_context(
#ifdef USE_MECH_CONTEXT
						  mech->context,
#endif
						  minor_status,
						  &union_ctx_id->internal_ctx_id,
						  input_cred_handle,
						  input_token_buffer,
						  input_chan_bindings,
						  &internal_name,
						  mech_type,
						  output_token,
						  ret_flags,
						  time_rec,
						  delegated_cred_handle);

	    /* If there's more work to do, keep going... */
	    if (status == GSS_S_CONTINUE_NEEDED)
		goto continue_out;

	    /* if the call failed, return with failure */
	    if (status != GSS_S_COMPLETE)
		goto error_out;

	    /*
	     * if src_name is non-NULL,
	     * convert internal_name into a union name equivalent
	     * First call the mechanism specific display_name()
	     * then call gss_import_name() to create
	     * the union name struct cast to src_name
	     */
	    if (src_name != NULL && status == GSS_S_COMPLETE) {
		temp_status = __gss_convert_name_to_union_name(
		       &temp_minor_status, mech, internal_name, src_name);
		if (temp_status != GSS_S_COMPLETE) {
		    if (minor_status)
			*minor_status = temp_minor_status;
		    gss_release_buffer(&temp_minor_status, output_token);
		    return (temp_status);
		}
	    }

==============================

It is the thing at the end - __gss_convert_name_to_union_name that 
creates the thing that is passed out of gss_accept_sec_context().

It may well be true that a gss_name_t isn't required to be a 
krb5_principal.  I have also posted to the openssh mailing list - people 
who know the code a lot better can take what I have discovered and do a 
better job of figuring out where things are really going wrong.



More information about the Kerberos mailing list