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