• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/heimdal/lib/gssapi/krb5/
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#include "gsskrb5_locl.h"
34
35/* 1.2.752.43.13.17 */
36static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
37{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
38
39gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_cred_no_ci_flags_x_oid_desc;
40
41/* 1.2.752.43.13.18 */
42static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
43{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
44
45gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
46
47
48
49static OM_uint32
50import_cred(OM_uint32 *minor_status,
51	    krb5_context context,
52            gss_cred_id_t *cred_handle,
53            const gss_buffer_t value)
54{
55    OM_uint32 major_stat;
56    krb5_error_code ret;
57    krb5_principal keytab_principal = NULL;
58    krb5_keytab keytab = NULL;
59    krb5_storage *sp = NULL;
60    krb5_ccache id = NULL;
61    char *str;
62
63    if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) {
64	*minor_status = 0;
65	return GSS_S_FAILURE;
66    }
67
68    sp = krb5_storage_from_mem(value->value, value->length);
69    if (sp == NULL) {
70	*minor_status = 0;
71	return GSS_S_FAILURE;
72    }
73
74    /* credential cache name */
75    ret = krb5_ret_string(sp, &str);
76    if (ret) {
77	*minor_status = ret;
78	major_stat =  GSS_S_FAILURE;
79	goto out;
80    }
81    if (str[0]) {
82	ret = krb5_cc_resolve(context, str, &id);
83	if (ret) {
84	    *minor_status = ret;
85	    major_stat =  GSS_S_FAILURE;
86	    goto out;
87	}
88    }
89    free(str);
90    str = NULL;
91
92    /* keytab principal name */
93    ret = krb5_ret_string(sp, &str);
94    if (ret == 0 && str[0])
95	ret = krb5_parse_name(context, str, &keytab_principal);
96    if (ret) {
97	*minor_status = ret;
98	major_stat = GSS_S_FAILURE;
99	goto out;
100    }
101    free(str);
102    str = NULL;
103
104    /* keytab principal */
105    ret = krb5_ret_string(sp, &str);
106    if (ret) {
107	*minor_status = ret;
108	major_stat =  GSS_S_FAILURE;
109	goto out;
110    }
111    if (str[0]) {
112	ret = krb5_kt_resolve(context, str, &keytab);
113	if (ret) {
114	    *minor_status = ret;
115	    major_stat =  GSS_S_FAILURE;
116	    goto out;
117	}
118    }
119    free(str);
120    str = NULL;
121
122    major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal,
123					   keytab, cred_handle);
124out:
125    if (id)
126	krb5_cc_close(context, id);
127    if (keytab_principal)
128	krb5_free_principal(context, keytab_principal);
129    if (keytab)
130	krb5_kt_close(context, keytab);
131    if (str)
132	free(str);
133    if (sp)
134	krb5_storage_free(sp);
135
136    return major_stat;
137}
138
139
140static OM_uint32
141allowed_enctypes(OM_uint32 *minor_status,
142		 krb5_context context,
143		 gss_cred_id_t *cred_handle,
144		 const gss_buffer_t value)
145{
146    OM_uint32 major_stat;
147    krb5_error_code ret;
148    size_t len, i;
149    krb5_enctype *enctypes = NULL;
150    krb5_storage *sp = NULL;
151    gsskrb5_cred cred;
152
153    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
154	*minor_status = 0;
155	return GSS_S_FAILURE;
156    }
157
158    cred = (gsskrb5_cred)*cred_handle;
159
160    if ((value->length % 4) != 0) {
161	*minor_status = 0;
162	major_stat = GSS_S_FAILURE;
163	goto out;
164    }
165
166    len = value->length / 4;
167    enctypes = malloc((len + 1) * 4);
168    if (enctypes == NULL) {
169	*minor_status = ENOMEM;
170	major_stat = GSS_S_FAILURE;
171	goto out;
172    }
173
174    sp = krb5_storage_from_mem(value->value, value->length);
175    if (sp == NULL) {
176	*minor_status = ENOMEM;
177	major_stat = GSS_S_FAILURE;
178	goto out;
179    }
180
181    for (i = 0; i < len; i++) {
182	uint32_t e;
183
184	ret = krb5_ret_uint32(sp, &e);
185	if (ret) {
186	    *minor_status = ret;
187	    major_stat =  GSS_S_FAILURE;
188	    goto out;
189	}
190	enctypes[i] = e;
191    }
192    enctypes[i] = 0;
193
194    if (cred->enctypes)
195	free(cred->enctypes);
196    cred->enctypes = enctypes;
197
198    krb5_storage_free(sp);
199
200    return GSS_S_COMPLETE;
201
202out:
203    if (sp)
204	krb5_storage_free(sp);
205    if (enctypes)
206	free(enctypes);
207
208    return major_stat;
209}
210
211static OM_uint32
212no_ci_flags(OM_uint32 *minor_status,
213	    krb5_context context,
214	    gss_cred_id_t *cred_handle,
215	    const gss_buffer_t value)
216{
217    gsskrb5_cred cred;
218
219    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
220	*minor_status = 0;
221	return GSS_S_FAILURE;
222    }
223
224    cred = (gsskrb5_cred)*cred_handle;
225    cred->cred_flags |= GSS_CF_NO_CI_FLAGS;
226
227    *minor_status = 0;
228    return GSS_S_COMPLETE;
229
230}
231
232
233OM_uint32
234_gsskrb5_set_cred_option
235           (OM_uint32 *minor_status,
236            gss_cred_id_t *cred_handle,
237            const gss_OID desired_object,
238            const gss_buffer_t value)
239{
240    krb5_context context;
241
242    GSSAPI_KRB5_INIT (&context);
243
244    if (value == GSS_C_NO_BUFFER) {
245	*minor_status = EINVAL;
246	return GSS_S_FAILURE;
247    }
248
249    if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X))
250	return import_cred(minor_status, context, cred_handle, value);
251
252    if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X))
253	return allowed_enctypes(minor_status, context, cred_handle, value);
254
255    if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) {
256	return no_ci_flags(minor_status, context, cred_handle, value);
257    }
258
259
260    *minor_status = EINVAL;
261    return GSS_S_FAILURE;
262}
263