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
val_dup_name_args(OM_uint32 * minor_status,const gss_name_t src_name,gss_name_t * dest_name)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
gss_duplicate_name(OM_uint32 * minor_status,const gss_name_t src_name,gss_name_t * dest_name)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