1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * routine gss_canonicalize_name 27 * 28 * This routine is used to produce a mechanism specific 29 * representation of name that has been previously 30 * imported with gss_import_name. The routine uses the mechanism 31 * specific implementation of gss_import_name to implement this 32 * function. 33 * 34 * We allow a NULL output_name, in which case we modify the 35 * input_name to include the mechanism specific name. 36 */ 37 38 #include <mechglueP.h> 39 #include "gssapiP_generic.h" 40 #ifdef HAVE_STDLIB_H 41 #include <stdlib.h> 42 #endif 43 #include <string.h> 44 #include <errno.h> 45 #include <syslog.h> 46 47 static OM_uint32 val_canon_name_args( 48 OM_uint32 *minor_status, 49 const gss_name_t input_name, 50 const gss_OID mech_type, 51 gss_name_t *output_name) 52 { 53 54 /* Initialize outputs. */ 55 56 if (minor_status != NULL) 57 *minor_status = 0; 58 59 if (output_name != NULL) 60 *output_name = GSS_C_NO_NAME; 61 62 /* Validate arguments. */ 63 64 if (minor_status == NULL) 65 return (GSS_S_CALL_INACCESSIBLE_WRITE); 66 67 if (input_name == GSS_C_NO_NAME || mech_type == GSS_C_NULL_OID) 68 return (GSS_S_CALL_INACCESSIBLE_READ); 69 70 return (GSS_S_COMPLETE); 71 } 72 73 OM_uint32 74 gss_canonicalize_name(minor_status, 75 input_name, 76 mech_type, 77 output_name) 78 OM_uint32 *minor_status; 79 const gss_name_t input_name; 80 const gss_OID mech_type; 81 gss_name_t *output_name; 82 { 83 gss_union_name_t in_union, out_union = NULL, dest_union = NULL; 84 OM_uint32 major_status = GSS_S_FAILURE; 85 /* Solaris Kerberos - need to preserve more important minor_status */ 86 OM_uint32 tmp_status = 0; 87 88 major_status = val_canon_name_args(minor_status, 89 input_name, 90 mech_type, 91 output_name); 92 if (major_status != GSS_S_COMPLETE) 93 return (major_status); 94 95 /* Initial value needed below. */ 96 major_status = GSS_S_FAILURE; 97 98 in_union = (gss_union_name_t)input_name; 99 /* 100 * If the caller wants to reuse the name, and the name has already 101 * been converted, then there is nothing for us to do. 102 */ 103 if (!output_name && in_union->mech_type && 104 g_OID_equal(in_union->mech_type, mech_type)) 105 return (GSS_S_COMPLETE); 106 107 /* ok, then we need to do something - start by creating data struct */ 108 if (output_name) { 109 out_union = 110 (gss_union_name_t)malloc(sizeof (gss_union_name_desc)); 111 if (!out_union) 112 goto allocation_failure; 113 114 out_union->mech_type = 0; 115 out_union->mech_name = 0; 116 out_union->name_type = 0; 117 out_union->external_name = 0; 118 119 /* Allocate the buffer for the user specified representation */ 120 if (gssint_create_copy_buffer(in_union->external_name, 121 &out_union->external_name, 1)) 122 goto allocation_failure; 123 124 if (in_union->name_type != GSS_C_NULL_OID) { 125 major_status = generic_gss_copy_oid(minor_status, 126 in_union->name_type, 127 &out_union->name_type); 128 if (major_status) { 129 map_errcode(minor_status); 130 goto allocation_failure; 131 } 132 } 133 } 134 135 /* 136 * might need to delete any old mechanism names if we are 137 * reusing the buffer. 138 */ 139 if (!output_name) { 140 if (in_union->mech_type) { 141 (void) __gss_release_internal_name(minor_status, 142 in_union->mech_type, 143 &in_union->mech_name); 144 (void) gss_release_oid(minor_status, 145 &in_union->mech_type); 146 in_union->mech_type = 0; 147 } 148 dest_union = in_union; 149 } else 150 dest_union = out_union; 151 152 /* now let's create the new mech name */ 153 if (major_status = generic_gss_copy_oid(minor_status, mech_type, 154 &dest_union->mech_type)) { 155 map_errcode(minor_status); 156 goto allocation_failure; 157 } 158 159 if (major_status = 160 __gss_import_internal_name(minor_status, mech_type, 161 dest_union, 162 &dest_union->mech_name)) 163 goto allocation_failure; 164 165 if (output_name) 166 *output_name = (gss_name_t)dest_union; 167 168 return (GSS_S_COMPLETE); 169 170 /* Solaris Kerberos - note some fails are not "allocation fails". Sigh. */ 171 allocation_failure: 172 /* do not delete the src name external name format */ 173 if (output_name) { 174 if (out_union->external_name) { 175 if (out_union->external_name->value) 176 free(out_union->external_name->value); 177 free(out_union->external_name); 178 } 179 if (out_union->name_type) 180 (void) gss_release_oid(&tmp_status, 181 &out_union->name_type); 182 183 dest_union = out_union; 184 } else 185 dest_union = in_union; 186 187 /* 188 * delete the partially created mech specific name 189 * applies for both src and dest which ever is being used for output 190 */ 191 192 if (dest_union->mech_name) { 193 (void) __gss_release_internal_name(&tmp_status, 194 dest_union->mech_type, 195 &dest_union->mech_name); 196 } 197 198 if (dest_union->mech_type) 199 (void) gss_release_oid(&tmp_status, &dest_union->mech_type); 200 201 202 if (output_name) 203 free(out_union); 204 205 return (major_status); 206 } /********** gss_canonicalize_name ********/ 207