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_duplicate_name 27 * 28 * This routine does not rely on mechanism implementation of this 29 * name, but instead uses mechanism specific gss_import_name routine. 30 */ 31 32 #include <mechglueP.h> 33 #include "gssapiP_generic.h" 34 #ifdef HAVE_STDLIB_H 35 #include <stdlib.h> 36 #endif 37 #include <string.h> 38 #include <errno.h> 39 40 static OM_uint32 41 val_dup_name_args( 42 OM_uint32 *minor_status, 43 const gss_name_t src_name, 44 gss_name_t *dest_name) 45 { 46 47 /* Initialize outputs. */ 48 49 if (minor_status != NULL) 50 *minor_status = 0; 51 52 if (dest_name != NULL) 53 *dest_name = GSS_C_NO_NAME; 54 55 /* Validate arguments. */ 56 57 if (minor_status == NULL) 58 return (GSS_S_CALL_INACCESSIBLE_WRITE); 59 60 /* if output_name is NULL, simply return */ 61 if (dest_name == NULL) 62 return (GSS_S_CALL_INACCESSIBLE_WRITE); 63 64 if (src_name == GSS_C_NO_NAME) 65 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME); 66 67 return (GSS_S_COMPLETE); 68 } 69 70 OM_uint32 71 gss_duplicate_name(OM_uint32 *minor_status, const gss_name_t src_name, 72 gss_name_t *dest_name) 73 { 74 gss_union_name_t src_union, dest_union; 75 OM_uint32 major_status = GSS_S_FAILURE; 76 77 major_status = val_dup_name_args(minor_status, src_name, dest_name); 78 if (major_status != GSS_S_COMPLETE) 79 return (major_status); 80 81 major_status = GSS_S_FAILURE; 82 83 src_union = (gss_union_name_t)src_name; 84 85 /* 86 * First create the union name struct that will hold the external 87 * name and the name type. 88 */ 89 dest_union = (gss_union_name_t)malloc(sizeof (gss_union_name_desc)); 90 if (!dest_union) 91 goto allocation_failure; 92 93 dest_union->mech_type = 0; 94 dest_union->mech_name = 0; 95 dest_union->name_type = 0; 96 dest_union->external_name = 0; 97 98 /* Now copy the external representaion */ 99 if (gssint_create_copy_buffer(src_union->external_name, 100 &dest_union->external_name, 0)) 101 goto allocation_failure; 102 103 if (src_union->name_type != GSS_C_NULL_OID) { 104 major_status = generic_gss_copy_oid(minor_status, 105 src_union->name_type, &dest_union->name_type); 106 if (major_status != GSS_S_COMPLETE) { 107 map_errcode(minor_status); 108 goto allocation_failure; 109 } 110 } 111 112 /* 113 * See if source name is mechanim specific, if so then need to import it 114 */ 115 if (src_union->mech_type) { 116 major_status = generic_gss_copy_oid(minor_status, 117 src_union->mech_type, &dest_union->mech_type); 118 if (major_status != GSS_S_COMPLETE) { 119 map_errcode(minor_status); 120 goto allocation_failure; 121 } 122 123 major_status = __gss_import_internal_name(minor_status, 124 dest_union->mech_type, dest_union, &dest_union->mech_name); 125 if (major_status != GSS_S_COMPLETE) 126 goto allocation_failure; 127 } 128 129 130 *dest_name = (gss_name_t)dest_union; 131 return (GSS_S_COMPLETE); 132 133 allocation_failure: 134 if (dest_union) { 135 if (dest_union->external_name) { 136 free(dest_union->external_name->value); 137 free(dest_union->external_name); 138 } 139 if (dest_union->name_type) { 140 (void) generic_gss_release_oid(minor_status, 141 &dest_union->name_type); 142 } 143 if (dest_union->mech_name) { 144 (void) __gss_release_internal_name(minor_status, 145 dest_union->mech_type, &dest_union->mech_name); 146 } 147 if (dest_union->mech_type) { 148 (void) generic_gss_release_oid(minor_status, 149 &dest_union->mech_type); 150 } 151 free(dest_union); 152 } 153 return (major_status); 154 } /* gss_duplicate_name */ 155