+ return (status);
+}
+
+/*
+ * This parses an exported name, extracting the mechanism specific portion
+ * to use for ACL checking. It verifies that the name belongs the mechanism
+ * originally selected.
+ */
+static OM_uint32
+ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
+{
+ u_char *tok;
+ OM_uint32 offset;
+ OM_uint32 oidl;
+
+ tok = ename->value;
+
+#ifdef GSI /* GSI gss_export_name() is broken. */
+ if ((ctx->oid->length == gssapi_gsi_mech.oid.length) &&
+ (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements,
+ gssapi_gsi_mech.oid.length) == 0)) {
+ name->length = ename->length;
+ name->value = xmalloc(ename->length+1);
+ memcpy(name->value, ename->value, ename->length);
+ return GSS_S_COMPLETE;
+ }
+#endif
+
+ /*
+ * Check that ename is long enough for all of the fixed length
+ * header, and that the initial ID bytes are correct
+ */
+
+ if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0)
+ return GSS_S_FAILURE;
+
+ /*
+ * Extract the OID, and check it. Here GSSAPI breaks with tradition
+ * and does use the OID type and length bytes. To confuse things
+ * there are two lengths - the first including these, and the
+ * second without.
+ */
+
+ oidl = get_u16(tok+2); /* length including next two bytes */
+ oidl = oidl-2; /* turn it into the _real_ length of the variable OID */
+
+ /*
+ * Check the BER encoding for correct type and length, that the
+ * string is long enough and that the OID matches that in our context
+ */
+ if (tok[4] != 0x06 || tok[5] != oidl ||
+ ename->length < oidl+6 ||
+ !ssh_gssapi_check_oid(ctx, tok+6, oidl))
+ return GSS_S_FAILURE;
+
+ offset = oidl+6;
+
+ if (ename->length < offset+4)
+ return GSS_S_FAILURE;
+
+ name->length = get_u32(tok+offset);
+ offset += 4;
+
+ if (ename->length < offset+name->length)
+ return GSS_S_FAILURE;
+
+ name->value = xmalloc(name->length+1);
+ memcpy(name->value, tok+offset, name->length);
+ ((char *)name->value)[name->length] = 0;
+
+ return GSS_S_COMPLETE;