xref: /onnv-gate/usr/src/lib/libgss/g_compare_name.c (revision 13132:9615cdbf7b70)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
59698SPeter.Shoults@Sun.COM  * Common Development and Distribution License (the "License").
69698SPeter.Shoults@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*13132SGlenn.Barry@oracle.com  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  *  glue routine for gss_compare_name
270Sstevel@tonic-gate  *
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <mechglueP.h>
31*13132SGlenn.Barry@oracle.com #include "gssapiP_generic.h"
320Sstevel@tonic-gate #ifdef HAVE_STDLIB_H
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #endif
350Sstevel@tonic-gate #include <string.h>
360Sstevel@tonic-gate 
379698SPeter.Shoults@Sun.COM static OM_uint32
val_comp_name_args(OM_uint32 * minor_status,gss_name_t name1,gss_name_t name2,int * name_equal)389698SPeter.Shoults@Sun.COM val_comp_name_args(
399698SPeter.Shoults@Sun.COM 	OM_uint32 *minor_status,
409698SPeter.Shoults@Sun.COM 	gss_name_t name1,
419698SPeter.Shoults@Sun.COM 	gss_name_t name2,
429698SPeter.Shoults@Sun.COM 	int *name_equal)
439698SPeter.Shoults@Sun.COM {
449698SPeter.Shoults@Sun.COM 
459698SPeter.Shoults@Sun.COM 	/* Initialize outputs. */
469698SPeter.Shoults@Sun.COM 
479698SPeter.Shoults@Sun.COM 	if (minor_status != NULL)
489698SPeter.Shoults@Sun.COM 		*minor_status = 0;
499698SPeter.Shoults@Sun.COM 
509698SPeter.Shoults@Sun.COM 	/* Validate arguments. */
519698SPeter.Shoults@Sun.COM 
529698SPeter.Shoults@Sun.COM 	if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME)
539698SPeter.Shoults@Sun.COM 		return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
549698SPeter.Shoults@Sun.COM 
559698SPeter.Shoults@Sun.COM 	if (name_equal == NULL)
569698SPeter.Shoults@Sun.COM 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
579698SPeter.Shoults@Sun.COM 
589698SPeter.Shoults@Sun.COM 	return (GSS_S_COMPLETE);
599698SPeter.Shoults@Sun.COM }
609698SPeter.Shoults@Sun.COM 
610Sstevel@tonic-gate OM_uint32
gss_compare_name(minor_status,name1,name2,name_equal)620Sstevel@tonic-gate gss_compare_name(minor_status,
630Sstevel@tonic-gate 			name1,
640Sstevel@tonic-gate 			name2,
650Sstevel@tonic-gate 			name_equal)
660Sstevel@tonic-gate 
670Sstevel@tonic-gate OM_uint32 *minor_status;
680Sstevel@tonic-gate const gss_name_t name1;
690Sstevel@tonic-gate const gss_name_t name2;
700Sstevel@tonic-gate int *name_equal;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate {
730Sstevel@tonic-gate 	OM_uint32		major_status, temp_minor;
740Sstevel@tonic-gate 	gss_union_name_t	union_name1, union_name2;
75*13132SGlenn.Barry@oracle.com 	gss_mechanism		mech = NULL;
760Sstevel@tonic-gate 	gss_name_t		internal_name;
770Sstevel@tonic-gate 
789698SPeter.Shoults@Sun.COM 	major_status = val_comp_name_args(minor_status,
799698SPeter.Shoults@Sun.COM 					name1, name2, name_equal);
809698SPeter.Shoults@Sun.COM 	if (major_status != GSS_S_COMPLETE)
819698SPeter.Shoults@Sun.COM 		return (major_status);
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	union_name1 = (gss_union_name_t)name1;
840Sstevel@tonic-gate 	union_name2 = (gss_union_name_t)name2;
850Sstevel@tonic-gate 	/*
860Sstevel@tonic-gate 	 * Try our hardest to make union_name1 be the mechanism-specific
870Sstevel@tonic-gate 	 * name.  (Of course we can't if both names aren't
880Sstevel@tonic-gate 	 * mechanism-specific.)
890Sstevel@tonic-gate 	 */
900Sstevel@tonic-gate 	if (union_name1->mech_type == 0) {
910Sstevel@tonic-gate 		union_name1 = (gss_union_name_t)name2;
920Sstevel@tonic-gate 		union_name2 = (gss_union_name_t)name1;
930Sstevel@tonic-gate 	}
940Sstevel@tonic-gate 	/*
950Sstevel@tonic-gate 	 * If union_name1 is mechanism specific, then fetch its mechanism
960Sstevel@tonic-gate 	 * information.
970Sstevel@tonic-gate 	 */
980Sstevel@tonic-gate 	if (union_name1->mech_type) {
990Sstevel@tonic-gate 		mech = __gss_get_mechanism(union_name1->mech_type);
1000Sstevel@tonic-gate 		if (!mech)
1010Sstevel@tonic-gate 			return (GSS_S_BAD_MECH);
1020Sstevel@tonic-gate 		if (!mech->gss_compare_name)
1030Sstevel@tonic-gate 			return (GSS_S_UNAVAILABLE);
1040Sstevel@tonic-gate 	}
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	*name_equal = 0;	/* Default to *not* equal.... */
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	/*
1090Sstevel@tonic-gate 	 * First case... both names are mechanism-specific
1100Sstevel@tonic-gate 	 */
1110Sstevel@tonic-gate 	if (union_name1->mech_type && union_name2->mech_type) {
1120Sstevel@tonic-gate 		if (!g_OID_equal(union_name1->mech_type,
1130Sstevel@tonic-gate 					union_name2->mech_type))
1140Sstevel@tonic-gate 			return (GSS_S_COMPLETE);
1150Sstevel@tonic-gate 		if ((union_name1->mech_name == 0) ||
1160Sstevel@tonic-gate 			(union_name2->mech_name == 0))
1170Sstevel@tonic-gate 			/* should never happen */
1180Sstevel@tonic-gate 			return (GSS_S_BAD_NAME);
119*13132SGlenn.Barry@oracle.com 		if (!mech)
120*13132SGlenn.Barry@oracle.com 			return (GSS_S_BAD_MECH);
121*13132SGlenn.Barry@oracle.com 		if (!mech->gss_compare_name)
122*13132SGlenn.Barry@oracle.com 			return (GSS_S_UNAVAILABLE);
123*13132SGlenn.Barry@oracle.com 		major_status = mech->gss_compare_name(mech->context,
124*13132SGlenn.Barry@oracle.com 						    minor_status,
125*13132SGlenn.Barry@oracle.com 						    union_name1->mech_name,
126*13132SGlenn.Barry@oracle.com 						    union_name2->mech_name,
127*13132SGlenn.Barry@oracle.com 						    name_equal);
128*13132SGlenn.Barry@oracle.com 		if (major_status != GSS_S_COMPLETE)
129*13132SGlenn.Barry@oracle.com 			map_error(minor_status, mech);
130*13132SGlenn.Barry@oracle.com 		return major_status;
1310Sstevel@tonic-gate 	}
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 	/*
1340Sstevel@tonic-gate 	 * Second case... both names are NOT mechanism specific.
1350Sstevel@tonic-gate 	 *
1360Sstevel@tonic-gate 	 * All we do here is make sure the two name_types are equal and then
1370Sstevel@tonic-gate 	 * that the external_names are equal. Note the we do not take care
1380Sstevel@tonic-gate 	 * of the case where two different external names map to the same
1390Sstevel@tonic-gate 	 * internal name. We cannot determine this, since we as yet do not
1400Sstevel@tonic-gate 	 * know what mechanism to use for calling the underlying
1410Sstevel@tonic-gate 	 * gss_import_name().
1420Sstevel@tonic-gate 	 */
1430Sstevel@tonic-gate 	if (!union_name1->mech_type && !union_name2->mech_type) {
1440Sstevel@tonic-gate 		/*
1450Sstevel@tonic-gate 		 * Second case, first sub-case... one name has null
1460Sstevel@tonic-gate 		 * name_type, the other doesn't.
1470Sstevel@tonic-gate 		 *
1480Sstevel@tonic-gate 		 * Not knowing a mech_type we can't import the name with
1490Sstevel@tonic-gate 		 * null name_type so we can't compare.
1500Sstevel@tonic-gate 		 */
1510Sstevel@tonic-gate 		if ((union_name1->name_type == GSS_C_NULL_OID &&
1520Sstevel@tonic-gate 		    union_name2->name_type != GSS_C_NULL_OID) ||
1530Sstevel@tonic-gate 		    (union_name1->name_type != GSS_C_NULL_OID &&
1540Sstevel@tonic-gate 		    union_name2->name_type == GSS_C_NULL_OID))
1550Sstevel@tonic-gate 			return (GSS_S_COMPLETE);
1560Sstevel@tonic-gate 		/*
1570Sstevel@tonic-gate 		 * Second case, second sub-case... both names have
1580Sstevel@tonic-gate 		 * name_types, but they are different.
1590Sstevel@tonic-gate 		 */
1600Sstevel@tonic-gate 		if ((union_name1->name_type != GSS_C_NULL_OID &&
1610Sstevel@tonic-gate 		    union_name2->name_type != GSS_C_NULL_OID) &&
1620Sstevel@tonic-gate 		    !g_OID_equal(union_name1->name_type,
1630Sstevel@tonic-gate 					union_name2->name_type))
1640Sstevel@tonic-gate 			return (GSS_S_COMPLETE);
1650Sstevel@tonic-gate 		/*
1660Sstevel@tonic-gate 		 * Second case, third sub-case... both names have equal
1670Sstevel@tonic-gate 		 * name_types (and both have no mech_types) so we just
1680Sstevel@tonic-gate 		 * compare the external_names.
1690Sstevel@tonic-gate 		 */
1700Sstevel@tonic-gate 		if ((union_name1->external_name->length !=
1710Sstevel@tonic-gate 			union_name2->external_name->length) ||
1720Sstevel@tonic-gate 			(memcmp(union_name1->external_name->value,
1730Sstevel@tonic-gate 				union_name2->external_name->value,
1740Sstevel@tonic-gate 				union_name1->external_name->length) != 0))
1750Sstevel@tonic-gate 			return (GSS_S_COMPLETE);
1760Sstevel@tonic-gate 		*name_equal = 1;
1770Sstevel@tonic-gate 		return (GSS_S_COMPLETE);
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	/*
1810Sstevel@tonic-gate 	 * Final case... one name is mechanism specific, the other isn't.
1820Sstevel@tonic-gate 	 *
1830Sstevel@tonic-gate 	 * We attempt to convert the general name to the mechanism type of
1840Sstevel@tonic-gate 	 * the mechanism-specific name, and then do the compare.  If we
1850Sstevel@tonic-gate 	 * can't import the general name, then we return that the name is
1860Sstevel@tonic-gate 	 * _NOT_ equal.
1870Sstevel@tonic-gate 	 */
1880Sstevel@tonic-gate 	if (union_name2->mech_type) {
1890Sstevel@tonic-gate 		/* We make union_name1 the mechanism specific name. */
1900Sstevel@tonic-gate 		union_name1 = (gss_union_name_t)name2;
1910Sstevel@tonic-gate 		union_name2 = (gss_union_name_t)name1;
1920Sstevel@tonic-gate 	}
1930Sstevel@tonic-gate 	major_status = __gss_import_internal_name(minor_status,
1940Sstevel@tonic-gate 							union_name1->mech_type,
1950Sstevel@tonic-gate 							union_name2,
1960Sstevel@tonic-gate 							&internal_name);
1970Sstevel@tonic-gate 	if (major_status != GSS_S_COMPLETE)
1980Sstevel@tonic-gate 		return (GSS_S_COMPLETE); /* return complete, but not equal */
1990Sstevel@tonic-gate 
200*13132SGlenn.Barry@oracle.com 	if (!mech)
201*13132SGlenn.Barry@oracle.com 		return (GSS_S_BAD_MECH);
202*13132SGlenn.Barry@oracle.com 	if (!mech->gss_compare_name)
203*13132SGlenn.Barry@oracle.com 		return (GSS_S_UNAVAILABLE);
2040Sstevel@tonic-gate 	major_status = mech->gss_compare_name(mech->context, minor_status,
2050Sstevel@tonic-gate 							union_name1->mech_name,
2060Sstevel@tonic-gate 							internal_name,
2070Sstevel@tonic-gate 							name_equal);
208*13132SGlenn.Barry@oracle.com 	if (major_status != GSS_S_COMPLETE)
209*13132SGlenn.Barry@oracle.com 		map_error(minor_status, mech);
2100Sstevel@tonic-gate 	(void) __gss_release_internal_name(&temp_minor, union_name1->mech_type,
2110Sstevel@tonic-gate 					&internal_name);
2120Sstevel@tonic-gate 	return (major_status);
2130Sstevel@tonic-gate }
214