1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* #pragma ident "@(#)g_canon_name.c 1.15 04/02/23 SMI" */ 7 8 /* 9 * routine gss_canonicalize_name 10 * 11 * This routine is used to produce a mechanism specific 12 * representation of name that has been previously 13 * imported with gss_import_name. The routine uses the mechanism 14 * specific implementation of gss_import_name to implement this 15 * function. 16 * 17 * We allow a NULL output_name, in which case we modify the 18 * input_name to include the mechanism specific name. 19 */ 20 21 #include <mglueP.h> 22 #ifdef HAVE_STDLIB_H 23 #include <stdlib.h> 24 #endif 25 #include <string.h> 26 #include <errno.h> 27 28 static OM_uint32 29 val_canon_name_args( 30 OM_uint32 *minor_status, 31 const gss_name_t input_name, 32 const gss_OID mech_type, 33 gss_name_t *output_name) 34 { 35 36 /* Initialize outputs. */ 37 38 if (minor_status != NULL) 39 *minor_status = 0; 40 41 if (output_name != NULL) 42 *output_name = GSS_C_NO_NAME; 43 44 /* Validate arguments. */ 45 46 if (minor_status == NULL) 47 return (GSS_S_CALL_INACCESSIBLE_WRITE); 48 49 if (input_name == GSS_C_NO_NAME || mech_type == GSS_C_NULL_OID) 50 return (GSS_S_CALL_INACCESSIBLE_READ); 51 52 return (GSS_S_COMPLETE); 53 } 54 55 56 OM_uint32 KRB5_CALLCONV 57 gss_canonicalize_name(OM_uint32 *minor_status, const gss_name_t input_name, 58 const gss_OID mech_type, gss_name_t *output_name) 59 { 60 gss_union_name_t in_union, out_union = NULL, dest_union = NULL; 61 OM_uint32 major_status = GSS_S_FAILURE, tmpmin; 62 gss_OID selected_mech; 63 64 major_status = val_canon_name_args(minor_status, 65 input_name, 66 mech_type, 67 output_name); 68 if (major_status != GSS_S_COMPLETE) 69 return (major_status); 70 71 major_status = gssint_select_mech_type(minor_status, mech_type, 72 &selected_mech); 73 if (major_status != GSS_S_COMPLETE) 74 return (major_status); 75 76 /* Initial value needed below. */ 77 major_status = GSS_S_FAILURE; 78 79 in_union = (gss_union_name_t)input_name; 80 /* 81 * If the caller wants to reuse the name, and the name has already 82 * been converted, then there is nothing for us to do. 83 */ 84 if (!output_name && in_union->mech_type && 85 g_OID_equal(in_union->mech_type, selected_mech)) 86 return (GSS_S_COMPLETE); 87 88 /* ok, then we need to do something - start by creating data struct */ 89 if (output_name) { 90 out_union = 91 (gss_union_name_t)malloc(sizeof (gss_union_name_desc)); 92 if (!out_union) 93 goto allocation_failure; 94 95 out_union->mech_type = 0; 96 out_union->mech_name = 0; 97 out_union->name_type = 0; 98 out_union->external_name = 0; 99 out_union->loopback = out_union; 100 101 /* Allocate the buffer for the user specified representation */ 102 if (gssint_create_copy_buffer(in_union->external_name, 103 &out_union->external_name, 1)) 104 goto allocation_failure; 105 106 if (in_union->name_type != GSS_C_NULL_OID) { 107 major_status = generic_gss_copy_oid(minor_status, 108 in_union->name_type, 109 &out_union->name_type); 110 if (major_status) { 111 map_errcode(minor_status); 112 goto allocation_failure; 113 } 114 } 115 116 } 117 118 /* 119 * might need to delete any old mechanism names if we are 120 * reusing the buffer. 121 */ 122 if (!output_name) { 123 if (in_union->mech_type) { 124 (void) gssint_release_internal_name(minor_status, 125 in_union->mech_type, 126 &in_union->mech_name); 127 (void) gss_release_oid(minor_status, 128 &in_union->mech_type); 129 in_union->mech_type = 0; 130 } 131 dest_union = in_union; 132 } else 133 dest_union = out_union; 134 135 /* now let's create the new mech name */ 136 if ((major_status = generic_gss_copy_oid(minor_status, selected_mech, 137 &dest_union->mech_type))) { 138 map_errcode(minor_status); 139 goto allocation_failure; 140 } 141 142 if ((major_status = 143 gssint_import_internal_name(minor_status, selected_mech, 144 in_union, 145 &dest_union->mech_name))) 146 goto allocation_failure; 147 148 if (output_name) 149 *output_name = (gss_name_t)dest_union; 150 151 return (GSS_S_COMPLETE); 152 153 allocation_failure: 154 if (out_union) { 155 /* Release the partly constructed out_union. */ 156 gss_name_t name = (gss_name_t)out_union; 157 (void) gss_release_name(&tmpmin, &name); 158 } else if (!output_name) { 159 /* Release only the mech name fields in in_union. */ 160 if (in_union->mech_name) { 161 (void) gssint_release_internal_name(&tmpmin, 162 dest_union->mech_type, 163 &dest_union->mech_name); 164 } 165 if (in_union->mech_type) 166 (void) gss_release_oid(&tmpmin, &dest_union->mech_type); 167 } 168 169 return (major_status); 170 } /********** gss_canonicalize_name ********/ 171