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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * routine gss_canonicalize_name 28 * 29 * This routine is used to produce a mechanism specific 30 * representation of name that has been previously 31 * imported with gss_import_name. The routine uses the mechanism 32 * specific implementation of gss_import_name to implement this 33 * function. 34 * 35 * We allow a NULL output_name, in which case we modify the 36 * input_name to include the mechanism specific name. 37 */ 38 39 #include <mechglueP.h> 40 #ifdef HAVE_STDLIB_H 41 #include <stdlib.h> 42 #endif 43 #include <string.h> 44 #include <errno.h> 45 46 static OM_uint32 val_canon_name_args( 47 OM_uint32 *minor_status, 48 const gss_name_t input_name, 49 const gss_OID mech_type, 50 gss_name_t *output_name) 51 { 52 53 /* Initialize outputs. */ 54 55 if (minor_status != NULL) 56 *minor_status = 0; 57 58 if (output_name != NULL) 59 *output_name = GSS_C_NO_NAME; 60 61 /* Validate arguments. */ 62 63 if (minor_status == NULL) 64 return (GSS_S_CALL_INACCESSIBLE_WRITE); 65 66 if (input_name == GSS_C_NO_NAME || mech_type == GSS_C_NULL_OID) 67 return (GSS_S_CALL_INACCESSIBLE_READ); 68 69 return (GSS_S_COMPLETE); 70 } 71 72 OM_uint32 73 gss_canonicalize_name(minor_status, 74 input_name, 75 mech_type, 76 output_name) 77 OM_uint32 *minor_status; 78 const gss_name_t input_name; 79 const gss_OID mech_type; 80 gss_name_t *output_name; 81 { 82 gss_union_name_t in_union, out_union = NULL, dest_union = NULL; 83 OM_uint32 major_status = GSS_S_FAILURE; 84 85 major_status = val_canon_name_args(minor_status, 86 input_name, 87 mech_type, 88 output_name); 89 if (major_status != GSS_S_COMPLETE) 90 return (major_status); 91 92 /* Initial value needed below. */ 93 major_status = GSS_S_FAILURE; 94 95 in_union = (gss_union_name_t)input_name; 96 /* 97 * If the caller wants to reuse the name, and the name has already 98 * been converted, then there is nothing for us to do. 99 */ 100 if (!output_name && in_union->mech_type && 101 g_OID_equal(in_union->mech_type, mech_type)) 102 return (GSS_S_COMPLETE); 103 104 /* ok, then we need to do something - start by creating data struct */ 105 if (output_name) { 106 out_union = 107 (gss_union_name_t)malloc(sizeof (gss_union_name_desc)); 108 if (!out_union) 109 goto allocation_failure; 110 111 out_union->mech_type = 0; 112 out_union->mech_name = 0; 113 out_union->name_type = 0; 114 out_union->external_name = 0; 115 116 /* Allocate the buffer for the user specified representation */ 117 if (gssint_create_copy_buffer(in_union->external_name, 118 &out_union->external_name, 1)) 119 goto allocation_failure; 120 121 if (in_union->name_type != GSS_C_NULL_OID) { 122 if ((major_status = generic_gss_copy_oid(minor_status, 123 in_union->name_type, &out_union->name_type))) 124 goto allocation_failure; 125 } 126 127 } 128 129 /* 130 * might need to delete any old mechanism names if we are 131 * reusing the buffer. 132 */ 133 if (!output_name) { 134 if (in_union->mech_type) { 135 (void) __gss_release_internal_name(minor_status, 136 in_union->mech_type, 137 &in_union->mech_name); 138 (void) gss_release_oid(minor_status, 139 &in_union->mech_type); 140 in_union->mech_type = 0; 141 } 142 dest_union = in_union; 143 } else 144 dest_union = out_union; 145 146 /* now let's create the new mech name */ 147 if (major_status = generic_gss_copy_oid(minor_status, mech_type, 148 &dest_union->mech_type)) 149 goto allocation_failure; 150 151 if (major_status = 152 __gss_import_internal_name(minor_status, mech_type, 153 dest_union, 154 &dest_union->mech_name)) 155 goto allocation_failure; 156 157 if (output_name) 158 *output_name = (gss_name_t)dest_union; 159 160 return (GSS_S_COMPLETE); 161 162 allocation_failure: 163 /* do not delete the src name external name format */ 164 if (output_name) { 165 if (out_union->external_name) { 166 if (out_union->external_name->value) 167 free(out_union->external_name->value); 168 free(out_union->external_name); 169 } 170 if (out_union->name_type) 171 (void) gss_release_oid(minor_status, 172 &out_union->name_type); 173 174 dest_union = out_union; 175 } else 176 dest_union = in_union; 177 178 /* 179 * delete the partially created mech specific name 180 * applies for both src and dest which ever is being used for output 181 */ 182 183 if (dest_union->mech_name) { 184 (void) __gss_release_internal_name(minor_status, 185 dest_union->mech_type, 186 &dest_union->mech_name); 187 } 188 189 if (dest_union->mech_type) 190 (void) gss_release_oid(minor_status, &dest_union->mech_type); 191 192 193 if (output_name) 194 free(out_union); 195 196 return (major_status); 197 } /********** gss_canonicalize_name ********/ 198