xref: /freebsd/lib/libgssapi/gss_display_status.c (revision ae77177087c655fc883075af4f425b37e032cd05)
1c0b9f4feSDoug Rabson /*-
2c0b9f4feSDoug Rabson  * Copyright (c) 2005 Doug Rabson
3c0b9f4feSDoug Rabson  * All rights reserved.
4c0b9f4feSDoug Rabson  *
5c0b9f4feSDoug Rabson  * Redistribution and use in source and binary forms, with or without
6c0b9f4feSDoug Rabson  * modification, are permitted provided that the following conditions
7c0b9f4feSDoug Rabson  * are met:
8c0b9f4feSDoug Rabson  * 1. Redistributions of source code must retain the above copyright
9c0b9f4feSDoug Rabson  *    notice, this list of conditions and the following disclaimer.
10c0b9f4feSDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
11c0b9f4feSDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
12c0b9f4feSDoug Rabson  *    documentation and/or other materials provided with the distribution.
13c0b9f4feSDoug Rabson  *
14c0b9f4feSDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15c0b9f4feSDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16c0b9f4feSDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c0b9f4feSDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18c0b9f4feSDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c0b9f4feSDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c0b9f4feSDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c0b9f4feSDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22c0b9f4feSDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23c0b9f4feSDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24c0b9f4feSDoug Rabson  * SUCH DAMAGE.
25c0b9f4feSDoug Rabson  *
26c0b9f4feSDoug Rabson  *	$FreeBSD$
27c0b9f4feSDoug Rabson  */
2822a25490SDoug Rabson /*
29bf3f9db6SUlrich Spörlein  * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
3022a25490SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
3122a25490SDoug Rabson  * All rights reserved.
3222a25490SDoug Rabson  *
3322a25490SDoug Rabson  * Redistribution and use in source and binary forms, with or without
3422a25490SDoug Rabson  * modification, are permitted provided that the following conditions
3522a25490SDoug Rabson  * are met:
3622a25490SDoug Rabson  *
3722a25490SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
3822a25490SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
3922a25490SDoug Rabson  *
4022a25490SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
4122a25490SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
4222a25490SDoug Rabson  *    documentation and/or other materials provided with the distribution.
4322a25490SDoug Rabson  *
4422a25490SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
4522a25490SDoug Rabson  *    may be used to endorse or promote products derived from this software
4622a25490SDoug Rabson  *    without specific prior written permission.
4722a25490SDoug Rabson  *
4822a25490SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4922a25490SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5022a25490SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5122a25490SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
5222a25490SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5322a25490SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5422a25490SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5522a25490SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5622a25490SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5722a25490SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5822a25490SDoug Rabson  * SUCH DAMAGE.
5922a25490SDoug Rabson  */
6033f12199SDoug Rabson /*
61bf3f9db6SUlrich Spörlein  * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
6233f12199SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
6333f12199SDoug Rabson  * All rights reserved.
6433f12199SDoug Rabson  *
6533f12199SDoug Rabson  * Redistribution and use in source and binary forms, with or without
6633f12199SDoug Rabson  * modification, are permitted provided that the following conditions
6733f12199SDoug Rabson  * are met:
6833f12199SDoug Rabson  *
6933f12199SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
7033f12199SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
7133f12199SDoug Rabson  *
7233f12199SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
7333f12199SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
7433f12199SDoug Rabson  *    documentation and/or other materials provided with the distribution.
7533f12199SDoug Rabson  *
7633f12199SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
7733f12199SDoug Rabson  *    may be used to endorse or promote products derived from this software
7833f12199SDoug Rabson  *    without specific prior written permission.
7933f12199SDoug Rabson  *
8033f12199SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
8133f12199SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8233f12199SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8333f12199SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
8433f12199SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8533f12199SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
8633f12199SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8733f12199SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
8833f12199SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
8933f12199SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9033f12199SDoug Rabson  * SUCH DAMAGE.
9133f12199SDoug Rabson  */
92c0b9f4feSDoug Rabson 
93c0b9f4feSDoug Rabson #include <gssapi/gssapi.h>
9433f12199SDoug Rabson #include <stdio.h>
95c0b9f4feSDoug Rabson #include <string.h>
9633f12199SDoug Rabson #include <stdlib.h>
9722a25490SDoug Rabson #include <errno.h>
98c0b9f4feSDoug Rabson 
99c0b9f4feSDoug Rabson #include "mech_switch.h"
10033f12199SDoug Rabson #include "utils.h"
101c0b9f4feSDoug Rabson 
10222a25490SDoug Rabson static const char *
10322a25490SDoug Rabson calling_error(OM_uint32 v)
10422a25490SDoug Rabson {
10522a25490SDoug Rabson     static const char *msgs[] = {
10622a25490SDoug Rabson 	NULL,			/* 0 */
10722a25490SDoug Rabson 	"A required input parameter could not be read.", /*  */
10822a25490SDoug Rabson 	"A required output parameter could not be written.", /*  */
10922a25490SDoug Rabson 	"A parameter was malformed"
110c0b9f4feSDoug Rabson     };
111c0b9f4feSDoug Rabson 
11222a25490SDoug Rabson     v >>= GSS_C_CALLING_ERROR_OFFSET;
113c0b9f4feSDoug Rabson 
11422a25490SDoug Rabson     if (v == 0)
11522a25490SDoug Rabson 	return "";
11622a25490SDoug Rabson     else if (v >= sizeof(msgs)/sizeof(*msgs))
11722a25490SDoug Rabson 	return "unknown calling error";
11822a25490SDoug Rabson     else
11922a25490SDoug Rabson 	return msgs[v];
12022a25490SDoug Rabson }
12122a25490SDoug Rabson 
12222a25490SDoug Rabson static const char *
12322a25490SDoug Rabson routine_error(OM_uint32 v)
12422a25490SDoug Rabson {
12522a25490SDoug Rabson     static const char *msgs[] = {
12633f12199SDoug Rabson 	"Function completed successfully",			/* 0 */
12722a25490SDoug Rabson 	"An unsupported mechanism was requested",
12822a25490SDoug Rabson 	"An invalid name was supplied",
12922a25490SDoug Rabson 	"A supplied name was of an unsupported type",
13022a25490SDoug Rabson 	"Incorrect channel bindings were supplied",
13122a25490SDoug Rabson 	"An invalid status code was supplied",
13222a25490SDoug Rabson 	"A token had an invalid MIC",
13322a25490SDoug Rabson 	"No credentials were supplied, "
13422a25490SDoug Rabson 	"or the credentials were unavailable or inaccessible.",
13522a25490SDoug Rabson 	"No context has been established",
13622a25490SDoug Rabson 	"A token was invalid",
13722a25490SDoug Rabson 	"A credential was invalid",
13822a25490SDoug Rabson 	"The referenced credentials have expired",
13922a25490SDoug Rabson 	"The context has expired",
14022a25490SDoug Rabson 	"Miscellaneous failure (see text)",
14122a25490SDoug Rabson 	"The quality-of-protection requested could not be provide",
14222a25490SDoug Rabson 	"The operation is forbidden by local security policy",
14322a25490SDoug Rabson 	"The operation or option is not available",
14422a25490SDoug Rabson 	"The requested credential element already exists",
14522a25490SDoug Rabson 	"The provided name was not a mechanism name.",
14622a25490SDoug Rabson     };
14722a25490SDoug Rabson 
14822a25490SDoug Rabson     v >>= GSS_C_ROUTINE_ERROR_OFFSET;
14922a25490SDoug Rabson 
15033f12199SDoug Rabson     if (v >= sizeof(msgs)/sizeof(*msgs))
15122a25490SDoug Rabson 	return "unknown routine error";
15222a25490SDoug Rabson     else
15322a25490SDoug Rabson 	return msgs[v];
15422a25490SDoug Rabson }
15522a25490SDoug Rabson 
15622a25490SDoug Rabson static const char *
15722a25490SDoug Rabson supplementary_error(OM_uint32 v)
15822a25490SDoug Rabson {
15922a25490SDoug Rabson     static const char *msgs[] = {
16022a25490SDoug Rabson 	"normal completion",
16122a25490SDoug Rabson 	"continuation call to routine required",
16222a25490SDoug Rabson 	"duplicate per-message token detected",
16322a25490SDoug Rabson 	"timed-out per-message token detected",
16422a25490SDoug Rabson 	"reordered (early) per-message token detected",
16522a25490SDoug Rabson 	"skipped predecessor token(s) detected"
16622a25490SDoug Rabson     };
16722a25490SDoug Rabson 
16822a25490SDoug Rabson     v >>= GSS_C_SUPPLEMENTARY_OFFSET;
16922a25490SDoug Rabson 
17022a25490SDoug Rabson     if (v >= sizeof(msgs)/sizeof(*msgs))
17122a25490SDoug Rabson 	return "unknown routine error";
17222a25490SDoug Rabson     else
17322a25490SDoug Rabson 	return msgs[v];
17422a25490SDoug Rabson }
175c0b9f4feSDoug Rabson 
17633f12199SDoug Rabson #if defined(__sparc64__) || defined(__arm__) || defined(__mips__)
17733f12199SDoug Rabson 
17833f12199SDoug Rabson /*
17933f12199SDoug Rabson  * These platforms don't support TLS on FreeBSD - threads will just
18033f12199SDoug Rabson  * have to step on each other's error values for now.
18133f12199SDoug Rabson  */
18233f12199SDoug Rabson #define __thread
18333f12199SDoug Rabson 
18433f12199SDoug Rabson #endif
18533f12199SDoug Rabson 
18633f12199SDoug Rabson struct mg_thread_ctx {
18733f12199SDoug Rabson     gss_OID mech;
18833f12199SDoug Rabson     OM_uint32 maj_stat;
18933f12199SDoug Rabson     OM_uint32 min_stat;
19033f12199SDoug Rabson     gss_buffer_desc maj_error;
19133f12199SDoug Rabson     gss_buffer_desc min_error;
19233f12199SDoug Rabson };
19333f12199SDoug Rabson static __thread struct mg_thread_ctx last_error_context;
19433f12199SDoug Rabson 
19533f12199SDoug Rabson static OM_uint32
19633f12199SDoug Rabson _gss_mg_get_error(const gss_OID mech, OM_uint32 type,
19733f12199SDoug Rabson 		  OM_uint32 value, gss_buffer_t string)
19833f12199SDoug Rabson {
19933f12199SDoug Rabson 	struct mg_thread_ctx *mg;
20033f12199SDoug Rabson 
20133f12199SDoug Rabson 	mg = &last_error_context;
20233f12199SDoug Rabson 
20333f12199SDoug Rabson 	if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0)
20433f12199SDoug Rabson 		return (GSS_S_BAD_STATUS);
20533f12199SDoug Rabson 
20633f12199SDoug Rabson 	switch (type) {
20733f12199SDoug Rabson 	case GSS_C_GSS_CODE: {
20833f12199SDoug Rabson 		if (value != mg->maj_stat || mg->maj_error.length == 0)
20933f12199SDoug Rabson 			break;
21033f12199SDoug Rabson 		string->value = malloc(mg->maj_error.length);
21133f12199SDoug Rabson 		string->length = mg->maj_error.length;
21233f12199SDoug Rabson 		memcpy(string->value, mg->maj_error.value,
21333f12199SDoug Rabson 		    mg->maj_error.length);
21433f12199SDoug Rabson 		return (GSS_S_COMPLETE);
21533f12199SDoug Rabson 	}
21633f12199SDoug Rabson 	case GSS_C_MECH_CODE: {
21733f12199SDoug Rabson 		if (value != mg->min_stat || mg->min_error.length == 0)
21833f12199SDoug Rabson 			break;
21933f12199SDoug Rabson 		string->value = malloc(mg->min_error.length);
22033f12199SDoug Rabson 		string->length = mg->min_error.length;
22133f12199SDoug Rabson 		memcpy(string->value, mg->min_error.value,
22233f12199SDoug Rabson 		    mg->min_error.length);
22333f12199SDoug Rabson 		return (GSS_S_COMPLETE);
22433f12199SDoug Rabson 	}
22533f12199SDoug Rabson 	}
22633f12199SDoug Rabson 	string->value = NULL;
22733f12199SDoug Rabson 	string->length = 0;
22833f12199SDoug Rabson 	return (GSS_S_BAD_STATUS);
22933f12199SDoug Rabson }
23033f12199SDoug Rabson 
23133f12199SDoug Rabson void
23233f12199SDoug Rabson _gss_mg_error(struct _gss_mech_switch *m, OM_uint32 maj, OM_uint32 min)
23333f12199SDoug Rabson {
23433f12199SDoug Rabson 	OM_uint32 major_status, minor_status;
23533f12199SDoug Rabson 	OM_uint32 message_content;
23633f12199SDoug Rabson 	struct mg_thread_ctx *mg;
23733f12199SDoug Rabson 
23833f12199SDoug Rabson 	mg = &last_error_context;
23933f12199SDoug Rabson 
24033f12199SDoug Rabson 	gss_release_buffer(&minor_status, &mg->maj_error);
24133f12199SDoug Rabson 	gss_release_buffer(&minor_status, &mg->min_error);
24233f12199SDoug Rabson 
24333f12199SDoug Rabson 	mg->mech = &m->gm_mech_oid;
24433f12199SDoug Rabson 	mg->maj_stat = maj;
24533f12199SDoug Rabson 	mg->min_stat = min;
24633f12199SDoug Rabson 
24733f12199SDoug Rabson 	major_status = m->gm_display_status(&minor_status,
24833f12199SDoug Rabson 	    maj,
24933f12199SDoug Rabson 	    GSS_C_GSS_CODE,
25033f12199SDoug Rabson 	    &m->gm_mech_oid,
25133f12199SDoug Rabson 	    &message_content,
25233f12199SDoug Rabson 	    &mg->maj_error);
25333f12199SDoug Rabson 	if (GSS_ERROR(major_status)) {
25433f12199SDoug Rabson 		mg->maj_error.value = NULL;
25533f12199SDoug Rabson 		mg->maj_error.length = 0;
25633f12199SDoug Rabson 	}
25733f12199SDoug Rabson 	major_status = m->gm_display_status(&minor_status,
25833f12199SDoug Rabson 	    min,
25933f12199SDoug Rabson 	    GSS_C_MECH_CODE,
26033f12199SDoug Rabson 	    &m->gm_mech_oid,
26133f12199SDoug Rabson 	    &message_content,
26233f12199SDoug Rabson 	    &mg->min_error);
26333f12199SDoug Rabson 	if (GSS_ERROR(major_status)) {
26433f12199SDoug Rabson 		mg->min_error.value = NULL;
26533f12199SDoug Rabson 		mg->min_error.length = 0;
26633f12199SDoug Rabson 	}
26733f12199SDoug Rabson }
26833f12199SDoug Rabson 
269c0b9f4feSDoug Rabson OM_uint32
270c0b9f4feSDoug Rabson gss_display_status(OM_uint32 *minor_status,
271c0b9f4feSDoug Rabson     OM_uint32 status_value,
272c0b9f4feSDoug Rabson     int status_type,
27333f12199SDoug Rabson     const gss_OID mech_type,
274c0b9f4feSDoug Rabson     OM_uint32 *message_content,
275c0b9f4feSDoug Rabson     gss_buffer_t status_string)
276c0b9f4feSDoug Rabson {
277c0b9f4feSDoug Rabson 	OM_uint32 major_status;
27841ec3746SDoug Rabson 
27933f12199SDoug Rabson 	_gss_buffer_zero(status_string);
28033f12199SDoug Rabson 	*message_content = 0;
28133f12199SDoug Rabson 
28233f12199SDoug Rabson 	major_status = _gss_mg_get_error(mech_type, status_type,
28333f12199SDoug Rabson 					 status_value, status_string);
28433f12199SDoug Rabson 	if (major_status == GSS_S_COMPLETE) {
28533f12199SDoug Rabson 
28633f12199SDoug Rabson 		*message_content = 0;
28733f12199SDoug Rabson 		*minor_status = 0;
28833f12199SDoug Rabson 		return (GSS_S_COMPLETE);
28941ec3746SDoug Rabson 	}
290c0b9f4feSDoug Rabson 
291c0b9f4feSDoug Rabson 	*minor_status = 0;
292c0b9f4feSDoug Rabson 	switch (status_type) {
29322a25490SDoug Rabson 	case GSS_C_GSS_CODE: {
29422a25490SDoug Rabson 		char *buf;
295c0b9f4feSDoug Rabson 
29622a25490SDoug Rabson 		if (GSS_SUPPLEMENTARY_INFO(status_value))
29722a25490SDoug Rabson 		    asprintf(&buf, "%s", supplementary_error(
29822a25490SDoug Rabson 		        GSS_SUPPLEMENTARY_INFO(status_value)));
29922a25490SDoug Rabson 		else
30022a25490SDoug Rabson 		    asprintf (&buf, "%s %s",
30122a25490SDoug Rabson 		        calling_error(GSS_CALLING_ERROR(status_value)),
30222a25490SDoug Rabson 			routine_error(GSS_ROUTINE_ERROR(status_value)));
30322a25490SDoug Rabson 
30433f12199SDoug Rabson 		if (buf == NULL)
30533f12199SDoug Rabson 			break;
30633f12199SDoug Rabson 
30722a25490SDoug Rabson 		status_string->length = strlen(buf);
30822a25490SDoug Rabson 		status_string->value  = buf;
30922a25490SDoug Rabson 
31033f12199SDoug Rabson 		return (GSS_S_COMPLETE);
31122a25490SDoug Rabson 	}
31222a25490SDoug Rabson 	case GSS_C_MECH_CODE: {
31333f12199SDoug Rabson 		OM_uint32 maj_junk, min_junk;
31433f12199SDoug Rabson 		gss_buffer_desc oid;
31533f12199SDoug Rabson 		char *buf;
31633f12199SDoug Rabson 
31733f12199SDoug Rabson 		maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid);
31833f12199SDoug Rabson 		if (maj_junk != GSS_S_COMPLETE) {
31933f12199SDoug Rabson 			oid.value = strdup("unknown");
32033f12199SDoug Rabson 			oid.length = 7;
32133f12199SDoug Rabson 		}
32233f12199SDoug Rabson 
32333f12199SDoug Rabson 		asprintf (&buf, "unknown mech-code %lu for mech %.*s",
32433f12199SDoug Rabson 			  (unsigned long)status_value,
32533f12199SDoug Rabson 			  (int)oid.length, (char *)oid.value);
32633f12199SDoug Rabson 		if (maj_junk == GSS_S_COMPLETE)
32733f12199SDoug Rabson 			gss_release_buffer(&min_junk, &oid);
32833f12199SDoug Rabson 
32933f12199SDoug Rabson 		if (buf == NULL)
33033f12199SDoug Rabson 		    break;
33133f12199SDoug Rabson 
33233f12199SDoug Rabson 		status_string->length = strlen(buf);
33333f12199SDoug Rabson 		status_string->value  = buf;
33433f12199SDoug Rabson 
335c0b9f4feSDoug Rabson 		return (GSS_S_COMPLETE);
336c0b9f4feSDoug Rabson 	}
337c0b9f4feSDoug Rabson 	}
33833f12199SDoug Rabson 	_gss_buffer_zero(status_string);
339c0b9f4feSDoug Rabson 	return (GSS_S_BAD_STATUS);
340c0b9f4feSDoug Rabson }
341*ae771770SStanislav Sedov 
342*ae771770SStanislav Sedov void
343*ae771770SStanislav Sedov _gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)
344*ae771770SStanislav Sedov {
345*ae771770SStanislav Sedov 	struct _gss_mech_switch *m;
346*ae771770SStanislav Sedov 
347*ae771770SStanislav Sedov 	m = _gss_find_mech_switch(mech);
348*ae771770SStanislav Sedov 	if (m != NULL)
349*ae771770SStanislav Sedov 		_gss_mg_error(m, maj, min);
350*ae771770SStanislav Sedov }
351