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