xref: /titanic_51/usr/src/lib/libgss/g_dsp_status.c (revision 5e01956f3000408c2a2c5a08c8d0acf2c2a9d8ee)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5503a2b89SPeter Shoults  * Common Development and Distribution License (the "License").
6503a2b89SPeter Shoults  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*5e01956fSGlenn Barry  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  *  glue routine gss_display_status
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <mechglueP.h>
31*5e01956fSGlenn Barry #include "gssapiP_generic.h"
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #endif
367c478bd9Sstevel@tonic-gate #include <string.h>
377c478bd9Sstevel@tonic-gate #include <libintl.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
39*5e01956fSGlenn Barry #include <syslog.h>
407c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN
417c478bd9Sstevel@tonic-gate #error TEXT_DOMAIN not defined
427c478bd9Sstevel@tonic-gate #endif
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /* local function */
457c478bd9Sstevel@tonic-gate static OM_uint32 displayMajor(OM_uint32, OM_uint32 *, gss_buffer_t);
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate OM_uint32
497c478bd9Sstevel@tonic-gate gss_display_status(minor_status,
507c478bd9Sstevel@tonic-gate 			status_value,
517c478bd9Sstevel@tonic-gate 			status_type,
527c478bd9Sstevel@tonic-gate 			req_mech_type,
537c478bd9Sstevel@tonic-gate 			message_context,
547c478bd9Sstevel@tonic-gate 			status_string)
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate OM_uint32 *minor_status;
577c478bd9Sstevel@tonic-gate OM_uint32 status_value;
587c478bd9Sstevel@tonic-gate int status_type;
597c478bd9Sstevel@tonic-gate const gss_OID req_mech_type;
607c478bd9Sstevel@tonic-gate OM_uint32 *message_context;
617c478bd9Sstevel@tonic-gate gss_buffer_t status_string;
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	gss_OID			mech_type = (gss_OID) req_mech_type;
647c478bd9Sstevel@tonic-gate 	gss_mechanism		mech;
65*5e01956fSGlenn Barry 	gss_OID_desc		m_oid = { 0, 0 };
667c478bd9Sstevel@tonic-gate 
67503a2b89SPeter Shoults 	if (minor_status != NULL)
687c478bd9Sstevel@tonic-gate 		*minor_status = 0;
697c478bd9Sstevel@tonic-gate 
70503a2b89SPeter Shoults 	if (status_string != GSS_C_NO_BUFFER) {
717c478bd9Sstevel@tonic-gate 		status_string->length = 0;
727c478bd9Sstevel@tonic-gate 		status_string->value = NULL;
73503a2b89SPeter Shoults 	}
74503a2b89SPeter Shoults 
75503a2b89SPeter Shoults 	if (minor_status == NULL ||
76503a2b89SPeter Shoults 	    message_context == NULL ||
77503a2b89SPeter Shoults 	    status_string == GSS_C_NO_BUFFER)
78503a2b89SPeter Shoults 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 	/* we handle major status codes, and the mechs do the minor */
817c478bd9Sstevel@tonic-gate 	if (status_type == GSS_C_GSS_CODE)
827c478bd9Sstevel@tonic-gate 		return (displayMajor(status_value, message_context,
837c478bd9Sstevel@tonic-gate 				status_string));
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	/*
867c478bd9Sstevel@tonic-gate 	 * must be the minor status - let mechs do the work
877c478bd9Sstevel@tonic-gate 	 * select the appropriate underlying mechanism routine and
887c478bd9Sstevel@tonic-gate 	 * call it.
897c478bd9Sstevel@tonic-gate 	 */
90*5e01956fSGlenn Barry 
91*5e01956fSGlenn Barry 	/* In this version, we only handle status codes that have been
92*5e01956fSGlenn Barry 	   mapped to a flat numbering space.  Look up the value we got
93*5e01956fSGlenn Barry 	   passed.  If it's not found, complain.  */
94*5e01956fSGlenn Barry 	if (status_value == 0) {
95*5e01956fSGlenn Barry 		status_string->value = strdup("Unknown error");
96*5e01956fSGlenn Barry 		if (status_string->value == NULL) {
97*5e01956fSGlenn Barry 			*minor_status = ENOMEM;
98*5e01956fSGlenn Barry 			map_errcode(minor_status);
99*5e01956fSGlenn Barry 			return GSS_S_FAILURE;
100*5e01956fSGlenn Barry 		}
101*5e01956fSGlenn Barry 		status_string->length = strlen(status_string->value);
102*5e01956fSGlenn Barry 		*message_context = 0;
103*5e01956fSGlenn Barry 		*minor_status = 0;
104*5e01956fSGlenn Barry 		return GSS_S_COMPLETE;
105*5e01956fSGlenn Barry 	}
106*5e01956fSGlenn Barry 	{
107*5e01956fSGlenn Barry 		int err;
108*5e01956fSGlenn Barry 	        OM_uint32 m_status = 0, status;
109*5e01956fSGlenn Barry 
110*5e01956fSGlenn Barry 		err = gssint_mecherrmap_get(status_value, &m_oid, &m_status);
111*5e01956fSGlenn Barry 		if (err) {
112*5e01956fSGlenn Barry 			*minor_status = err;
113*5e01956fSGlenn Barry 			map_errcode(minor_status);
114*5e01956fSGlenn Barry 			return GSS_S_BAD_STATUS;
115*5e01956fSGlenn Barry 		}
116*5e01956fSGlenn Barry 
117*5e01956fSGlenn Barry 		if (m_oid.length == 0) {
118*5e01956fSGlenn Barry 			/* Magic flag for com_err values.  */
119*5e01956fSGlenn Barry 			status = gssint_g_display_com_err_status(minor_status,
120*5e01956fSGlenn Barry 							m_status,
121*5e01956fSGlenn Barry 							status_string);
122*5e01956fSGlenn Barry 			if (status != GSS_S_COMPLETE)
123*5e01956fSGlenn Barry 				map_errcode(minor_status);
124*5e01956fSGlenn Barry 			return status;
125*5e01956fSGlenn Barry 		}
126*5e01956fSGlenn Barry 		mech_type = &m_oid;
127*5e01956fSGlenn Barry 		status_value = m_status;
128*5e01956fSGlenn Barry 	}
129*5e01956fSGlenn Barry 
1307c478bd9Sstevel@tonic-gate 	mech = __gss_get_mechanism(mech_type);
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	if (mech && mech->gss_display_status) {
133*5e01956fSGlenn Barry 		OM_uint32 r;
134*5e01956fSGlenn Barry 
1357c478bd9Sstevel@tonic-gate 		if (mech_type == GSS_C_NULL_OID)
1367c478bd9Sstevel@tonic-gate 			mech_type = &mech->mech_type;
1377c478bd9Sstevel@tonic-gate 
138*5e01956fSGlenn Barry 		r = mech->gss_display_status(mech->context, minor_status,
1397c478bd9Sstevel@tonic-gate 				status_value, status_type, mech_type,
140*5e01956fSGlenn Barry 				message_context, status_string);
141*5e01956fSGlenn Barry 		/* How's this for weird?  If we get an error returning the
142*5e01956fSGlenn Barry 		mechanism-specific error code, we save away the
143*5e01956fSGlenn Barry 		mechanism-specific error code describing the error.  */
144*5e01956fSGlenn Barry 		if (r != GSS_S_COMPLETE)
145*5e01956fSGlenn Barry 			map_error(minor_status, mech);
146*5e01956fSGlenn Barry 		return r;
1477c478bd9Sstevel@tonic-gate 	}
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	if (!mech)
1507c478bd9Sstevel@tonic-gate 		return (GSS_S_BAD_MECH);
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	return (GSS_S_UNAVAILABLE);
1537c478bd9Sstevel@tonic-gate } /* gss_display_status */
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate /*
1577c478bd9Sstevel@tonic-gate  * function to map the major error codes
1587c478bd9Sstevel@tonic-gate  * it uses case statements so that the strings could be wrapped by gettext
1597c478bd9Sstevel@tonic-gate  * msgCtxt is interpreted as:
1607c478bd9Sstevel@tonic-gate  *	0 - first call
1617c478bd9Sstevel@tonic-gate  *	1 - routine error
1627c478bd9Sstevel@tonic-gate  *	>= 2 - the supplementary error code bit shifted by 1
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate static OM_uint32
1657c478bd9Sstevel@tonic-gate displayMajor(status, msgCtxt, outStr)
1667c478bd9Sstevel@tonic-gate OM_uint32 status;
1677c478bd9Sstevel@tonic-gate OM_uint32 *msgCtxt;
1687c478bd9Sstevel@tonic-gate gss_buffer_t outStr;
1697c478bd9Sstevel@tonic-gate {
1707c478bd9Sstevel@tonic-gate 	OM_uint32 oneVal, mask = 0x1, currErr;
1717c478bd9Sstevel@tonic-gate 	char *errStr = NULL;
1727c478bd9Sstevel@tonic-gate 	int i, haveErr = 0;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	/* take care of the success value first */
1757c478bd9Sstevel@tonic-gate 	if (status == GSS_S_COMPLETE)
1767c478bd9Sstevel@tonic-gate 		errStr = dgettext(TEXT_DOMAIN,
1777c478bd9Sstevel@tonic-gate 				"The routine completed successfully");
1787c478bd9Sstevel@tonic-gate 	else if (*msgCtxt == 0 && (oneVal = GSS_CALLING_ERROR(status))) {
1797c478bd9Sstevel@tonic-gate 		switch (oneVal) {
1807c478bd9Sstevel@tonic-gate 		case GSS_S_CALL_INACCESSIBLE_READ:
1817c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
1827c478bd9Sstevel@tonic-gate 					"A required input parameter"
1837c478bd9Sstevel@tonic-gate 					" could not be read");
1847c478bd9Sstevel@tonic-gate 			break;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 		case GSS_S_CALL_INACCESSIBLE_WRITE:
1877c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
1887c478bd9Sstevel@tonic-gate 					"A required output parameter"
1897c478bd9Sstevel@tonic-gate 					" could not be written");
1907c478bd9Sstevel@tonic-gate 			break;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 		case GSS_S_CALL_BAD_STRUCTURE:
1937c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
1947c478bd9Sstevel@tonic-gate 					"A parameter was malformed");
1957c478bd9Sstevel@tonic-gate 			break;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		default:
1987c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
1997c478bd9Sstevel@tonic-gate 					"An invalid status code was supplied");
2007c478bd9Sstevel@tonic-gate 			break;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 		/* we now need to determine new value of msgCtxt */
2047c478bd9Sstevel@tonic-gate 		if (GSS_ROUTINE_ERROR(status))
2057c478bd9Sstevel@tonic-gate 			*msgCtxt = 1;
2067c478bd9Sstevel@tonic-gate 		else if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
2077c478bd9Sstevel@tonic-gate 			*msgCtxt = (OM_uint32)(oneVal << 1);
2087c478bd9Sstevel@tonic-gate 		else
2097c478bd9Sstevel@tonic-gate 			*msgCtxt = 0;
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	} else if ((*msgCtxt == 0 || *msgCtxt == 1) &&
2127c478bd9Sstevel@tonic-gate 		(oneVal = GSS_ROUTINE_ERROR(status))) {
2137c478bd9Sstevel@tonic-gate 		switch (oneVal) {
2147c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_MECH:
2157c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2167c478bd9Sstevel@tonic-gate 					"An unsupported mechanism"
2177c478bd9Sstevel@tonic-gate 					" was requested");
2187c478bd9Sstevel@tonic-gate 			break;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_NAME:
2217c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2227c478bd9Sstevel@tonic-gate 					"An invalid name was supplied");
2237c478bd9Sstevel@tonic-gate 			break;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_NAMETYPE:
2267c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2277c478bd9Sstevel@tonic-gate 					"A supplied name was of an"
2287c478bd9Sstevel@tonic-gate 					" unsupported type");
2297c478bd9Sstevel@tonic-gate 			break;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_BINDINGS:
2327c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2337c478bd9Sstevel@tonic-gate 					"Incorrect channel bindings"
2347c478bd9Sstevel@tonic-gate 					" were supplied");
2357c478bd9Sstevel@tonic-gate 			break;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_SIG: /* same as GSS_S_BAD_MIC: */
2387c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2397c478bd9Sstevel@tonic-gate 					"A token had an invalid Message"
2407c478bd9Sstevel@tonic-gate 					" Integrity Check (MIC)");
2417c478bd9Sstevel@tonic-gate 			break;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 		case GSS_S_NO_CRED:
2447c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2457c478bd9Sstevel@tonic-gate 					"No credentials were supplied, or the"
2467c478bd9Sstevel@tonic-gate 					" credentials were unavailable or"
2477c478bd9Sstevel@tonic-gate 					" inaccessible");
2487c478bd9Sstevel@tonic-gate 			break;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 		case GSS_S_NO_CONTEXT:
2517c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2527c478bd9Sstevel@tonic-gate 					"No context has been established");
2537c478bd9Sstevel@tonic-gate 			break;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 		case GSS_S_DEFECTIVE_TOKEN:
2567c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2577c478bd9Sstevel@tonic-gate 					"Invalid token was supplied");
2587c478bd9Sstevel@tonic-gate 			break;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		case GSS_S_DEFECTIVE_CREDENTIAL:
2617c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2627c478bd9Sstevel@tonic-gate 					"Invalid credential was supplied");
2637c478bd9Sstevel@tonic-gate 			break;
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 		case GSS_S_CREDENTIALS_EXPIRED:
2667c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2677c478bd9Sstevel@tonic-gate 					"The referenced credential has"
2687c478bd9Sstevel@tonic-gate 					" expired");
2697c478bd9Sstevel@tonic-gate 			break;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 		case GSS_S_CONTEXT_EXPIRED:
2727c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2737c478bd9Sstevel@tonic-gate 					"The referenced context has expired");
2747c478bd9Sstevel@tonic-gate 			break;
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 		case GSS_S_FAILURE:
2777c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2787c478bd9Sstevel@tonic-gate 					"Unspecified GSS failure.  Minor code"
2797c478bd9Sstevel@tonic-gate 					" may provide more information");
2807c478bd9Sstevel@tonic-gate 			break;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_QOP:
2837c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2847c478bd9Sstevel@tonic-gate 					"The quality-of-protection (QOP) "
2857c478bd9Sstevel@tonic-gate 					"requested could not be provided");
2867c478bd9Sstevel@tonic-gate 			break;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 		case GSS_S_UNAUTHORIZED:
2897c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2907c478bd9Sstevel@tonic-gate 					"The operation is forbidden by local"
2917c478bd9Sstevel@tonic-gate 					" security policy");
2927c478bd9Sstevel@tonic-gate 			break;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 		case GSS_S_UNAVAILABLE:
2957c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
2967c478bd9Sstevel@tonic-gate 					"The operation or option is not"
2977c478bd9Sstevel@tonic-gate 					" available or unsupported");
2987c478bd9Sstevel@tonic-gate 			break;
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 		case GSS_S_DUPLICATE_ELEMENT:
3017c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3027c478bd9Sstevel@tonic-gate 					"The requested credential element"
3037c478bd9Sstevel@tonic-gate 					" already exists");
3047c478bd9Sstevel@tonic-gate 			break;
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 		case GSS_S_NAME_NOT_MN:
3077c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3087c478bd9Sstevel@tonic-gate 					"The provided name was not mechanism"
3097c478bd9Sstevel@tonic-gate 					" specific (MN)");
3107c478bd9Sstevel@tonic-gate 			break;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 		case GSS_S_BAD_STATUS:
3137c478bd9Sstevel@tonic-gate 		default:
3147c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3157c478bd9Sstevel@tonic-gate 					"An invalid status code was supplied");
3167c478bd9Sstevel@tonic-gate 		}
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 		/* we must determine if the caller should call us again */
3197c478bd9Sstevel@tonic-gate 		if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
3207c478bd9Sstevel@tonic-gate 			*msgCtxt = (OM_uint32)(oneVal << 1);
3217c478bd9Sstevel@tonic-gate 		else
3227c478bd9Sstevel@tonic-gate 			*msgCtxt = 0;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 	} else if ((*msgCtxt == 0 || *msgCtxt >= 2) &&
3257c478bd9Sstevel@tonic-gate 		(oneVal = GSS_SUPPLEMENTARY_INFO(status))) {
3267c478bd9Sstevel@tonic-gate 		/*
3277c478bd9Sstevel@tonic-gate 		 * if msgCtxt is not 0, then it should encode
3287c478bd9Sstevel@tonic-gate 		 * the supplementary error code we should be printing
3297c478bd9Sstevel@tonic-gate 		 */
3307c478bd9Sstevel@tonic-gate 		if (*msgCtxt >= 2)
3317c478bd9Sstevel@tonic-gate 			oneVal = (OM_uint32) (*msgCtxt) >> 1;
3327c478bd9Sstevel@tonic-gate 		else
3337c478bd9Sstevel@tonic-gate 			oneVal = GSS_SUPPLEMENTARY_INFO(status);
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 		/* we display the errors LSB first */
3367c478bd9Sstevel@tonic-gate 		for (i = 0; i < 16; i++) {
3377c478bd9Sstevel@tonic-gate 			if (oneVal & mask) {
3387c478bd9Sstevel@tonic-gate 				haveErr = 1;
3397c478bd9Sstevel@tonic-gate 				break;
3407c478bd9Sstevel@tonic-gate 			}
3417c478bd9Sstevel@tonic-gate 			mask <<= 1;
3427c478bd9Sstevel@tonic-gate 		}
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 		/* isolate the bit or if not found set to illegal value */
3457c478bd9Sstevel@tonic-gate 		if (haveErr)
3467c478bd9Sstevel@tonic-gate 			currErr = oneVal & mask;
3477c478bd9Sstevel@tonic-gate 		else
3487c478bd9Sstevel@tonic-gate 			currErr = 1 << 17; /* illegal value */
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 		switch (currErr) {
3517c478bd9Sstevel@tonic-gate 		case GSS_S_CONTINUE_NEEDED:
3527c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3537c478bd9Sstevel@tonic-gate 					"The routine must be called again to"
3547c478bd9Sstevel@tonic-gate 					" complete its function");
3557c478bd9Sstevel@tonic-gate 			break;
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 		case GSS_S_DUPLICATE_TOKEN:
3587c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3597c478bd9Sstevel@tonic-gate 					"The token was a duplicate of an"
3607c478bd9Sstevel@tonic-gate 					" earlier token");
3617c478bd9Sstevel@tonic-gate 			break;
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 		case GSS_S_OLD_TOKEN:
3647c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3657c478bd9Sstevel@tonic-gate 					"The token's validity period"
3667c478bd9Sstevel@tonic-gate 					" has expired");
3677c478bd9Sstevel@tonic-gate 			break;
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 		case GSS_S_UNSEQ_TOKEN:
3707c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3717c478bd9Sstevel@tonic-gate 					"A later token has already been"
3727c478bd9Sstevel@tonic-gate 					" processed");
3737c478bd9Sstevel@tonic-gate 			break;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 		case GSS_S_GAP_TOKEN:
3767c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3777c478bd9Sstevel@tonic-gate 					"An expected per-message token was"
3787c478bd9Sstevel@tonic-gate 					" not received");
3797c478bd9Sstevel@tonic-gate 			break;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 		default:
3827c478bd9Sstevel@tonic-gate 			errStr = dgettext(TEXT_DOMAIN,
3837c478bd9Sstevel@tonic-gate 					"An invalid status code was supplied");
3847c478bd9Sstevel@tonic-gate 		}
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 		/*
3877c478bd9Sstevel@tonic-gate 		 * we must check if there is any other supplementary errors
3887c478bd9Sstevel@tonic-gate 		 * if found, then turn off current bit, and store next value
3897c478bd9Sstevel@tonic-gate 		 * in msgCtxt shifted by 1 bit
3907c478bd9Sstevel@tonic-gate 		 */
3917c478bd9Sstevel@tonic-gate 		if (!haveErr)
3927c478bd9Sstevel@tonic-gate 			*msgCtxt = 0;
3937c478bd9Sstevel@tonic-gate 		else if (GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask)
3947c478bd9Sstevel@tonic-gate 			*msgCtxt = (OM_uint32)
3957c478bd9Sstevel@tonic-gate 				((GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask) << 1);
3967c478bd9Sstevel@tonic-gate 		else
3977c478bd9Sstevel@tonic-gate 			*msgCtxt = 0;
3987c478bd9Sstevel@tonic-gate 	}
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	if (errStr == NULL)
4017c478bd9Sstevel@tonic-gate 		errStr = dgettext(TEXT_DOMAIN,
4027c478bd9Sstevel@tonic-gate 				"An invalid status code was supplied");
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	/* now copy the status code and return to caller */
4057c478bd9Sstevel@tonic-gate 	outStr->length = strlen(errStr);
406*5e01956fSGlenn Barry 	outStr->value = strdup(errStr);
4077c478bd9Sstevel@tonic-gate 	if (outStr->value == NULL) {
4087c478bd9Sstevel@tonic-gate 		outStr->length = 0;
4097c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
4107c478bd9Sstevel@tonic-gate 	}
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	return (GSS_S_COMPLETE);
4137c478bd9Sstevel@tonic-gate } /* displayMajor */
414