Line data Source code
1 : /*
2 : * Copyright (c) 2004, PADL Software Pty Ltd.
3 : * All rights reserved.
4 : *
5 : * Redistribution and use in source and binary forms, with or without
6 : * modification, are permitted provided that the following conditions
7 : * are met:
8 : *
9 : * 1. Redistributions of source code must retain the above copyright
10 : * notice, this list of conditions and the following disclaimer.
11 : *
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * 3. Neither the name of PADL Software nor the names of its contributors
17 : * may be used to endorse or promote products derived from this software
18 : * without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 : * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 : * SUCH DAMAGE.
31 : */
32 :
33 : /*
34 : * glue routine for _gsskrb5_inquire_sec_context_by_oid
35 : */
36 :
37 : #include "gsskrb5_locl.h"
38 :
39 : static OM_uint32
40 82300 : get_bool(OM_uint32 *minor_status,
41 : const gss_buffer_t value,
42 : int *flag)
43 : {
44 84700 : if (value->value == NULL || value->length != 1) {
45 0 : *minor_status = EINVAL;
46 0 : return GSS_S_FAILURE;
47 : }
48 84700 : *flag = *((const char *)value->value) != 0;
49 82300 : return GSS_S_COMPLETE;
50 : }
51 :
52 : static OM_uint32
53 75431 : get_string(OM_uint32 *minor_status,
54 : const gss_buffer_t value,
55 : char **str)
56 : {
57 75431 : if (value == NULL || value->length == 0) {
58 16 : *str = NULL;
59 : } else {
60 75415 : *str = malloc(value->length + 1);
61 75415 : if (*str == NULL) {
62 0 : *minor_status = 0;
63 0 : return GSS_S_UNAVAILABLE;
64 : }
65 77815 : memcpy(*str, value->value, value->length);
66 75415 : (*str)[value->length] = '\0';
67 : }
68 73031 : return GSS_S_COMPLETE;
69 : }
70 :
71 : static OM_uint32
72 0 : get_int32(OM_uint32 *minor_status,
73 : const gss_buffer_t value,
74 : OM_uint32 *ret)
75 : {
76 0 : *minor_status = 0;
77 0 : if (value == NULL || value->length == 0)
78 0 : *ret = 0;
79 0 : else if (value->length == sizeof(*ret))
80 0 : memcpy(ret, value->value, sizeof(*ret));
81 : else
82 0 : return GSS_S_UNAVAILABLE;
83 :
84 0 : return GSS_S_COMPLETE;
85 : }
86 :
87 : static OM_uint32
88 0 : set_int32(OM_uint32 *minor_status,
89 : const gss_buffer_t value,
90 : OM_uint32 set)
91 : {
92 0 : *minor_status = 0;
93 0 : if (value->length == sizeof(set))
94 0 : memcpy(value->value, &set, sizeof(set));
95 : else
96 0 : return GSS_S_UNAVAILABLE;
97 :
98 0 : return GSS_S_COMPLETE;
99 : }
100 :
101 : OM_uint32 GSSAPI_CALLCONV
102 234645 : _gsskrb5_set_sec_context_option
103 : (OM_uint32 *minor_status,
104 : gss_ctx_id_t *context_handle,
105 : const gss_OID desired_object,
106 : const gss_buffer_t value)
107 : {
108 : krb5_context context;
109 : OM_uint32 maj_stat;
110 :
111 234645 : GSSAPI_KRB5_INIT (&context);
112 :
113 234645 : if (value == GSS_C_NO_BUFFER) {
114 0 : *minor_status = EINVAL;
115 0 : return GSS_S_FAILURE;
116 : }
117 :
118 234645 : if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
119 : gsskrb5_ctx ctx;
120 : int flag;
121 :
122 0 : if (*context_handle == GSS_C_NO_CONTEXT) {
123 0 : *minor_status = EINVAL;
124 0 : return GSS_S_NO_CONTEXT;
125 : }
126 :
127 0 : maj_stat = get_bool(minor_status, value, &flag);
128 0 : if (maj_stat != GSS_S_COMPLETE)
129 0 : return maj_stat;
130 :
131 0 : ctx = (gsskrb5_ctx)*context_handle;
132 : HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
133 0 : if (flag)
134 0 : ctx->more_flags |= COMPAT_OLD_DES3;
135 : else
136 0 : ctx->more_flags &= ~COMPAT_OLD_DES3;
137 0 : ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
138 : HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
139 0 : return GSS_S_COMPLETE;
140 234645 : } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
141 : int flag;
142 :
143 84700 : maj_stat = get_bool(minor_status, value, &flag);
144 82300 : if (maj_stat != GSS_S_COMPLETE)
145 0 : return maj_stat;
146 :
147 84700 : krb5_set_dns_canonicalize_hostname(context, flag);
148 84700 : return GSS_S_COMPLETE;
149 :
150 149945 : } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
151 : char *str;
152 :
153 0 : maj_stat = get_string(minor_status, value, &str);
154 0 : if (maj_stat != GSS_S_COMPLETE)
155 0 : return maj_stat;
156 :
157 0 : maj_stat = _gsskrb5_register_acceptor_identity(minor_status, str);
158 0 : free(str);
159 :
160 0 : return maj_stat;
161 :
162 149945 : } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
163 : char *str;
164 :
165 75431 : maj_stat = get_string(minor_status, value, &str);
166 75431 : if (maj_stat != GSS_S_COMPLETE)
167 0 : return maj_stat;
168 75431 : if (str == NULL) {
169 16 : *minor_status = 0;
170 16 : return GSS_S_CALL_INACCESSIBLE_READ;
171 : }
172 :
173 75415 : krb5_set_default_realm(context, str);
174 75415 : free(str);
175 :
176 75415 : *minor_status = 0;
177 75415 : return GSS_S_COMPLETE;
178 :
179 74514 : } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {
180 :
181 74514 : if (value == NULL || value->length == 0) {
182 0 : krb5_set_send_to_kdc_func(context, NULL, NULL);
183 : } else {
184 : struct gsskrb5_send_to_kdc c;
185 :
186 74514 : if (value->length != sizeof(c)) {
187 0 : *minor_status = EINVAL;
188 0 : return GSS_S_FAILURE;
189 : }
190 74514 : memcpy(&c, value->value, sizeof(c));
191 146052 : krb5_set_send_to_kdc_func(context,
192 71538 : (krb5_send_to_kdc_func)c.func,
193 : c.ptr);
194 : }
195 :
196 74514 : *minor_status = 0;
197 74514 : return GSS_S_COMPLETE;
198 0 : } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
199 : char *str;
200 :
201 0 : maj_stat = get_string(minor_status, value, &str);
202 0 : if (maj_stat != GSS_S_COMPLETE)
203 0 : return maj_stat;
204 0 : if (str == NULL) {
205 0 : *minor_status = 0;
206 0 : return GSS_S_CALL_INACCESSIBLE_READ;
207 : }
208 :
209 0 : *minor_status = krb5_cc_set_default_name(context, str);
210 0 : free(str);
211 0 : if (*minor_status)
212 0 : return GSS_S_FAILURE;
213 :
214 0 : return GSS_S_COMPLETE;
215 0 : } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
216 : OM_uint32 offset;
217 : time_t t;
218 :
219 0 : maj_stat = get_int32(minor_status, value, &offset);
220 0 : if (maj_stat != GSS_S_COMPLETE)
221 0 : return maj_stat;
222 :
223 0 : t = time(NULL) + offset;
224 :
225 0 : krb5_set_real_time(context, t, 0);
226 :
227 0 : *minor_status = 0;
228 0 : return GSS_S_COMPLETE;
229 0 : } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) {
230 : krb5_timestamp sec;
231 : int32_t usec;
232 : time_t t;
233 :
234 0 : t = time(NULL);
235 :
236 0 : krb5_us_timeofday (context, &sec, &usec);
237 :
238 0 : maj_stat = set_int32(minor_status, value, sec - t);
239 0 : if (maj_stat != GSS_S_COMPLETE)
240 0 : return maj_stat;
241 :
242 0 : *minor_status = 0;
243 0 : return GSS_S_COMPLETE;
244 0 : } else if (gss_oid_equal(desired_object, GSS_KRB5_PLUGIN_REGISTER_X)) {
245 : struct gsskrb5_krb5_plugin c;
246 :
247 0 : if (value->length != sizeof(c)) {
248 0 : *minor_status = EINVAL;
249 0 : return GSS_S_FAILURE;
250 : }
251 0 : memcpy(&c, value->value, sizeof(c));
252 0 : krb5_plugin_register(context, c.type, c.name, c.symbol);
253 :
254 0 : *minor_status = 0;
255 0 : return GSS_S_COMPLETE;
256 : }
257 :
258 0 : *minor_status = EINVAL;
259 0 : return GSS_S_FAILURE;
260 : }
|