1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* #pragma ident "@(#)g_dup_name.c 1.14 04/02/23 SMI" */ 7 8 /* 9 * routine gss_duplicate_name 10 * 11 * This routine does not rely on mechanism implementation of this 12 * name, but instead uses mechanism specific gss_import_name routine. 13 */ 14 15 #include <mglueP.h> 16 #ifdef HAVE_STDLIB_H 17 #include <stdlib.h> 18 #endif 19 #include <string.h> 20 #include <errno.h> 21 22 static OM_uint32 23 val_dup_name_args( 24 OM_uint32 *minor_status, 25 const gss_name_t src_name, 26 gss_name_t *dest_name) 27 { 28 29 /* Initialize outputs. */ 30 31 if (minor_status != NULL) 32 *minor_status = 0; 33 34 if (dest_name != NULL) 35 *dest_name = GSS_C_NO_NAME; 36 37 /* Validate arguments. */ 38 39 if (minor_status == NULL) 40 return (GSS_S_CALL_INACCESSIBLE_WRITE); 41 42 /* if output_name is NULL, simply return */ 43 if (dest_name == NULL) 44 return (GSS_S_CALL_INACCESSIBLE_WRITE); 45 46 if (src_name == GSS_C_NO_NAME) 47 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME); 48 49 return (GSS_S_COMPLETE); 50 } 51 52 53 OM_uint32 KRB5_CALLCONV 54 gss_duplicate_name(OM_uint32 *minor_status, const gss_name_t src_name, 55 gss_name_t *dest_name) 56 { 57 gss_union_name_t src_union, dest_union; 58 OM_uint32 major_status = GSS_S_FAILURE; 59 60 major_status = val_dup_name_args(minor_status, src_name, dest_name); 61 if (major_status != GSS_S_COMPLETE) 62 return (major_status); 63 64 src_union = (gss_union_name_t)src_name; 65 66 /* 67 * First create the union name struct that will hold the external 68 * name and the name type. 69 */ 70 dest_union = (gss_union_name_t)malloc(sizeof (gss_union_name_desc)); 71 if (!dest_union) 72 goto allocation_failure; 73 74 dest_union->loopback = 0; 75 dest_union->mech_type = 0; 76 dest_union->mech_name = 0; 77 dest_union->name_type = 0; 78 dest_union->external_name = 0; 79 80 /* Now copy the external representation. */ 81 if (gssint_create_copy_buffer(src_union->external_name, 82 &dest_union->external_name, 0)) 83 goto allocation_failure; 84 85 if (src_union->name_type != GSS_C_NULL_OID) { 86 major_status = generic_gss_copy_oid(minor_status, 87 src_union->name_type, 88 &dest_union->name_type); 89 if (major_status != GSS_S_COMPLETE) { 90 map_errcode(minor_status); 91 goto allocation_failure; 92 } 93 } 94 95 /* 96 * See if source name is mechanim specific, if so then need to import it 97 */ 98 if (src_union->mech_type) { 99 major_status = generic_gss_copy_oid(minor_status, 100 src_union->mech_type, 101 &dest_union->mech_type); 102 if (major_status != GSS_S_COMPLETE) { 103 map_errcode(minor_status); 104 goto allocation_failure; 105 } 106 107 major_status = gssint_import_internal_name(minor_status, 108 src_union->mech_type, 109 src_union, 110 &dest_union->mech_name); 111 if (major_status != GSS_S_COMPLETE) 112 goto allocation_failure; 113 } 114 115 116 dest_union->loopback = dest_union; 117 *dest_name = (gss_name_t)dest_union; 118 return (GSS_S_COMPLETE); 119 120 allocation_failure: 121 if (dest_union) { 122 if (dest_union->external_name) { 123 if (dest_union->external_name->value) 124 free(dest_union->external_name->value); 125 free(dest_union->external_name); 126 } 127 if (dest_union->name_type) 128 (void) generic_gss_release_oid(minor_status, 129 &dest_union->name_type); 130 if (dest_union->mech_name) 131 (void) gssint_release_internal_name(minor_status, 132 dest_union->mech_type, 133 &dest_union->mech_name); 134 if (dest_union->mech_type) 135 (void) generic_gss_release_oid(minor_status, 136 &dest_union->mech_type); 137 free(dest_union); 138 } 139 return (major_status); 140 } /* gss_duplicate_name */ 141