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  *  glue routine for gss_inquire_context
27  */
28 
29 #include <mechglueP.h>
30 #include "gssapiP_generic.h"
31 
32 #define	MAX_MECH_OID_PAIRS 32
33 
34 /* Last argument new for V2 */
35 OM_uint32
gss_inquire_names_for_mech(minor_status,mechanism,name_types)36 gss_inquire_names_for_mech(minor_status, mechanism, name_types)
37 
38 OM_uint32 *		minor_status;
39 const gss_OID 		mechanism;
40 gss_OID_set *		name_types;
41 
42 {
43 	OM_uint32		status;
44 	gss_mechanism		mech;
45 
46 	/* Initialize outputs. */
47 
48 	if (minor_status != NULL)
49 		*minor_status = 0;
50 
51 	if (name_types != NULL)
52 		*name_types = GSS_C_NO_OID_SET;
53 
54 	/* Validate arguments. */
55 
56 	if (minor_status == NULL)
57 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
58 
59 	if (name_types == NULL)
60 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
61 
62 	/*
63 	 * select the approprate underlying mechanism routine and
64 	 * call it.
65 	 */
66 
67 	mech = __gss_get_mechanism(mechanism);
68 
69 	if (mech) {
70 
71 		if (mech->gss_inquire_names_for_mech) {
72 			status = mech->gss_inquire_names_for_mech(
73 					mech->context,
74 					minor_status,
75 					mechanism,
76 					name_types);
77 			if (status != GSS_S_COMPLETE)
78 				map_error(minor_status, mech);
79 		} else
80 			status = GSS_S_UNAVAILABLE;
81 
82 		return (status);
83 	}
84 
85 	return (GSS_S_BAD_MECH);
86 }
87 
val_inq_mechs4name_args(OM_uint32 * minor_status,const gss_name_t input_name,gss_OID_set * mech_set)88 static OM_uint32 val_inq_mechs4name_args(
89 	OM_uint32 *minor_status,
90 	const gss_name_t input_name,
91 	gss_OID_set *mech_set)
92 {
93 
94 	/* Initialize outputs. */
95 	if (minor_status != NULL)
96 		*minor_status = 0;
97 
98 	if (mech_set != NULL)
99 		*mech_set = GSS_C_NO_OID_SET;
100 
101 	/* Validate arguments. */
102 
103 	if (minor_status == NULL)
104 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
105 
106 	if (input_name == GSS_C_NO_NAME)
107 		return (GSS_S_BAD_NAME);
108 
109 	return (GSS_S_COMPLETE);
110 }
111 
112 OM_uint32
gss_inquire_mechs_for_name(minor_status,input_name,mech_set)113 gss_inquire_mechs_for_name(minor_status, input_name, mech_set)
114 
115 OM_uint32 *		minor_status;
116 const gss_name_t	input_name;
117 gss_OID_set *		mech_set;
118 
119 {
120 	OM_uint32		status;
121 	static char		*mech_list[MAX_MECH_OID_PAIRS+1];
122 	gss_OID_set		mech_name_types;
123 	int			present;
124 	char 			*mechanism;
125 	gss_OID 		mechOid;
126 	gss_OID 		name_type;
127 	gss_buffer_desc		name_buffer;
128 	int			i;
129 
130 	status = val_inq_mechs4name_args(minor_status, input_name, mech_set);
131 	if (status != GSS_S_COMPLETE)
132 		return (status);
133 
134 	status = gss_create_empty_oid_set(minor_status, mech_set);
135 	if (status != GSS_S_COMPLETE)
136 		return (status);
137 	*mech_list = NULL;
138 	status = __gss_get_mechanisms(mech_list, MAX_MECH_OID_PAIRS+1);
139 	if (status != GSS_S_COMPLETE)
140 		return (status);
141 	for (i = 0; i < MAX_MECH_OID_PAIRS && mech_list[i] != NULL; i++) {
142 		mechanism = mech_list[i];
143 		if (__gss_mech_to_oid(mechanism, &mechOid) == GSS_S_COMPLETE) {
144 			status = gss_inquire_names_for_mech(
145 					minor_status,
146 					mechOid,
147 					&mech_name_types);
148 			if (status == GSS_S_COMPLETE) {
149 				status = gss_display_name(minor_status,
150 							input_name,
151 							&name_buffer,
152 							&name_type);
153 
154 				(void) gss_release_buffer(NULL, &name_buffer);
155 
156 				if (status == GSS_S_COMPLETE && name_type) {
157 					status = gss_test_oid_set_member(
158 							minor_status,
159 							name_type,
160 							mech_name_types,
161 							&present);
162 					if (status == GSS_S_COMPLETE &&
163 						present) {
164 						status = gss_add_oid_set_member(
165 							minor_status,
166 							mechOid,
167 							mech_set);
168 						if (status != GSS_S_COMPLETE) {
169 						(void) gss_release_oid_set(
170 							    minor_status,
171 							    &mech_name_types);
172 						(void) gss_release_oid_set(
173 							    minor_status,
174 							    mech_set);
175 							return (status);
176 						}
177 					}
178 				}
179 				(void) gss_release_oid_set(
180 					minor_status,
181 					&mech_name_types);
182 			}
183 		} else {
184 			(void) gss_release_oid_set(
185 				minor_status,
186 				mech_set);
187 			return (GSS_S_FAILURE);
188 		}
189 	}
190 	return (GSS_S_COMPLETE);
191 }
192