krb5tgs.c revision 1.1.1.1.4.1 1 1.1.1.1.4.1 yamt /* $NetBSD: krb5tgs.c,v 1.1.1.1.4.1 2014/05/22 13:21:24 yamt Exp $ */
2 1.1 elric
3 1.1 elric /*
4 1.1 elric * Copyright (c) 1997-2008 Kungliga Tekniska Hgskolan
5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden).
6 1.1 elric * All rights reserved.
7 1.1 elric *
8 1.1 elric * Redistribution and use in source and binary forms, with or without
9 1.1 elric * modification, are permitted provided that the following conditions
10 1.1 elric * are met:
11 1.1 elric *
12 1.1 elric * 1. Redistributions of source code must retain the above copyright
13 1.1 elric * notice, this list of conditions and the following disclaimer.
14 1.1 elric *
15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 elric * notice, this list of conditions and the following disclaimer in the
17 1.1 elric * documentation and/or other materials provided with the distribution.
18 1.1 elric *
19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors
20 1.1 elric * may be used to endorse or promote products derived from this software
21 1.1 elric * without specific prior written permission.
22 1.1 elric *
23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 elric * SUCH DAMAGE.
34 1.1 elric */
35 1.1 elric
36 1.1 elric #include "kdc_locl.h"
37 1.1 elric
38 1.1 elric /*
39 1.1 elric * return the realm of a krbtgt-ticket or NULL
40 1.1 elric */
41 1.1 elric
42 1.1 elric static Realm
43 1.1 elric get_krbtgt_realm(const PrincipalName *p)
44 1.1 elric {
45 1.1 elric if(p->name_string.len == 2
46 1.1 elric && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)
47 1.1 elric return p->name_string.val[1];
48 1.1 elric else
49 1.1 elric return NULL;
50 1.1 elric }
51 1.1 elric
52 1.1 elric /*
53 1.1 elric * The KDC might add a signed path to the ticket authorization data
54 1.1 elric * field. This is to avoid server impersonating clients and the
55 1.1 elric * request constrained delegation.
56 1.1 elric *
57 1.1 elric * This is done by storing a KRB5_AUTHDATA_IF_RELEVANT with a single
58 1.1 elric * entry of type KRB5SignedPath.
59 1.1 elric */
60 1.1 elric
61 1.1 elric static krb5_error_code
62 1.1 elric find_KRB5SignedPath(krb5_context context,
63 1.1 elric const AuthorizationData *ad,
64 1.1 elric krb5_data *data)
65 1.1 elric {
66 1.1 elric AuthorizationData child;
67 1.1 elric krb5_error_code ret;
68 1.1 elric int pos;
69 1.1.1.1.4.1 yamt
70 1.1 elric if (ad == NULL || ad->len == 0)
71 1.1 elric return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
72 1.1 elric
73 1.1 elric pos = ad->len - 1;
74 1.1 elric
75 1.1 elric if (ad->val[pos].ad_type != KRB5_AUTHDATA_IF_RELEVANT)
76 1.1 elric return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
77 1.1 elric
78 1.1 elric ret = decode_AuthorizationData(ad->val[pos].ad_data.data,
79 1.1 elric ad->val[pos].ad_data.length,
80 1.1 elric &child,
81 1.1 elric NULL);
82 1.1 elric if (ret) {
83 1.1 elric krb5_set_error_message(context, ret, "Failed to decode "
84 1.1 elric "IF_RELEVANT with %d", ret);
85 1.1 elric return ret;
86 1.1 elric }
87 1.1 elric
88 1.1 elric if (child.len != 1) {
89 1.1 elric free_AuthorizationData(&child);
90 1.1 elric return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
91 1.1 elric }
92 1.1 elric
93 1.1 elric if (child.val[0].ad_type != KRB5_AUTHDATA_SIGNTICKET) {
94 1.1 elric free_AuthorizationData(&child);
95 1.1 elric return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
96 1.1 elric }
97 1.1 elric
98 1.1 elric if (data)
99 1.1 elric ret = der_copy_octet_string(&child.val[0].ad_data, data);
100 1.1 elric free_AuthorizationData(&child);
101 1.1 elric return ret;
102 1.1 elric }
103 1.1 elric
104 1.1 elric krb5_error_code
105 1.1 elric _kdc_add_KRB5SignedPath(krb5_context context,
106 1.1 elric krb5_kdc_configuration *config,
107 1.1 elric hdb_entry_ex *krbtgt,
108 1.1 elric krb5_enctype enctype,
109 1.1 elric krb5_principal client,
110 1.1 elric krb5_const_principal server,
111 1.1 elric krb5_principals principals,
112 1.1 elric EncTicketPart *tkt)
113 1.1 elric {
114 1.1 elric krb5_error_code ret;
115 1.1 elric KRB5SignedPath sp;
116 1.1 elric krb5_data data;
117 1.1 elric krb5_crypto crypto = NULL;
118 1.1.1.1.4.1 yamt size_t size = 0;
119 1.1 elric
120 1.1 elric if (server && principals) {
121 1.1 elric ret = add_Principals(principals, server);
122 1.1 elric if (ret)
123 1.1 elric return ret;
124 1.1 elric }
125 1.1 elric
126 1.1 elric {
127 1.1 elric KRB5SignedPathData spd;
128 1.1.1.1.4.1 yamt
129 1.1 elric spd.client = client;
130 1.1 elric spd.authtime = tkt->authtime;
131 1.1 elric spd.delegated = principals;
132 1.1 elric spd.method_data = NULL;
133 1.1.1.1.4.1 yamt
134 1.1 elric ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
135 1.1 elric &spd, &size, ret);
136 1.1 elric if (ret)
137 1.1 elric return ret;
138 1.1 elric if (data.length != size)
139 1.1 elric krb5_abortx(context, "internal asn.1 encoder error");
140 1.1 elric }
141 1.1 elric
142 1.1 elric {
143 1.1 elric Key *key;
144 1.1 elric ret = hdb_enctype2key(context, &krbtgt->entry, enctype, &key);
145 1.1 elric if (ret == 0)
146 1.1 elric ret = krb5_crypto_init(context, &key->key, 0, &crypto);
147 1.1 elric if (ret) {
148 1.1 elric free(data.data);
149 1.1 elric return ret;
150 1.1 elric }
151 1.1 elric }
152 1.1 elric
153 1.1 elric /*
154 1.1 elric * Fill in KRB5SignedPath
155 1.1 elric */
156 1.1 elric
157 1.1 elric sp.etype = enctype;
158 1.1 elric sp.delegated = principals;
159 1.1 elric sp.method_data = NULL;
160 1.1 elric
161 1.1 elric ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,
162 1.1 elric data.data, data.length, &sp.cksum);
163 1.1 elric krb5_crypto_destroy(context, crypto);
164 1.1 elric free(data.data);
165 1.1 elric if (ret)
166 1.1 elric return ret;
167 1.1 elric
168 1.1 elric ASN1_MALLOC_ENCODE(KRB5SignedPath, data.data, data.length, &sp, &size, ret);
169 1.1 elric free_Checksum(&sp.cksum);
170 1.1 elric if (ret)
171 1.1 elric return ret;
172 1.1 elric if (data.length != size)
173 1.1 elric krb5_abortx(context, "internal asn.1 encoder error");
174 1.1 elric
175 1.1 elric
176 1.1 elric /*
177 1.1 elric * Add IF-RELEVANT(KRB5SignedPath) to the last slot in
178 1.1 elric * authorization data field.
179 1.1 elric */
180 1.1 elric
181 1.1 elric ret = _kdc_tkt_add_if_relevant_ad(context, tkt,
182 1.1 elric KRB5_AUTHDATA_SIGNTICKET, &data);
183 1.1 elric krb5_data_free(&data);
184 1.1 elric
185 1.1 elric return ret;
186 1.1 elric }
187 1.1 elric
188 1.1 elric static krb5_error_code
189 1.1 elric check_KRB5SignedPath(krb5_context context,
190 1.1 elric krb5_kdc_configuration *config,
191 1.1 elric hdb_entry_ex *krbtgt,
192 1.1 elric krb5_principal cp,
193 1.1 elric EncTicketPart *tkt,
194 1.1 elric krb5_principals *delegated,
195 1.1 elric int *signedpath)
196 1.1 elric {
197 1.1 elric krb5_error_code ret;
198 1.1 elric krb5_data data;
199 1.1 elric krb5_crypto crypto = NULL;
200 1.1 elric
201 1.1 elric if (delegated)
202 1.1 elric *delegated = NULL;
203 1.1 elric
204 1.1 elric ret = find_KRB5SignedPath(context, tkt->authorization_data, &data);
205 1.1 elric if (ret == 0) {
206 1.1 elric KRB5SignedPathData spd;
207 1.1 elric KRB5SignedPath sp;
208 1.1.1.1.4.1 yamt size_t size = 0;
209 1.1 elric
210 1.1 elric ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL);
211 1.1 elric krb5_data_free(&data);
212 1.1 elric if (ret)
213 1.1 elric return ret;
214 1.1 elric
215 1.1 elric spd.client = cp;
216 1.1 elric spd.authtime = tkt->authtime;
217 1.1 elric spd.delegated = sp.delegated;
218 1.1 elric spd.method_data = sp.method_data;
219 1.1 elric
220 1.1 elric ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
221 1.1 elric &spd, &size, ret);
222 1.1 elric if (ret) {
223 1.1 elric free_KRB5SignedPath(&sp);
224 1.1 elric return ret;
225 1.1 elric }
226 1.1 elric if (data.length != size)
227 1.1 elric krb5_abortx(context, "internal asn.1 encoder error");
228 1.1 elric
229 1.1 elric {
230 1.1 elric Key *key;
231 1.1 elric ret = hdb_enctype2key(context, &krbtgt->entry, sp.etype, &key);
232 1.1 elric if (ret == 0)
233 1.1 elric ret = krb5_crypto_init(context, &key->key, 0, &crypto);
234 1.1 elric if (ret) {
235 1.1 elric free(data.data);
236 1.1 elric free_KRB5SignedPath(&sp);
237 1.1 elric return ret;
238 1.1 elric }
239 1.1 elric }
240 1.1 elric ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH,
241 1.1 elric data.data, data.length,
242 1.1 elric &sp.cksum);
243 1.1 elric krb5_crypto_destroy(context, crypto);
244 1.1 elric free(data.data);
245 1.1 elric if (ret) {
246 1.1 elric free_KRB5SignedPath(&sp);
247 1.1 elric kdc_log(context, config, 5,
248 1.1 elric "KRB5SignedPath not signed correctly, not marking as signed");
249 1.1 elric return 0;
250 1.1 elric }
251 1.1 elric
252 1.1 elric if (delegated && sp.delegated) {
253 1.1 elric
254 1.1 elric *delegated = malloc(sizeof(*sp.delegated));
255 1.1 elric if (*delegated == NULL) {
256 1.1 elric free_KRB5SignedPath(&sp);
257 1.1 elric return ENOMEM;
258 1.1 elric }
259 1.1 elric
260 1.1 elric ret = copy_Principals(*delegated, sp.delegated);
261 1.1 elric if (ret) {
262 1.1 elric free_KRB5SignedPath(&sp);
263 1.1 elric free(*delegated);
264 1.1 elric *delegated = NULL;
265 1.1 elric return ret;
266 1.1 elric }
267 1.1 elric }
268 1.1 elric free_KRB5SignedPath(&sp);
269 1.1 elric
270 1.1 elric *signedpath = 1;
271 1.1 elric }
272 1.1 elric
273 1.1 elric return 0;
274 1.1 elric }
275 1.1 elric
276 1.1 elric /*
277 1.1 elric *
278 1.1 elric */
279 1.1 elric
280 1.1 elric static krb5_error_code
281 1.1 elric check_PAC(krb5_context context,
282 1.1 elric krb5_kdc_configuration *config,
283 1.1 elric const krb5_principal client_principal,
284 1.1.1.1.4.1 yamt const krb5_principal delegated_proxy_principal,
285 1.1 elric hdb_entry_ex *client,
286 1.1 elric hdb_entry_ex *server,
287 1.1 elric hdb_entry_ex *krbtgt,
288 1.1.1.1.4.1 yamt const EncryptionKey *server_check_key,
289 1.1 elric const EncryptionKey *krbtgt_check_key,
290 1.1.1.1.4.1 yamt const EncryptionKey *server_sign_key,
291 1.1 elric const EncryptionKey *krbtgt_sign_key,
292 1.1 elric EncTicketPart *tkt,
293 1.1 elric krb5_data *rspac,
294 1.1 elric int *signedpath)
295 1.1 elric {
296 1.1 elric AuthorizationData *ad = tkt->authorization_data;
297 1.1 elric unsigned i, j;
298 1.1 elric krb5_error_code ret;
299 1.1 elric
300 1.1 elric if (ad == NULL || ad->len == 0)
301 1.1 elric return 0;
302 1.1 elric
303 1.1 elric for (i = 0; i < ad->len; i++) {
304 1.1 elric AuthorizationData child;
305 1.1 elric
306 1.1 elric if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT)
307 1.1 elric continue;
308 1.1 elric
309 1.1 elric ret = decode_AuthorizationData(ad->val[i].ad_data.data,
310 1.1 elric ad->val[i].ad_data.length,
311 1.1 elric &child,
312 1.1 elric NULL);
313 1.1 elric if (ret) {
314 1.1 elric krb5_set_error_message(context, ret, "Failed to decode "
315 1.1 elric "IF_RELEVANT with %d", ret);
316 1.1 elric return ret;
317 1.1 elric }
318 1.1 elric for (j = 0; j < child.len; j++) {
319 1.1 elric
320 1.1 elric if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) {
321 1.1 elric int signed_pac = 0;
322 1.1 elric krb5_pac pac;
323 1.1 elric
324 1.1 elric /* Found PAC */
325 1.1 elric ret = krb5_pac_parse(context,
326 1.1 elric child.val[j].ad_data.data,
327 1.1 elric child.val[j].ad_data.length,
328 1.1 elric &pac);
329 1.1 elric free_AuthorizationData(&child);
330 1.1 elric if (ret)
331 1.1 elric return ret;
332 1.1 elric
333 1.1 elric ret = krb5_pac_verify(context, pac, tkt->authtime,
334 1.1 elric client_principal,
335 1.1.1.1.4.1 yamt server_check_key, krbtgt_check_key);
336 1.1 elric if (ret) {
337 1.1 elric krb5_pac_free(context, pac);
338 1.1 elric return ret;
339 1.1 elric }
340 1.1 elric
341 1.1 elric ret = _kdc_pac_verify(context, client_principal,
342 1.1.1.1.4.1 yamt delegated_proxy_principal,
343 1.1 elric client, server, krbtgt, &pac, &signed_pac);
344 1.1 elric if (ret) {
345 1.1 elric krb5_pac_free(context, pac);
346 1.1 elric return ret;
347 1.1 elric }
348 1.1 elric
349 1.1 elric /*
350 1.1 elric * Only re-sign PAC if we could verify it with the PAC
351 1.1 elric * function. The no-verify case happens when we get in
352 1.1 elric * a PAC from cross realm from a Windows domain and
353 1.1 elric * that there is no PAC verification function.
354 1.1 elric */
355 1.1 elric if (signed_pac) {
356 1.1 elric *signedpath = 1;
357 1.1 elric ret = _krb5_pac_sign(context, pac, tkt->authtime,
358 1.1 elric client_principal,
359 1.1.1.1.4.1 yamt server_sign_key, krbtgt_sign_key, rspac);
360 1.1 elric }
361 1.1 elric krb5_pac_free(context, pac);
362 1.1.1.1.4.1 yamt
363 1.1 elric return ret;
364 1.1 elric }
365 1.1 elric }
366 1.1 elric free_AuthorizationData(&child);
367 1.1 elric }
368 1.1 elric return 0;
369 1.1 elric }
370 1.1 elric
371 1.1 elric /*
372 1.1 elric *
373 1.1 elric */
374 1.1 elric
375 1.1 elric static krb5_error_code
376 1.1 elric check_tgs_flags(krb5_context context,
377 1.1 elric krb5_kdc_configuration *config,
378 1.1 elric KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et)
379 1.1 elric {
380 1.1 elric KDCOptions f = b->kdc_options;
381 1.1.1.1.4.1 yamt
382 1.1 elric if(f.validate){
383 1.1 elric if(!tgt->flags.invalid || tgt->starttime == NULL){
384 1.1 elric kdc_log(context, config, 0,
385 1.1 elric "Bad request to validate ticket");
386 1.1 elric return KRB5KDC_ERR_BADOPTION;
387 1.1 elric }
388 1.1 elric if(*tgt->starttime > kdc_time){
389 1.1 elric kdc_log(context, config, 0,
390 1.1 elric "Early request to validate ticket");
391 1.1 elric return KRB5KRB_AP_ERR_TKT_NYV;
392 1.1 elric }
393 1.1 elric /* XXX tkt = tgt */
394 1.1 elric et->flags.invalid = 0;
395 1.1 elric }else if(tgt->flags.invalid){
396 1.1 elric kdc_log(context, config, 0,
397 1.1 elric "Ticket-granting ticket has INVALID flag set");
398 1.1 elric return KRB5KRB_AP_ERR_TKT_INVALID;
399 1.1 elric }
400 1.1 elric
401 1.1 elric if(f.forwardable){
402 1.1 elric if(!tgt->flags.forwardable){
403 1.1 elric kdc_log(context, config, 0,
404 1.1 elric "Bad request for forwardable ticket");
405 1.1 elric return KRB5KDC_ERR_BADOPTION;
406 1.1 elric }
407 1.1 elric et->flags.forwardable = 1;
408 1.1 elric }
409 1.1 elric if(f.forwarded){
410 1.1 elric if(!tgt->flags.forwardable){
411 1.1 elric kdc_log(context, config, 0,
412 1.1 elric "Request to forward non-forwardable ticket");
413 1.1 elric return KRB5KDC_ERR_BADOPTION;
414 1.1 elric }
415 1.1 elric et->flags.forwarded = 1;
416 1.1 elric et->caddr = b->addresses;
417 1.1 elric }
418 1.1 elric if(tgt->flags.forwarded)
419 1.1 elric et->flags.forwarded = 1;
420 1.1.1.1.4.1 yamt
421 1.1 elric if(f.proxiable){
422 1.1 elric if(!tgt->flags.proxiable){
423 1.1 elric kdc_log(context, config, 0,
424 1.1 elric "Bad request for proxiable ticket");
425 1.1 elric return KRB5KDC_ERR_BADOPTION;
426 1.1 elric }
427 1.1 elric et->flags.proxiable = 1;
428 1.1 elric }
429 1.1 elric if(f.proxy){
430 1.1 elric if(!tgt->flags.proxiable){
431 1.1 elric kdc_log(context, config, 0,
432 1.1 elric "Request to proxy non-proxiable ticket");
433 1.1 elric return KRB5KDC_ERR_BADOPTION;
434 1.1 elric }
435 1.1 elric et->flags.proxy = 1;
436 1.1 elric et->caddr = b->addresses;
437 1.1 elric }
438 1.1 elric if(tgt->flags.proxy)
439 1.1 elric et->flags.proxy = 1;
440 1.1 elric
441 1.1 elric if(f.allow_postdate){
442 1.1 elric if(!tgt->flags.may_postdate){
443 1.1 elric kdc_log(context, config, 0,
444 1.1 elric "Bad request for post-datable ticket");
445 1.1 elric return KRB5KDC_ERR_BADOPTION;
446 1.1 elric }
447 1.1 elric et->flags.may_postdate = 1;
448 1.1 elric }
449 1.1 elric if(f.postdated){
450 1.1 elric if(!tgt->flags.may_postdate){
451 1.1 elric kdc_log(context, config, 0,
452 1.1 elric "Bad request for postdated ticket");
453 1.1 elric return KRB5KDC_ERR_BADOPTION;
454 1.1 elric }
455 1.1 elric if(b->from)
456 1.1 elric *et->starttime = *b->from;
457 1.1 elric et->flags.postdated = 1;
458 1.1 elric et->flags.invalid = 1;
459 1.1 elric }else if(b->from && *b->from > kdc_time + context->max_skew){
460 1.1 elric kdc_log(context, config, 0, "Ticket cannot be postdated");
461 1.1 elric return KRB5KDC_ERR_CANNOT_POSTDATE;
462 1.1 elric }
463 1.1 elric
464 1.1 elric if(f.renewable){
465 1.1 elric if(!tgt->flags.renewable || tgt->renew_till == NULL){
466 1.1 elric kdc_log(context, config, 0,
467 1.1 elric "Bad request for renewable ticket");
468 1.1 elric return KRB5KDC_ERR_BADOPTION;
469 1.1 elric }
470 1.1 elric et->flags.renewable = 1;
471 1.1 elric ALLOC(et->renew_till);
472 1.1 elric _kdc_fix_time(&b->rtime);
473 1.1 elric *et->renew_till = *b->rtime;
474 1.1 elric }
475 1.1 elric if(f.renew){
476 1.1 elric time_t old_life;
477 1.1 elric if(!tgt->flags.renewable || tgt->renew_till == NULL){
478 1.1 elric kdc_log(context, config, 0,
479 1.1 elric "Request to renew non-renewable ticket");
480 1.1 elric return KRB5KDC_ERR_BADOPTION;
481 1.1 elric }
482 1.1 elric old_life = tgt->endtime;
483 1.1 elric if(tgt->starttime)
484 1.1 elric old_life -= *tgt->starttime;
485 1.1 elric else
486 1.1 elric old_life -= tgt->authtime;
487 1.1 elric et->endtime = *et->starttime + old_life;
488 1.1 elric if (et->renew_till != NULL)
489 1.1 elric et->endtime = min(*et->renew_till, et->endtime);
490 1.1.1.1.4.1 yamt }
491 1.1 elric
492 1.1 elric #if 0
493 1.1 elric /* checks for excess flags */
494 1.1 elric if(f.request_anonymous && !config->allow_anonymous){
495 1.1 elric kdc_log(context, config, 0,
496 1.1 elric "Request for anonymous ticket");
497 1.1 elric return KRB5KDC_ERR_BADOPTION;
498 1.1 elric }
499 1.1 elric #endif
500 1.1 elric return 0;
501 1.1 elric }
502 1.1 elric
503 1.1 elric /*
504 1.1 elric * Determine if constrained delegation is allowed from this client to this server
505 1.1 elric */
506 1.1 elric
507 1.1 elric static krb5_error_code
508 1.1 elric check_constrained_delegation(krb5_context context,
509 1.1 elric krb5_kdc_configuration *config,
510 1.1 elric HDB *clientdb,
511 1.1 elric hdb_entry_ex *client,
512 1.1.1.1.4.1 yamt hdb_entry_ex *server,
513 1.1.1.1.4.1 yamt krb5_const_principal target)
514 1.1 elric {
515 1.1 elric const HDB_Ext_Constrained_delegation_acl *acl;
516 1.1 elric krb5_error_code ret;
517 1.1.1.1.4.1 yamt size_t i;
518 1.1 elric
519 1.1.1.1.4.1 yamt /*
520 1.1.1.1.4.1 yamt * constrained_delegation (S4U2Proxy) only works within
521 1.1.1.1.4.1 yamt * the same realm. We use the already canonicalized version
522 1.1.1.1.4.1 yamt * of the principals here, while "target" is the principal
523 1.1.1.1.4.1 yamt * provided by the client.
524 1.1.1.1.4.1 yamt */
525 1.1.1.1.4.1 yamt if(!krb5_realm_compare(context, client->entry.principal, server->entry.principal)) {
526 1.1.1.1.4.1 yamt ret = KRB5KDC_ERR_BADOPTION;
527 1.1.1.1.4.1 yamt kdc_log(context, config, 0,
528 1.1.1.1.4.1 yamt "Bad request for constrained delegation");
529 1.1.1.1.4.1 yamt return ret;
530 1.1.1.1.4.1 yamt }
531 1.1 elric
532 1.1 elric if (clientdb->hdb_check_constrained_delegation) {
533 1.1.1.1.4.1 yamt ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, target);
534 1.1 elric if (ret == 0)
535 1.1 elric return 0;
536 1.1 elric } else {
537 1.1.1.1.4.1 yamt /* if client delegates to itself, that ok */
538 1.1.1.1.4.1 yamt if (krb5_principal_compare(context, client->entry.principal, server->entry.principal) == TRUE)
539 1.1.1.1.4.1 yamt return 0;
540 1.1.1.1.4.1 yamt
541 1.1 elric ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
542 1.1 elric if (ret) {
543 1.1 elric krb5_clear_error_message(context);
544 1.1 elric return ret;
545 1.1 elric }
546 1.1.1.1.4.1 yamt
547 1.1 elric if (acl) {
548 1.1 elric for (i = 0; i < acl->len; i++) {
549 1.1.1.1.4.1 yamt if (krb5_principal_compare(context, target, &acl->val[i]) == TRUE)
550 1.1 elric return 0;
551 1.1 elric }
552 1.1 elric }
553 1.1 elric ret = KRB5KDC_ERR_BADOPTION;
554 1.1 elric }
555 1.1 elric kdc_log(context, config, 0,
556 1.1 elric "Bad request for constrained delegation");
557 1.1 elric return ret;
558 1.1 elric }
559 1.1 elric
560 1.1 elric /*
561 1.1 elric * Determine if s4u2self is allowed from this client to this server
562 1.1 elric *
563 1.1 elric * For example, regardless of the principal being impersonated, if the
564 1.1 elric * 'client' and 'server' are the same, then it's safe.
565 1.1 elric */
566 1.1 elric
567 1.1 elric static krb5_error_code
568 1.1 elric check_s4u2self(krb5_context context,
569 1.1 elric krb5_kdc_configuration *config,
570 1.1 elric HDB *clientdb,
571 1.1 elric hdb_entry_ex *client,
572 1.1 elric krb5_const_principal server)
573 1.1 elric {
574 1.1 elric krb5_error_code ret;
575 1.1 elric
576 1.1 elric /* if client does a s4u2self to itself, that ok */
577 1.1 elric if (krb5_principal_compare(context, client->entry.principal, server) == TRUE)
578 1.1 elric return 0;
579 1.1 elric
580 1.1 elric if (clientdb->hdb_check_s4u2self) {
581 1.1 elric ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server);
582 1.1 elric if (ret == 0)
583 1.1 elric return 0;
584 1.1 elric } else {
585 1.1 elric ret = KRB5KDC_ERR_BADOPTION;
586 1.1 elric }
587 1.1 elric return ret;
588 1.1 elric }
589 1.1 elric
590 1.1 elric /*
591 1.1 elric *
592 1.1 elric */
593 1.1 elric
594 1.1 elric static krb5_error_code
595 1.1 elric verify_flags (krb5_context context,
596 1.1 elric krb5_kdc_configuration *config,
597 1.1 elric const EncTicketPart *et,
598 1.1 elric const char *pstr)
599 1.1 elric {
600 1.1 elric if(et->endtime < kdc_time){
601 1.1 elric kdc_log(context, config, 0, "Ticket expired (%s)", pstr);
602 1.1 elric return KRB5KRB_AP_ERR_TKT_EXPIRED;
603 1.1 elric }
604 1.1 elric if(et->flags.invalid){
605 1.1 elric kdc_log(context, config, 0, "Ticket not valid (%s)", pstr);
606 1.1 elric return KRB5KRB_AP_ERR_TKT_NYV;
607 1.1 elric }
608 1.1 elric return 0;
609 1.1 elric }
610 1.1 elric
611 1.1 elric /*
612 1.1 elric *
613 1.1 elric */
614 1.1 elric
615 1.1 elric static krb5_error_code
616 1.1 elric fix_transited_encoding(krb5_context context,
617 1.1 elric krb5_kdc_configuration *config,
618 1.1 elric krb5_boolean check_policy,
619 1.1 elric const TransitedEncoding *tr,
620 1.1 elric EncTicketPart *et,
621 1.1 elric const char *client_realm,
622 1.1 elric const char *server_realm,
623 1.1 elric const char *tgt_realm)
624 1.1 elric {
625 1.1 elric krb5_error_code ret = 0;
626 1.1 elric char **realms, **tmp;
627 1.1 elric unsigned int num_realms;
628 1.1.1.1.4.1 yamt size_t i;
629 1.1 elric
630 1.1 elric switch (tr->tr_type) {
631 1.1 elric case DOMAIN_X500_COMPRESS:
632 1.1 elric break;
633 1.1 elric case 0:
634 1.1 elric /*
635 1.1 elric * Allow empty content of type 0 because that is was Microsoft
636 1.1 elric * generates in their TGT.
637 1.1 elric */
638 1.1 elric if (tr->contents.length == 0)
639 1.1 elric break;
640 1.1 elric kdc_log(context, config, 0,
641 1.1 elric "Transited type 0 with non empty content");
642 1.1 elric return KRB5KDC_ERR_TRTYPE_NOSUPP;
643 1.1 elric default:
644 1.1 elric kdc_log(context, config, 0,
645 1.1 elric "Unknown transited type: %u", tr->tr_type);
646 1.1 elric return KRB5KDC_ERR_TRTYPE_NOSUPP;
647 1.1 elric }
648 1.1 elric
649 1.1 elric ret = krb5_domain_x500_decode(context,
650 1.1 elric tr->contents,
651 1.1 elric &realms,
652 1.1 elric &num_realms,
653 1.1 elric client_realm,
654 1.1 elric server_realm);
655 1.1 elric if(ret){
656 1.1 elric krb5_warn(context, ret,
657 1.1 elric "Decoding transited encoding");
658 1.1 elric return ret;
659 1.1 elric }
660 1.1 elric if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
661 1.1 elric /* not us, so add the previous realm to transited set */
662 1.1 elric if (num_realms + 1 > UINT_MAX/sizeof(*realms)) {
663 1.1 elric ret = ERANGE;
664 1.1 elric goto free_realms;
665 1.1 elric }
666 1.1 elric tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
667 1.1 elric if(tmp == NULL){
668 1.1 elric ret = ENOMEM;
669 1.1 elric goto free_realms;
670 1.1 elric }
671 1.1 elric realms = tmp;
672 1.1 elric realms[num_realms] = strdup(tgt_realm);
673 1.1 elric if(realms[num_realms] == NULL){
674 1.1 elric ret = ENOMEM;
675 1.1 elric goto free_realms;
676 1.1 elric }
677 1.1 elric num_realms++;
678 1.1 elric }
679 1.1 elric if(num_realms == 0) {
680 1.1 elric if(strcmp(client_realm, server_realm))
681 1.1 elric kdc_log(context, config, 0,
682 1.1 elric "cross-realm %s -> %s", client_realm, server_realm);
683 1.1 elric } else {
684 1.1 elric size_t l = 0;
685 1.1 elric char *rs;
686 1.1 elric for(i = 0; i < num_realms; i++)
687 1.1 elric l += strlen(realms[i]) + 2;
688 1.1 elric rs = malloc(l);
689 1.1 elric if(rs != NULL) {
690 1.1 elric *rs = '\0';
691 1.1 elric for(i = 0; i < num_realms; i++) {
692 1.1 elric if(i > 0)
693 1.1 elric strlcat(rs, ", ", l);
694 1.1 elric strlcat(rs, realms[i], l);
695 1.1 elric }
696 1.1 elric kdc_log(context, config, 0,
697 1.1 elric "cross-realm %s -> %s via [%s]",
698 1.1 elric client_realm, server_realm, rs);
699 1.1 elric free(rs);
700 1.1 elric }
701 1.1 elric }
702 1.1 elric if(check_policy) {
703 1.1 elric ret = krb5_check_transited(context, client_realm,
704 1.1 elric server_realm,
705 1.1 elric realms, num_realms, NULL);
706 1.1 elric if(ret) {
707 1.1 elric krb5_warn(context, ret, "cross-realm %s -> %s",
708 1.1 elric client_realm, server_realm);
709 1.1 elric goto free_realms;
710 1.1 elric }
711 1.1 elric et->flags.transited_policy_checked = 1;
712 1.1 elric }
713 1.1 elric et->transited.tr_type = DOMAIN_X500_COMPRESS;
714 1.1 elric ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
715 1.1 elric if(ret)
716 1.1 elric krb5_warn(context, ret, "Encoding transited encoding");
717 1.1 elric free_realms:
718 1.1 elric for(i = 0; i < num_realms; i++)
719 1.1 elric free(realms[i]);
720 1.1 elric free(realms);
721 1.1 elric return ret;
722 1.1 elric }
723 1.1 elric
724 1.1 elric
725 1.1 elric static krb5_error_code
726 1.1 elric tgs_make_reply(krb5_context context,
727 1.1 elric krb5_kdc_configuration *config,
728 1.1 elric KDC_REQ_BODY *b,
729 1.1 elric krb5_const_principal tgt_name,
730 1.1 elric const EncTicketPart *tgt,
731 1.1 elric const krb5_keyblock *replykey,
732 1.1 elric int rk_is_subkey,
733 1.1 elric const EncryptionKey *serverkey,
734 1.1 elric const krb5_keyblock *sessionkey,
735 1.1 elric krb5_kvno kvno,
736 1.1 elric AuthorizationData *auth_data,
737 1.1 elric hdb_entry_ex *server,
738 1.1 elric krb5_principal server_principal,
739 1.1 elric const char *server_name,
740 1.1 elric hdb_entry_ex *client,
741 1.1 elric krb5_principal client_principal,
742 1.1 elric hdb_entry_ex *krbtgt,
743 1.1 elric krb5_enctype krbtgt_etype,
744 1.1 elric krb5_principals spp,
745 1.1 elric const krb5_data *rspac,
746 1.1 elric const METHOD_DATA *enc_pa_data,
747 1.1 elric const char **e_text,
748 1.1 elric krb5_data *reply)
749 1.1 elric {
750 1.1 elric KDC_REP rep;
751 1.1 elric EncKDCRepPart ek;
752 1.1 elric EncTicketPart et;
753 1.1 elric KDCOptions f = b->kdc_options;
754 1.1 elric krb5_error_code ret;
755 1.1 elric int is_weak = 0;
756 1.1 elric
757 1.1 elric memset(&rep, 0, sizeof(rep));
758 1.1 elric memset(&et, 0, sizeof(et));
759 1.1 elric memset(&ek, 0, sizeof(ek));
760 1.1 elric
761 1.1 elric rep.pvno = 5;
762 1.1 elric rep.msg_type = krb_tgs_rep;
763 1.1 elric
764 1.1 elric et.authtime = tgt->authtime;
765 1.1 elric _kdc_fix_time(&b->till);
766 1.1 elric et.endtime = min(tgt->endtime, *b->till);
767 1.1 elric ALLOC(et.starttime);
768 1.1 elric *et.starttime = kdc_time;
769 1.1 elric
770 1.1 elric ret = check_tgs_flags(context, config, b, tgt, &et);
771 1.1 elric if(ret)
772 1.1 elric goto out;
773 1.1 elric
774 1.1 elric /* We should check the transited encoding if:
775 1.1 elric 1) the request doesn't ask not to be checked
776 1.1 elric 2) globally enforcing a check
777 1.1 elric 3) principal requires checking
778 1.1 elric 4) we allow non-check per-principal, but principal isn't marked as allowing this
779 1.1 elric 5) we don't globally allow this
780 1.1 elric */
781 1.1 elric
782 1.1 elric #define GLOBAL_FORCE_TRANSITED_CHECK \
783 1.1 elric (config->trpolicy == TRPOLICY_ALWAYS_CHECK)
784 1.1 elric #define GLOBAL_ALLOW_PER_PRINCIPAL \
785 1.1 elric (config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
786 1.1 elric #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK \
787 1.1 elric (config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
788 1.1 elric
789 1.1 elric /* these will consult the database in future release */
790 1.1 elric #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
791 1.1 elric #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
792 1.1 elric
793 1.1 elric ret = fix_transited_encoding(context, config,
794 1.1 elric !f.disable_transited_check ||
795 1.1 elric GLOBAL_FORCE_TRANSITED_CHECK ||
796 1.1 elric PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
797 1.1 elric !((GLOBAL_ALLOW_PER_PRINCIPAL &&
798 1.1 elric PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
799 1.1 elric GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
800 1.1 elric &tgt->transited, &et,
801 1.1 elric krb5_principal_get_realm(context, client_principal),
802 1.1 elric krb5_principal_get_realm(context, server->entry.principal),
803 1.1 elric krb5_principal_get_realm(context, krbtgt->entry.principal));
804 1.1 elric if(ret)
805 1.1 elric goto out;
806 1.1 elric
807 1.1 elric copy_Realm(&server_principal->realm, &rep.ticket.realm);
808 1.1 elric _krb5_principal2principalname(&rep.ticket.sname, server_principal);
809 1.1 elric copy_Realm(&tgt_name->realm, &rep.crealm);
810 1.1 elric /*
811 1.1 elric if (f.request_anonymous)
812 1.1 elric _kdc_make_anonymous_principalname (&rep.cname);
813 1.1 elric else */
814 1.1 elric
815 1.1 elric copy_PrincipalName(&tgt_name->name, &rep.cname);
816 1.1 elric rep.ticket.tkt_vno = 5;
817 1.1 elric
818 1.1 elric ek.caddr = et.caddr;
819 1.1 elric if(et.caddr == NULL)
820 1.1 elric et.caddr = tgt->caddr;
821 1.1 elric
822 1.1 elric {
823 1.1 elric time_t life;
824 1.1 elric life = et.endtime - *et.starttime;
825 1.1 elric if(client && client->entry.max_life)
826 1.1 elric life = min(life, *client->entry.max_life);
827 1.1 elric if(server->entry.max_life)
828 1.1 elric life = min(life, *server->entry.max_life);
829 1.1 elric et.endtime = *et.starttime + life;
830 1.1 elric }
831 1.1 elric if(f.renewable_ok && tgt->flags.renewable &&
832 1.1 elric et.renew_till == NULL && et.endtime < *b->till &&
833 1.1 elric tgt->renew_till != NULL)
834 1.1 elric {
835 1.1 elric et.flags.renewable = 1;
836 1.1 elric ALLOC(et.renew_till);
837 1.1 elric *et.renew_till = *b->till;
838 1.1 elric }
839 1.1 elric if(et.renew_till){
840 1.1 elric time_t renew;
841 1.1.1.1.4.1 yamt renew = *et.renew_till - *et.starttime;
842 1.1 elric if(client && client->entry.max_renew)
843 1.1 elric renew = min(renew, *client->entry.max_renew);
844 1.1 elric if(server->entry.max_renew)
845 1.1 elric renew = min(renew, *server->entry.max_renew);
846 1.1.1.1.4.1 yamt *et.renew_till = *et.starttime + renew;
847 1.1 elric }
848 1.1.1.1.4.1 yamt
849 1.1 elric if(et.renew_till){
850 1.1 elric *et.renew_till = min(*et.renew_till, *tgt->renew_till);
851 1.1 elric *et.starttime = min(*et.starttime, *et.renew_till);
852 1.1 elric et.endtime = min(et.endtime, *et.renew_till);
853 1.1 elric }
854 1.1 elric
855 1.1 elric *et.starttime = min(*et.starttime, et.endtime);
856 1.1 elric
857 1.1 elric if(*et.starttime == et.endtime){
858 1.1 elric ret = KRB5KDC_ERR_NEVER_VALID;
859 1.1 elric goto out;
860 1.1 elric }
861 1.1 elric if(et.renew_till && et.endtime == *et.renew_till){
862 1.1 elric free(et.renew_till);
863 1.1 elric et.renew_till = NULL;
864 1.1 elric et.flags.renewable = 0;
865 1.1 elric }
866 1.1 elric
867 1.1 elric et.flags.pre_authent = tgt->flags.pre_authent;
868 1.1 elric et.flags.hw_authent = tgt->flags.hw_authent;
869 1.1 elric et.flags.anonymous = tgt->flags.anonymous;
870 1.1 elric et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
871 1.1 elric
872 1.1 elric if(rspac->length) {
873 1.1 elric /*
874 1.1 elric * No not need to filter out the any PAC from the
875 1.1 elric * auth_data since it's signed by the KDC.
876 1.1 elric */
877 1.1 elric ret = _kdc_tkt_add_if_relevant_ad(context, &et,
878 1.1 elric KRB5_AUTHDATA_WIN2K_PAC, rspac);
879 1.1 elric if (ret)
880 1.1 elric goto out;
881 1.1 elric }
882 1.1.1.1.4.1 yamt
883 1.1 elric if (auth_data) {
884 1.1 elric unsigned int i = 0;
885 1.1 elric
886 1.1 elric /* XXX check authdata */
887 1.1 elric
888 1.1 elric if (et.authorization_data == NULL) {
889 1.1 elric et.authorization_data = calloc(1, sizeof(*et.authorization_data));
890 1.1 elric if (et.authorization_data == NULL) {
891 1.1 elric ret = ENOMEM;
892 1.1 elric krb5_set_error_message(context, ret, "malloc: out of memory");
893 1.1 elric goto out;
894 1.1 elric }
895 1.1 elric }
896 1.1 elric for(i = 0; i < auth_data->len ; i++) {
897 1.1 elric ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
898 1.1 elric if (ret) {
899 1.1 elric krb5_set_error_message(context, ret, "malloc: out of memory");
900 1.1 elric goto out;
901 1.1 elric }
902 1.1 elric }
903 1.1 elric
904 1.1 elric /* Filter out type KRB5SignedPath */
905 1.1 elric ret = find_KRB5SignedPath(context, et.authorization_data, NULL);
906 1.1 elric if (ret == 0) {
907 1.1 elric if (et.authorization_data->len == 1) {
908 1.1 elric free_AuthorizationData(et.authorization_data);
909 1.1 elric free(et.authorization_data);
910 1.1 elric et.authorization_data = NULL;
911 1.1 elric } else {
912 1.1 elric AuthorizationData *ad = et.authorization_data;
913 1.1 elric free_AuthorizationDataElement(&ad->val[ad->len - 1]);
914 1.1 elric ad->len--;
915 1.1 elric }
916 1.1 elric }
917 1.1 elric }
918 1.1 elric
919 1.1 elric ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key);
920 1.1 elric if (ret)
921 1.1 elric goto out;
922 1.1.1.1.4.1 yamt et.crealm = tgt_name->realm;
923 1.1 elric et.cname = tgt_name->name;
924 1.1.1.1.4.1 yamt
925 1.1 elric ek.key = et.key;
926 1.1 elric /* MIT must have at least one last_req */
927 1.1 elric ek.last_req.len = 1;
928 1.1 elric ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
929 1.1 elric if (ek.last_req.val == NULL) {
930 1.1 elric ret = ENOMEM;
931 1.1 elric goto out;
932 1.1 elric }
933 1.1 elric ek.nonce = b->nonce;
934 1.1 elric ek.flags = et.flags;
935 1.1 elric ek.authtime = et.authtime;
936 1.1 elric ek.starttime = et.starttime;
937 1.1 elric ek.endtime = et.endtime;
938 1.1 elric ek.renew_till = et.renew_till;
939 1.1 elric ek.srealm = rep.ticket.realm;
940 1.1 elric ek.sname = rep.ticket.sname;
941 1.1 elric
942 1.1 elric _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime,
943 1.1 elric et.endtime, et.renew_till);
944 1.1 elric
945 1.1 elric /* Don't sign cross realm tickets, they can't be checked anyway */
946 1.1 elric {
947 1.1 elric char *r = get_krbtgt_realm(&ek.sname);
948 1.1 elric
949 1.1 elric if (r == NULL || strcmp(r, ek.srealm) == 0) {
950 1.1 elric ret = _kdc_add_KRB5SignedPath(context,
951 1.1 elric config,
952 1.1 elric krbtgt,
953 1.1 elric krbtgt_etype,
954 1.1 elric client_principal,
955 1.1 elric NULL,
956 1.1 elric spp,
957 1.1 elric &et);
958 1.1 elric if (ret)
959 1.1 elric goto out;
960 1.1 elric }
961 1.1 elric }
962 1.1 elric
963 1.1 elric if (enc_pa_data->len) {
964 1.1 elric rep.padata = calloc(1, sizeof(*rep.padata));
965 1.1 elric if (rep.padata == NULL) {
966 1.1 elric ret = ENOMEM;
967 1.1 elric goto out;
968 1.1 elric }
969 1.1 elric ret = copy_METHOD_DATA(enc_pa_data, rep.padata);
970 1.1 elric if (ret)
971 1.1 elric goto out;
972 1.1 elric }
973 1.1 elric
974 1.1.1.1.4.1 yamt if (krb5_enctype_valid(context, serverkey->keytype) != 0
975 1.1.1.1.4.1 yamt && _kdc_is_weak_exception(server->entry.principal, serverkey->keytype))
976 1.1 elric {
977 1.1.1.1.4.1 yamt krb5_enctype_enable(context, serverkey->keytype);
978 1.1 elric is_weak = 1;
979 1.1 elric }
980 1.1 elric
981 1.1 elric
982 1.1 elric /* It is somewhat unclear where the etype in the following
983 1.1 elric encryption should come from. What we have is a session
984 1.1 elric key in the passed tgt, and a list of preferred etypes
985 1.1 elric *for the new ticket*. Should we pick the best possible
986 1.1 elric etype, given the keytype in the tgt, or should we look
987 1.1 elric at the etype list here as well? What if the tgt
988 1.1 elric session key is DES3 and we want a ticket with a (say)
989 1.1 elric CAST session key. Should the DES3 etype be added to the
990 1.1 elric etype list, even if we don't want a session key with
991 1.1 elric DES3? */
992 1.1 elric ret = _kdc_encode_reply(context, config,
993 1.1.1.1.4.1 yamt &rep, &et, &ek, serverkey->keytype,
994 1.1 elric kvno,
995 1.1 elric serverkey, 0, replykey, rk_is_subkey,
996 1.1 elric e_text, reply);
997 1.1 elric if (is_weak)
998 1.1.1.1.4.1 yamt krb5_enctype_disable(context, serverkey->keytype);
999 1.1 elric
1000 1.1 elric out:
1001 1.1 elric free_TGS_REP(&rep);
1002 1.1 elric free_TransitedEncoding(&et.transited);
1003 1.1 elric if(et.starttime)
1004 1.1 elric free(et.starttime);
1005 1.1 elric if(et.renew_till)
1006 1.1 elric free(et.renew_till);
1007 1.1 elric if(et.authorization_data) {
1008 1.1 elric free_AuthorizationData(et.authorization_data);
1009 1.1 elric free(et.authorization_data);
1010 1.1 elric }
1011 1.1 elric free_LastReq(&ek.last_req);
1012 1.1 elric memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
1013 1.1 elric free_EncryptionKey(&et.key);
1014 1.1 elric return ret;
1015 1.1 elric }
1016 1.1 elric
1017 1.1 elric static krb5_error_code
1018 1.1 elric tgs_check_authenticator(krb5_context context,
1019 1.1 elric krb5_kdc_configuration *config,
1020 1.1 elric krb5_auth_context ac,
1021 1.1 elric KDC_REQ_BODY *b,
1022 1.1 elric const char **e_text,
1023 1.1 elric krb5_keyblock *key)
1024 1.1 elric {
1025 1.1 elric krb5_authenticator auth;
1026 1.1.1.1.4.1 yamt size_t len = 0;
1027 1.1 elric unsigned char *buf;
1028 1.1 elric size_t buf_size;
1029 1.1 elric krb5_error_code ret;
1030 1.1 elric krb5_crypto crypto;
1031 1.1 elric
1032 1.1 elric krb5_auth_con_getauthenticator(context, ac, &auth);
1033 1.1 elric if(auth->cksum == NULL){
1034 1.1 elric kdc_log(context, config, 0, "No authenticator in request");
1035 1.1 elric ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1036 1.1 elric goto out;
1037 1.1 elric }
1038 1.1 elric /*
1039 1.1 elric * according to RFC1510 it doesn't need to be keyed,
1040 1.1 elric * but according to the latest draft it needs to.
1041 1.1 elric */
1042 1.1 elric if (
1043 1.1 elric #if 0
1044 1.1 elric !krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
1045 1.1 elric ||
1046 1.1 elric #endif
1047 1.1 elric !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
1048 1.1 elric kdc_log(context, config, 0, "Bad checksum type in authenticator: %d",
1049 1.1 elric auth->cksum->cksumtype);
1050 1.1 elric ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1051 1.1 elric goto out;
1052 1.1 elric }
1053 1.1.1.1.4.1 yamt
1054 1.1 elric /* XXX should not re-encode this */
1055 1.1 elric ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
1056 1.1 elric if(ret){
1057 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1058 1.1 elric kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", msg);
1059 1.1 elric krb5_free_error_message(context, msg);
1060 1.1 elric goto out;
1061 1.1 elric }
1062 1.1 elric if(buf_size != len) {
1063 1.1 elric free(buf);
1064 1.1 elric kdc_log(context, config, 0, "Internal error in ASN.1 encoder");
1065 1.1 elric *e_text = "KDC internal error";
1066 1.1 elric ret = KRB5KRB_ERR_GENERIC;
1067 1.1 elric goto out;
1068 1.1 elric }
1069 1.1 elric ret = krb5_crypto_init(context, key, 0, &crypto);
1070 1.1 elric if (ret) {
1071 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1072 1.1 elric free(buf);
1073 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
1074 1.1 elric krb5_free_error_message(context, msg);
1075 1.1 elric goto out;
1076 1.1 elric }
1077 1.1 elric ret = krb5_verify_checksum(context,
1078 1.1 elric crypto,
1079 1.1 elric KRB5_KU_TGS_REQ_AUTH_CKSUM,
1080 1.1 elric buf,
1081 1.1 elric len,
1082 1.1 elric auth->cksum);
1083 1.1 elric free(buf);
1084 1.1 elric krb5_crypto_destroy(context, crypto);
1085 1.1 elric if(ret){
1086 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1087 1.1 elric kdc_log(context, config, 0,
1088 1.1 elric "Failed to verify authenticator checksum: %s", msg);
1089 1.1 elric krb5_free_error_message(context, msg);
1090 1.1 elric }
1091 1.1 elric out:
1092 1.1 elric free_Authenticator(auth);
1093 1.1 elric free(auth);
1094 1.1 elric return ret;
1095 1.1 elric }
1096 1.1 elric
1097 1.1 elric /*
1098 1.1 elric *
1099 1.1 elric */
1100 1.1 elric
1101 1.1 elric static const char *
1102 1.1 elric find_rpath(krb5_context context, Realm crealm, Realm srealm)
1103 1.1 elric {
1104 1.1 elric const char *new_realm = krb5_config_get_string(context,
1105 1.1 elric NULL,
1106 1.1 elric "capaths",
1107 1.1 elric crealm,
1108 1.1 elric srealm,
1109 1.1 elric NULL);
1110 1.1 elric return new_realm;
1111 1.1 elric }
1112 1.1.1.1.4.1 yamt
1113 1.1 elric
1114 1.1 elric static krb5_boolean
1115 1.1 elric need_referral(krb5_context context, krb5_kdc_configuration *config,
1116 1.1 elric const KDCOptions * const options, krb5_principal server,
1117 1.1 elric krb5_realm **realms)
1118 1.1 elric {
1119 1.1 elric const char *name;
1120 1.1 elric
1121 1.1 elric if(!options->canonicalize && server->name.name_type != KRB5_NT_SRV_INST)
1122 1.1 elric return FALSE;
1123 1.1 elric
1124 1.1 elric if (server->name.name_string.len == 1)
1125 1.1 elric name = server->name.name_string.val[0];
1126 1.1 elric else if (server->name.name_string.len > 1)
1127 1.1 elric name = server->name.name_string.val[1];
1128 1.1 elric else
1129 1.1 elric return FALSE;
1130 1.1 elric
1131 1.1 elric kdc_log(context, config, 0, "Searching referral for %s", name);
1132 1.1 elric
1133 1.1 elric return _krb5_get_host_realm_int(context, name, FALSE, realms) == 0;
1134 1.1 elric }
1135 1.1 elric
1136 1.1 elric static krb5_error_code
1137 1.1 elric tgs_parse_request(krb5_context context,
1138 1.1 elric krb5_kdc_configuration *config,
1139 1.1 elric KDC_REQ_BODY *b,
1140 1.1 elric const PA_DATA *tgs_req,
1141 1.1 elric hdb_entry_ex **krbtgt,
1142 1.1 elric krb5_enctype *krbtgt_etype,
1143 1.1 elric krb5_ticket **ticket,
1144 1.1 elric const char **e_text,
1145 1.1 elric const char *from,
1146 1.1 elric const struct sockaddr *from_addr,
1147 1.1 elric time_t **csec,
1148 1.1 elric int **cusec,
1149 1.1 elric AuthorizationData **auth_data,
1150 1.1 elric krb5_keyblock **replykey,
1151 1.1 elric int *rk_is_subkey)
1152 1.1 elric {
1153 1.1.1.1.4.1 yamt static char failed[] = "<unparse_name failed>";
1154 1.1 elric krb5_ap_req ap_req;
1155 1.1 elric krb5_error_code ret;
1156 1.1 elric krb5_principal princ;
1157 1.1 elric krb5_auth_context ac = NULL;
1158 1.1 elric krb5_flags ap_req_options;
1159 1.1 elric krb5_flags verify_ap_req_flags;
1160 1.1 elric krb5_crypto crypto;
1161 1.1 elric Key *tkey;
1162 1.1 elric krb5_keyblock *subkey = NULL;
1163 1.1 elric unsigned usage;
1164 1.1 elric
1165 1.1 elric *auth_data = NULL;
1166 1.1 elric *csec = NULL;
1167 1.1 elric *cusec = NULL;
1168 1.1 elric *replykey = NULL;
1169 1.1 elric
1170 1.1 elric memset(&ap_req, 0, sizeof(ap_req));
1171 1.1 elric ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
1172 1.1 elric if(ret){
1173 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1174 1.1 elric kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", msg);
1175 1.1 elric krb5_free_error_message(context, msg);
1176 1.1 elric goto out;
1177 1.1 elric }
1178 1.1 elric
1179 1.1 elric if(!get_krbtgt_realm(&ap_req.ticket.sname)){
1180 1.1 elric /* XXX check for ticket.sname == req.sname */
1181 1.1 elric kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket");
1182 1.1 elric ret = KRB5KDC_ERR_POLICY; /* ? */
1183 1.1 elric goto out;
1184 1.1 elric }
1185 1.1 elric
1186 1.1 elric _krb5_principalname2krb5_principal(context,
1187 1.1 elric &princ,
1188 1.1 elric ap_req.ticket.sname,
1189 1.1 elric ap_req.ticket.realm);
1190 1.1 elric
1191 1.1 elric ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, ap_req.ticket.enc_part.kvno, NULL, krbtgt);
1192 1.1 elric
1193 1.1 elric if(ret == HDB_ERR_NOT_FOUND_HERE) {
1194 1.1 elric char *p;
1195 1.1 elric ret = krb5_unparse_name(context, princ, &p);
1196 1.1 elric if (ret != 0)
1197 1.1.1.1.4.1 yamt p = failed;
1198 1.1 elric krb5_free_principal(context, princ);
1199 1.1 elric kdc_log(context, config, 5, "Ticket-granting ticket account %s does not have secrets at this KDC, need to proxy", p);
1200 1.1 elric if (ret == 0)
1201 1.1 elric free(p);
1202 1.1 elric ret = HDB_ERR_NOT_FOUND_HERE;
1203 1.1 elric goto out;
1204 1.1 elric } else if(ret){
1205 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1206 1.1 elric char *p;
1207 1.1 elric ret = krb5_unparse_name(context, princ, &p);
1208 1.1 elric if (ret != 0)
1209 1.1.1.1.4.1 yamt p = failed;
1210 1.1 elric krb5_free_principal(context, princ);
1211 1.1 elric kdc_log(context, config, 0,
1212 1.1 elric "Ticket-granting ticket not found in database: %s", msg);
1213 1.1 elric krb5_free_error_message(context, msg);
1214 1.1 elric if (ret == 0)
1215 1.1 elric free(p);
1216 1.1 elric ret = KRB5KRB_AP_ERR_NOT_US;
1217 1.1 elric goto out;
1218 1.1 elric }
1219 1.1 elric
1220 1.1 elric if(ap_req.ticket.enc_part.kvno &&
1221 1.1 elric *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
1222 1.1 elric char *p;
1223 1.1 elric
1224 1.1 elric ret = krb5_unparse_name (context, princ, &p);
1225 1.1 elric krb5_free_principal(context, princ);
1226 1.1 elric if (ret != 0)
1227 1.1.1.1.4.1 yamt p = failed;
1228 1.1 elric kdc_log(context, config, 0,
1229 1.1 elric "Ticket kvno = %d, DB kvno = %d (%s)",
1230 1.1 elric *ap_req.ticket.enc_part.kvno,
1231 1.1 elric (*krbtgt)->entry.kvno,
1232 1.1 elric p);
1233 1.1 elric if (ret == 0)
1234 1.1 elric free (p);
1235 1.1 elric ret = KRB5KRB_AP_ERR_BADKEYVER;
1236 1.1 elric goto out;
1237 1.1 elric }
1238 1.1 elric
1239 1.1 elric *krbtgt_etype = ap_req.ticket.enc_part.etype;
1240 1.1 elric
1241 1.1 elric ret = hdb_enctype2key(context, &(*krbtgt)->entry,
1242 1.1 elric ap_req.ticket.enc_part.etype, &tkey);
1243 1.1 elric if(ret){
1244 1.1 elric char *str = NULL, *p = NULL;
1245 1.1 elric
1246 1.1 elric krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
1247 1.1 elric krb5_unparse_name(context, princ, &p);
1248 1.1 elric kdc_log(context, config, 0,
1249 1.1 elric "No server key with enctype %s found for %s",
1250 1.1 elric str ? str : "<unknown enctype>",
1251 1.1 elric p ? p : "<unparse_name failed>");
1252 1.1 elric free(str);
1253 1.1 elric free(p);
1254 1.1 elric ret = KRB5KRB_AP_ERR_BADKEYVER;
1255 1.1 elric goto out;
1256 1.1 elric }
1257 1.1 elric
1258 1.1 elric if (b->kdc_options.validate)
1259 1.1 elric verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
1260 1.1 elric else
1261 1.1 elric verify_ap_req_flags = 0;
1262 1.1 elric
1263 1.1 elric ret = krb5_verify_ap_req2(context,
1264 1.1 elric &ac,
1265 1.1 elric &ap_req,
1266 1.1 elric princ,
1267 1.1 elric &tkey->key,
1268 1.1 elric verify_ap_req_flags,
1269 1.1 elric &ap_req_options,
1270 1.1 elric ticket,
1271 1.1 elric KRB5_KU_TGS_REQ_AUTH);
1272 1.1.1.1.4.1 yamt
1273 1.1 elric krb5_free_principal(context, princ);
1274 1.1 elric if(ret) {
1275 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1276 1.1 elric kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", msg);
1277 1.1 elric krb5_free_error_message(context, msg);
1278 1.1 elric goto out;
1279 1.1 elric }
1280 1.1 elric
1281 1.1 elric {
1282 1.1 elric krb5_authenticator auth;
1283 1.1 elric
1284 1.1 elric ret = krb5_auth_con_getauthenticator(context, ac, &auth);
1285 1.1 elric if (ret == 0) {
1286 1.1 elric *csec = malloc(sizeof(**csec));
1287 1.1 elric if (*csec == NULL) {
1288 1.1 elric krb5_free_authenticator(context, &auth);
1289 1.1 elric kdc_log(context, config, 0, "malloc failed");
1290 1.1 elric goto out;
1291 1.1 elric }
1292 1.1 elric **csec = auth->ctime;
1293 1.1 elric *cusec = malloc(sizeof(**cusec));
1294 1.1 elric if (*cusec == NULL) {
1295 1.1 elric krb5_free_authenticator(context, &auth);
1296 1.1 elric kdc_log(context, config, 0, "malloc failed");
1297 1.1 elric goto out;
1298 1.1 elric }
1299 1.1 elric **cusec = auth->cusec;
1300 1.1 elric krb5_free_authenticator(context, &auth);
1301 1.1 elric }
1302 1.1 elric }
1303 1.1 elric
1304 1.1 elric ret = tgs_check_authenticator(context, config,
1305 1.1 elric ac, b, e_text, &(*ticket)->ticket.key);
1306 1.1 elric if (ret) {
1307 1.1 elric krb5_auth_con_free(context, ac);
1308 1.1 elric goto out;
1309 1.1 elric }
1310 1.1 elric
1311 1.1 elric usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
1312 1.1 elric *rk_is_subkey = 1;
1313 1.1 elric
1314 1.1 elric ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
1315 1.1 elric if(ret){
1316 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1317 1.1 elric krb5_auth_con_free(context, ac);
1318 1.1 elric kdc_log(context, config, 0, "Failed to get remote subkey: %s", msg);
1319 1.1 elric krb5_free_error_message(context, msg);
1320 1.1 elric goto out;
1321 1.1 elric }
1322 1.1 elric if(subkey == NULL){
1323 1.1 elric usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
1324 1.1 elric *rk_is_subkey = 0;
1325 1.1 elric
1326 1.1 elric ret = krb5_auth_con_getkey(context, ac, &subkey);
1327 1.1 elric if(ret) {
1328 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1329 1.1 elric krb5_auth_con_free(context, ac);
1330 1.1 elric kdc_log(context, config, 0, "Failed to get session key: %s", msg);
1331 1.1 elric krb5_free_error_message(context, msg);
1332 1.1 elric goto out;
1333 1.1 elric }
1334 1.1 elric }
1335 1.1 elric if(subkey == NULL){
1336 1.1 elric krb5_auth_con_free(context, ac);
1337 1.1 elric kdc_log(context, config, 0,
1338 1.1 elric "Failed to get key for enc-authorization-data");
1339 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1340 1.1 elric goto out;
1341 1.1 elric }
1342 1.1 elric
1343 1.1 elric *replykey = subkey;
1344 1.1 elric
1345 1.1 elric if (b->enc_authorization_data) {
1346 1.1 elric krb5_data ad;
1347 1.1 elric
1348 1.1 elric ret = krb5_crypto_init(context, subkey, 0, &crypto);
1349 1.1 elric if (ret) {
1350 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1351 1.1 elric krb5_auth_con_free(context, ac);
1352 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
1353 1.1 elric krb5_free_error_message(context, msg);
1354 1.1 elric goto out;
1355 1.1 elric }
1356 1.1 elric ret = krb5_decrypt_EncryptedData (context,
1357 1.1 elric crypto,
1358 1.1 elric usage,
1359 1.1 elric b->enc_authorization_data,
1360 1.1 elric &ad);
1361 1.1 elric krb5_crypto_destroy(context, crypto);
1362 1.1 elric if(ret){
1363 1.1 elric krb5_auth_con_free(context, ac);
1364 1.1 elric kdc_log(context, config, 0,
1365 1.1 elric "Failed to decrypt enc-authorization-data");
1366 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1367 1.1 elric goto out;
1368 1.1 elric }
1369 1.1 elric ALLOC(*auth_data);
1370 1.1 elric if (*auth_data == NULL) {
1371 1.1 elric krb5_auth_con_free(context, ac);
1372 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1373 1.1 elric goto out;
1374 1.1 elric }
1375 1.1 elric ret = decode_AuthorizationData(ad.data, ad.length, *auth_data, NULL);
1376 1.1 elric if(ret){
1377 1.1 elric krb5_auth_con_free(context, ac);
1378 1.1 elric free(*auth_data);
1379 1.1 elric *auth_data = NULL;
1380 1.1 elric kdc_log(context, config, 0, "Failed to decode authorization data");
1381 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1382 1.1 elric goto out;
1383 1.1 elric }
1384 1.1 elric }
1385 1.1 elric
1386 1.1 elric krb5_auth_con_free(context, ac);
1387 1.1 elric
1388 1.1 elric out:
1389 1.1 elric free_AP_REQ(&ap_req);
1390 1.1 elric
1391 1.1 elric return ret;
1392 1.1 elric }
1393 1.1 elric
1394 1.1 elric static krb5_error_code
1395 1.1 elric build_server_referral(krb5_context context,
1396 1.1 elric krb5_kdc_configuration *config,
1397 1.1 elric krb5_crypto session,
1398 1.1 elric krb5_const_realm referred_realm,
1399 1.1 elric const PrincipalName *true_principal_name,
1400 1.1 elric const PrincipalName *requested_principal,
1401 1.1 elric krb5_data *outdata)
1402 1.1.1.1.4.1 yamt {
1403 1.1 elric PA_ServerReferralData ref;
1404 1.1 elric krb5_error_code ret;
1405 1.1 elric EncryptedData ed;
1406 1.1 elric krb5_data data;
1407 1.1.1.1.4.1 yamt size_t size = 0;
1408 1.1 elric
1409 1.1 elric memset(&ref, 0, sizeof(ref));
1410 1.1 elric
1411 1.1 elric if (referred_realm) {
1412 1.1 elric ALLOC(ref.referred_realm);
1413 1.1 elric if (ref.referred_realm == NULL)
1414 1.1 elric goto eout;
1415 1.1 elric *ref.referred_realm = strdup(referred_realm);
1416 1.1 elric if (*ref.referred_realm == NULL)
1417 1.1 elric goto eout;
1418 1.1 elric }
1419 1.1 elric if (true_principal_name) {
1420 1.1 elric ALLOC(ref.true_principal_name);
1421 1.1 elric if (ref.true_principal_name == NULL)
1422 1.1 elric goto eout;
1423 1.1 elric ret = copy_PrincipalName(true_principal_name, ref.true_principal_name);
1424 1.1 elric if (ret)
1425 1.1 elric goto eout;
1426 1.1 elric }
1427 1.1 elric if (requested_principal) {
1428 1.1 elric ALLOC(ref.requested_principal_name);
1429 1.1 elric if (ref.requested_principal_name == NULL)
1430 1.1 elric goto eout;
1431 1.1 elric ret = copy_PrincipalName(requested_principal,
1432 1.1 elric ref.requested_principal_name);
1433 1.1 elric if (ret)
1434 1.1 elric goto eout;
1435 1.1 elric }
1436 1.1 elric
1437 1.1 elric ASN1_MALLOC_ENCODE(PA_ServerReferralData,
1438 1.1 elric data.data, data.length,
1439 1.1 elric &ref, &size, ret);
1440 1.1 elric free_PA_ServerReferralData(&ref);
1441 1.1 elric if (ret)
1442 1.1 elric return ret;
1443 1.1 elric if (data.length != size)
1444 1.1 elric krb5_abortx(context, "internal asn.1 encoder error");
1445 1.1 elric
1446 1.1 elric ret = krb5_encrypt_EncryptedData(context, session,
1447 1.1 elric KRB5_KU_PA_SERVER_REFERRAL,
1448 1.1 elric data.data, data.length,
1449 1.1 elric 0 /* kvno */, &ed);
1450 1.1 elric free(data.data);
1451 1.1 elric if (ret)
1452 1.1 elric return ret;
1453 1.1 elric
1454 1.1 elric ASN1_MALLOC_ENCODE(EncryptedData,
1455 1.1 elric outdata->data, outdata->length,
1456 1.1 elric &ed, &size, ret);
1457 1.1 elric free_EncryptedData(&ed);
1458 1.1 elric if (ret)
1459 1.1 elric return ret;
1460 1.1 elric if (outdata->length != size)
1461 1.1 elric krb5_abortx(context, "internal asn.1 encoder error");
1462 1.1 elric
1463 1.1 elric return 0;
1464 1.1 elric eout:
1465 1.1 elric free_PA_ServerReferralData(&ref);
1466 1.1 elric krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
1467 1.1 elric return ENOMEM;
1468 1.1 elric }
1469 1.1 elric
1470 1.1 elric static krb5_error_code
1471 1.1 elric tgs_build_reply(krb5_context context,
1472 1.1 elric krb5_kdc_configuration *config,
1473 1.1 elric KDC_REQ *req,
1474 1.1 elric KDC_REQ_BODY *b,
1475 1.1 elric hdb_entry_ex *krbtgt,
1476 1.1 elric krb5_enctype krbtgt_etype,
1477 1.1 elric const krb5_keyblock *replykey,
1478 1.1 elric int rk_is_subkey,
1479 1.1 elric krb5_ticket *ticket,
1480 1.1 elric krb5_data *reply,
1481 1.1 elric const char *from,
1482 1.1 elric const char **e_text,
1483 1.1 elric AuthorizationData **auth_data,
1484 1.1 elric const struct sockaddr *from_addr)
1485 1.1 elric {
1486 1.1 elric krb5_error_code ret;
1487 1.1.1.1.4.1 yamt krb5_principal cp = NULL, sp = NULL, rsp = NULL, tp = NULL, dp = NULL;
1488 1.1 elric krb5_principal krbtgt_principal = NULL;
1489 1.1.1.1.4.1 yamt char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL;
1490 1.1 elric hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
1491 1.1 elric HDB *clientdb, *s4u2self_impersonated_clientdb;
1492 1.1 elric krb5_realm ref_realm = NULL;
1493 1.1 elric EncTicketPart *tgt = &ticket->ticket;
1494 1.1 elric krb5_principals spp = NULL;
1495 1.1 elric const EncryptionKey *ekey;
1496 1.1 elric krb5_keyblock sessionkey;
1497 1.1 elric krb5_kvno kvno;
1498 1.1 elric krb5_data rspac;
1499 1.1 elric
1500 1.1 elric hdb_entry_ex *krbtgt_out = NULL;
1501 1.1 elric
1502 1.1 elric METHOD_DATA enc_pa_data;
1503 1.1 elric
1504 1.1 elric PrincipalName *s;
1505 1.1 elric Realm r;
1506 1.1 elric int nloop = 0;
1507 1.1 elric EncTicketPart adtkt;
1508 1.1 elric char opt_str[128];
1509 1.1 elric int signedpath = 0;
1510 1.1 elric
1511 1.1 elric Key *tkey_check;
1512 1.1 elric Key *tkey_sign;
1513 1.1.1.1.4.1 yamt int flags = HDB_F_FOR_TGS_REQ;
1514 1.1 elric
1515 1.1 elric memset(&sessionkey, 0, sizeof(sessionkey));
1516 1.1 elric memset(&adtkt, 0, sizeof(adtkt));
1517 1.1 elric krb5_data_zero(&rspac);
1518 1.1 elric memset(&enc_pa_data, 0, sizeof(enc_pa_data));
1519 1.1 elric
1520 1.1 elric s = b->sname;
1521 1.1 elric r = b->realm;
1522 1.1 elric
1523 1.1.1.1.4.1 yamt /*
1524 1.1.1.1.4.1 yamt * Always to do CANON, see comment below about returned server principal (rsp).
1525 1.1.1.1.4.1 yamt */
1526 1.1.1.1.4.1 yamt flags |= HDB_F_CANON;
1527 1.1.1.1.4.1 yamt
1528 1.1 elric if(b->kdc_options.enc_tkt_in_skey){
1529 1.1 elric Ticket *t;
1530 1.1 elric hdb_entry_ex *uu;
1531 1.1 elric krb5_principal p;
1532 1.1 elric Key *uukey;
1533 1.1.1.1.4.1 yamt
1534 1.1 elric if(b->additional_tickets == NULL ||
1535 1.1 elric b->additional_tickets->len == 0){
1536 1.1 elric ret = KRB5KDC_ERR_BADOPTION; /* ? */
1537 1.1 elric kdc_log(context, config, 0,
1538 1.1 elric "No second ticket present in request");
1539 1.1 elric goto out;
1540 1.1 elric }
1541 1.1 elric t = &b->additional_tickets->val[0];
1542 1.1 elric if(!get_krbtgt_realm(&t->sname)){
1543 1.1 elric kdc_log(context, config, 0,
1544 1.1 elric "Additional ticket is not a ticket-granting ticket");
1545 1.1 elric ret = KRB5KDC_ERR_POLICY;
1546 1.1 elric goto out;
1547 1.1 elric }
1548 1.1 elric _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
1549 1.1 elric ret = _kdc_db_fetch(context, config, p,
1550 1.1 elric HDB_F_GET_KRBTGT, t->enc_part.kvno,
1551 1.1 elric NULL, &uu);
1552 1.1 elric krb5_free_principal(context, p);
1553 1.1 elric if(ret){
1554 1.1 elric if (ret == HDB_ERR_NOENTRY)
1555 1.1 elric ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1556 1.1 elric goto out;
1557 1.1 elric }
1558 1.1 elric ret = hdb_enctype2key(context, &uu->entry,
1559 1.1 elric t->enc_part.etype, &uukey);
1560 1.1 elric if(ret){
1561 1.1 elric _kdc_free_ent(context, uu);
1562 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
1563 1.1 elric goto out;
1564 1.1 elric }
1565 1.1 elric ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0);
1566 1.1 elric _kdc_free_ent(context, uu);
1567 1.1 elric if(ret)
1568 1.1 elric goto out;
1569 1.1 elric
1570 1.1 elric ret = verify_flags(context, config, &adtkt, spn);
1571 1.1 elric if (ret)
1572 1.1 elric goto out;
1573 1.1 elric
1574 1.1 elric s = &adtkt.cname;
1575 1.1 elric r = adtkt.crealm;
1576 1.1 elric }
1577 1.1 elric
1578 1.1 elric _krb5_principalname2krb5_principal(context, &sp, *s, r);
1579 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, sp, &spn);
1580 1.1 elric if (ret)
1581 1.1 elric goto out;
1582 1.1 elric _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);
1583 1.1 elric ret = krb5_unparse_name(context, cp, &cpn);
1584 1.1 elric if (ret)
1585 1.1 elric goto out;
1586 1.1 elric unparse_flags (KDCOptions2int(b->kdc_options),
1587 1.1 elric asn1_KDCOptions_units(),
1588 1.1 elric opt_str, sizeof(opt_str));
1589 1.1 elric if(*opt_str)
1590 1.1 elric kdc_log(context, config, 0,
1591 1.1 elric "TGS-REQ %s from %s for %s [%s]",
1592 1.1 elric cpn, from, spn, opt_str);
1593 1.1 elric else
1594 1.1 elric kdc_log(context, config, 0,
1595 1.1 elric "TGS-REQ %s from %s for %s", cpn, from, spn);
1596 1.1 elric
1597 1.1 elric /*
1598 1.1 elric * Fetch server
1599 1.1 elric */
1600 1.1 elric
1601 1.1 elric server_lookup:
1602 1.1.1.1.4.1 yamt ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags,
1603 1.1 elric NULL, NULL, &server);
1604 1.1 elric
1605 1.1 elric if(ret == HDB_ERR_NOT_FOUND_HERE) {
1606 1.1 elric kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp);
1607 1.1 elric goto out;
1608 1.1 elric } else if(ret){
1609 1.1 elric const char *new_rlm, *msg;
1610 1.1 elric Realm req_rlm;
1611 1.1 elric krb5_realm *realms;
1612 1.1 elric
1613 1.1 elric if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
1614 1.1 elric if(nloop++ < 2) {
1615 1.1 elric new_rlm = find_rpath(context, tgt->crealm, req_rlm);
1616 1.1 elric if(new_rlm) {
1617 1.1 elric kdc_log(context, config, 5, "krbtgt for realm %s "
1618 1.1 elric "not found, trying %s",
1619 1.1 elric req_rlm, new_rlm);
1620 1.1 elric krb5_free_principal(context, sp);
1621 1.1 elric free(spn);
1622 1.1 elric krb5_make_principal(context, &sp, r,
1623 1.1 elric KRB5_TGS_NAME, new_rlm, NULL);
1624 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, sp, &spn);
1625 1.1 elric if (ret)
1626 1.1 elric goto out;
1627 1.1 elric
1628 1.1 elric if (ref_realm)
1629 1.1 elric free(ref_realm);
1630 1.1 elric ref_realm = strdup(new_rlm);
1631 1.1 elric goto server_lookup;
1632 1.1 elric }
1633 1.1 elric }
1634 1.1 elric } else if(need_referral(context, config, &b->kdc_options, sp, &realms)) {
1635 1.1 elric if (strcmp(realms[0], sp->realm) != 0) {
1636 1.1 elric kdc_log(context, config, 5,
1637 1.1 elric "Returning a referral to realm %s for "
1638 1.1 elric "server %s that was not found",
1639 1.1 elric realms[0], spn);
1640 1.1 elric krb5_free_principal(context, sp);
1641 1.1 elric free(spn);
1642 1.1 elric krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
1643 1.1 elric realms[0], NULL);
1644 1.1 elric ret = krb5_unparse_name(context, sp, &spn);
1645 1.1 elric if (ret)
1646 1.1 elric goto out;
1647 1.1 elric
1648 1.1 elric if (ref_realm)
1649 1.1 elric free(ref_realm);
1650 1.1 elric ref_realm = strdup(realms[0]);
1651 1.1 elric
1652 1.1 elric krb5_free_host_realm(context, realms);
1653 1.1 elric goto server_lookup;
1654 1.1 elric }
1655 1.1 elric krb5_free_host_realm(context, realms);
1656 1.1 elric }
1657 1.1 elric msg = krb5_get_error_message(context, ret);
1658 1.1 elric kdc_log(context, config, 0,
1659 1.1 elric "Server not found in database: %s: %s", spn, msg);
1660 1.1 elric krb5_free_error_message(context, msg);
1661 1.1 elric if (ret == HDB_ERR_NOENTRY)
1662 1.1 elric ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1663 1.1 elric goto out;
1664 1.1 elric }
1665 1.1 elric
1666 1.1.1.1.4.1 yamt /* the name returned to the client depend on what was asked for,
1667 1.1.1.1.4.1 yamt * return canonical name if kdc_options.canonicalize was set, the
1668 1.1.1.1.4.1 yamt * client wants the true name of the principal, if not it just
1669 1.1.1.1.4.1 yamt * wants the name its asked for.
1670 1.1.1.1.4.1 yamt */
1671 1.1.1.1.4.1 yamt
1672 1.1.1.1.4.1 yamt if (b->kdc_options.canonicalize)
1673 1.1.1.1.4.1 yamt rsp = server->entry.principal;
1674 1.1.1.1.4.1 yamt else
1675 1.1.1.1.4.1 yamt rsp = sp;
1676 1.1.1.1.4.1 yamt
1677 1.1.1.1.4.1 yamt
1678 1.1 elric /*
1679 1.1 elric * Select enctype, return key and kvno.
1680 1.1 elric */
1681 1.1 elric
1682 1.1 elric {
1683 1.1 elric krb5_enctype etype;
1684 1.1 elric
1685 1.1 elric if(b->kdc_options.enc_tkt_in_skey) {
1686 1.1.1.1.4.1 yamt size_t i;
1687 1.1 elric ekey = &adtkt.key;
1688 1.1 elric for(i = 0; i < b->etype.len; i++)
1689 1.1 elric if (b->etype.val[i] == adtkt.key.keytype)
1690 1.1 elric break;
1691 1.1 elric if(i == b->etype.len) {
1692 1.1 elric kdc_log(context, config, 0,
1693 1.1 elric "Addition ticket have not matching etypes");
1694 1.1 elric krb5_clear_error_message(context);
1695 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP;
1696 1.1 elric goto out;
1697 1.1 elric }
1698 1.1 elric etype = b->etype.val[i];
1699 1.1 elric kvno = 0;
1700 1.1 elric } else {
1701 1.1 elric Key *skey;
1702 1.1.1.1.4.1 yamt
1703 1.1.1.1.4.1 yamt ret = _kdc_find_etype(context,
1704 1.1.1.1.4.1 yamt krb5_principal_is_krbtgt(context, sp) ?
1705 1.1.1.1.4.1 yamt config->tgt_use_strongest_session_key :
1706 1.1.1.1.4.1 yamt config->svc_use_strongest_session_key, FALSE,
1707 1.1.1.1.4.1 yamt server, b->etype.val, b->etype.len, &etype,
1708 1.1.1.1.4.1 yamt NULL);
1709 1.1 elric if(ret) {
1710 1.1 elric kdc_log(context, config, 0,
1711 1.1 elric "Server (%s) has no support for etypes", spn);
1712 1.1 elric goto out;
1713 1.1 elric }
1714 1.1.1.1.4.1 yamt ret = _kdc_get_preferred_key(context, config, server, spn,
1715 1.1.1.1.4.1 yamt NULL, &skey);
1716 1.1.1.1.4.1 yamt if(ret) {
1717 1.1.1.1.4.1 yamt kdc_log(context, config, 0,
1718 1.1.1.1.4.1 yamt "Server (%s) has no supported etypes", spn);
1719 1.1.1.1.4.1 yamt goto out;
1720 1.1.1.1.4.1 yamt }
1721 1.1 elric ekey = &skey->key;
1722 1.1 elric kvno = server->entry.kvno;
1723 1.1 elric }
1724 1.1.1.1.4.1 yamt
1725 1.1 elric ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
1726 1.1 elric if (ret)
1727 1.1 elric goto out;
1728 1.1 elric }
1729 1.1 elric
1730 1.1 elric /*
1731 1.1 elric * Check that service is in the same realm as the krbtgt. If it's
1732 1.1 elric * not the same, it's someone that is using a uni-directional trust
1733 1.1 elric * backward.
1734 1.1 elric */
1735 1.1 elric
1736 1.1 elric /*
1737 1.1 elric * Validate authoriation data
1738 1.1 elric */
1739 1.1 elric
1740 1.1 elric ret = hdb_enctype2key(context, &krbtgt->entry,
1741 1.1 elric krbtgt_etype, &tkey_check);
1742 1.1 elric if(ret) {
1743 1.1 elric kdc_log(context, config, 0,
1744 1.1 elric "Failed to find key for krbtgt PAC check");
1745 1.1 elric goto out;
1746 1.1 elric }
1747 1.1 elric
1748 1.1 elric /* Now refetch the primary krbtgt, and get the current kvno (the
1749 1.1 elric * sign check may have been on an old kvno, and the server may
1750 1.1 elric * have been an incoming trust) */
1751 1.1.1.1.4.1 yamt ret = krb5_make_principal(context, &krbtgt_principal,
1752 1.1 elric krb5_principal_get_comp_string(context,
1753 1.1 elric krbtgt->entry.principal,
1754 1.1 elric 1),
1755 1.1.1.1.4.1 yamt KRB5_TGS_NAME,
1756 1.1 elric krb5_principal_get_comp_string(context,
1757 1.1 elric krbtgt->entry.principal,
1758 1.1 elric 1), NULL);
1759 1.1 elric if(ret) {
1760 1.1 elric kdc_log(context, config, 0,
1761 1.1 elric "Failed to generate krbtgt principal");
1762 1.1 elric goto out;
1763 1.1 elric }
1764 1.1 elric
1765 1.1 elric ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
1766 1.1 elric krb5_free_principal(context, krbtgt_principal);
1767 1.1 elric if (ret) {
1768 1.1 elric krb5_error_code ret2;
1769 1.1.1.1.4.1 yamt char *ktpn, *ktpn2;
1770 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
1771 1.1.1.1.4.1 yamt ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
1772 1.1 elric kdc_log(context, config, 0,
1773 1.1 elric "Request with wrong krbtgt: %s, %s not found in our database",
1774 1.1.1.1.4.1 yamt (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
1775 1.1 elric if(ret == 0)
1776 1.1.1.1.4.1 yamt free(ktpn);
1777 1.1 elric if(ret2 == 0)
1778 1.1.1.1.4.1 yamt free(ktpn2);
1779 1.1 elric ret = KRB5KRB_AP_ERR_NOT_US;
1780 1.1 elric goto out;
1781 1.1 elric }
1782 1.1 elric
1783 1.1 elric /* The first realm is the realm of the service, the second is
1784 1.1 elric * krbtgt/<this>/@REALM component of the krbtgt DN the request was
1785 1.1 elric * encrypted to. The redirection via the krbtgt_out entry allows
1786 1.1 elric * the DB to possibly correct the case of the realm (Samba4 does
1787 1.1 elric * this) before the strcmp() */
1788 1.1 elric if (strcmp(krb5_principal_get_realm(context, server->entry.principal),
1789 1.1 elric krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) {
1790 1.1.1.1.4.1 yamt char *ktpn;
1791 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn);
1792 1.1 elric kdc_log(context, config, 0,
1793 1.1 elric "Request with wrong krbtgt: %s",
1794 1.1.1.1.4.1 yamt (ret == 0) ? ktpn : "<unknown>");
1795 1.1 elric if(ret == 0)
1796 1.1.1.1.4.1 yamt free(ktpn);
1797 1.1 elric ret = KRB5KRB_AP_ERR_NOT_US;
1798 1.1 elric }
1799 1.1 elric
1800 1.1 elric ret = hdb_enctype2key(context, &krbtgt_out->entry,
1801 1.1 elric krbtgt_etype, &tkey_sign);
1802 1.1 elric if(ret) {
1803 1.1 elric kdc_log(context, config, 0,
1804 1.1 elric "Failed to find key for krbtgt PAC signature");
1805 1.1 elric goto out;
1806 1.1 elric }
1807 1.1 elric
1808 1.1.1.1.4.1 yamt ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags,
1809 1.1 elric NULL, &clientdb, &client);
1810 1.1 elric if(ret == HDB_ERR_NOT_FOUND_HERE) {
1811 1.1 elric /* This is OK, we are just trying to find out if they have
1812 1.1 elric * been disabled or deleted in the meantime, missing secrets
1813 1.1 elric * is OK */
1814 1.1 elric } else if(ret){
1815 1.1 elric const char *krbtgt_realm, *msg;
1816 1.1 elric
1817 1.1 elric /*
1818 1.1 elric * If the client belongs to the same realm as our krbtgt, it
1819 1.1 elric * should exist in the local database.
1820 1.1 elric *
1821 1.1 elric */
1822 1.1 elric
1823 1.1 elric krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal);
1824 1.1 elric
1825 1.1 elric if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {
1826 1.1 elric if (ret == HDB_ERR_NOENTRY)
1827 1.1 elric ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1828 1.1 elric kdc_log(context, config, 1, "Client no longer in database: %s",
1829 1.1 elric cpn);
1830 1.1 elric goto out;
1831 1.1 elric }
1832 1.1 elric
1833 1.1 elric msg = krb5_get_error_message(context, ret);
1834 1.1 elric kdc_log(context, config, 1, "Client not found in database: %s", msg);
1835 1.1 elric krb5_free_error_message(context, msg);
1836 1.1 elric }
1837 1.1 elric
1838 1.1.1.1.4.1 yamt ret = check_PAC(context, config, cp, NULL,
1839 1.1.1.1.4.1 yamt client, server, krbtgt,
1840 1.1.1.1.4.1 yamt &tkey_check->key, &tkey_check->key,
1841 1.1.1.1.4.1 yamt ekey, &tkey_sign->key,
1842 1.1 elric tgt, &rspac, &signedpath);
1843 1.1 elric if (ret) {
1844 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1845 1.1 elric kdc_log(context, config, 0,
1846 1.1 elric "Verify PAC failed for %s (%s) from %s with %s",
1847 1.1 elric spn, cpn, from, msg);
1848 1.1 elric krb5_free_error_message(context, msg);
1849 1.1 elric goto out;
1850 1.1 elric }
1851 1.1 elric
1852 1.1 elric /* also check the krbtgt for signature */
1853 1.1 elric ret = check_KRB5SignedPath(context,
1854 1.1 elric config,
1855 1.1 elric krbtgt,
1856 1.1 elric cp,
1857 1.1 elric tgt,
1858 1.1 elric &spp,
1859 1.1 elric &signedpath);
1860 1.1 elric if (ret) {
1861 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1862 1.1 elric kdc_log(context, config, 0,
1863 1.1 elric "KRB5SignedPath check failed for %s (%s) from %s with %s",
1864 1.1 elric spn, cpn, from, msg);
1865 1.1 elric krb5_free_error_message(context, msg);
1866 1.1 elric goto out;
1867 1.1 elric }
1868 1.1 elric
1869 1.1 elric /*
1870 1.1 elric * Process request
1871 1.1 elric */
1872 1.1 elric
1873 1.1.1.1.4.1 yamt /* by default the tgt principal matches the client principal */
1874 1.1.1.1.4.1 yamt tp = cp;
1875 1.1.1.1.4.1 yamt tpn = cpn;
1876 1.1 elric
1877 1.1 elric if (client) {
1878 1.1 elric const PA_DATA *sdata;
1879 1.1 elric int i = 0;
1880 1.1 elric
1881 1.1 elric sdata = _kdc_find_padata(req, &i, KRB5_PADATA_FOR_USER);
1882 1.1 elric if (sdata) {
1883 1.1 elric krb5_crypto crypto;
1884 1.1 elric krb5_data datack;
1885 1.1 elric PA_S4U2Self self;
1886 1.1 elric const char *str;
1887 1.1 elric
1888 1.1 elric ret = decode_PA_S4U2Self(sdata->padata_value.data,
1889 1.1 elric sdata->padata_value.length,
1890 1.1 elric &self, NULL);
1891 1.1 elric if (ret) {
1892 1.1 elric kdc_log(context, config, 0, "Failed to decode PA-S4U2Self");
1893 1.1 elric goto out;
1894 1.1 elric }
1895 1.1 elric
1896 1.1 elric ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);
1897 1.1 elric if (ret)
1898 1.1 elric goto out;
1899 1.1 elric
1900 1.1 elric ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
1901 1.1 elric if (ret) {
1902 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1903 1.1 elric free_PA_S4U2Self(&self);
1904 1.1 elric krb5_data_free(&datack);
1905 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
1906 1.1 elric krb5_free_error_message(context, msg);
1907 1.1 elric goto out;
1908 1.1 elric }
1909 1.1 elric
1910 1.1 elric ret = krb5_verify_checksum(context,
1911 1.1 elric crypto,
1912 1.1 elric KRB5_KU_OTHER_CKSUM,
1913 1.1 elric datack.data,
1914 1.1 elric datack.length,
1915 1.1 elric &self.cksum);
1916 1.1 elric krb5_data_free(&datack);
1917 1.1 elric krb5_crypto_destroy(context, crypto);
1918 1.1 elric if (ret) {
1919 1.1 elric const char *msg = krb5_get_error_message(context, ret);
1920 1.1 elric free_PA_S4U2Self(&self);
1921 1.1 elric kdc_log(context, config, 0,
1922 1.1 elric "krb5_verify_checksum failed for S4U2Self: %s", msg);
1923 1.1 elric krb5_free_error_message(context, msg);
1924 1.1 elric goto out;
1925 1.1 elric }
1926 1.1 elric
1927 1.1 elric ret = _krb5_principalname2krb5_principal(context,
1928 1.1.1.1.4.1 yamt &tp,
1929 1.1 elric self.name,
1930 1.1 elric self.realm);
1931 1.1 elric free_PA_S4U2Self(&self);
1932 1.1 elric if (ret)
1933 1.1 elric goto out;
1934 1.1 elric
1935 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, tp, &tpn);
1936 1.1 elric if (ret)
1937 1.1 elric goto out;
1938 1.1 elric
1939 1.1 elric /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */
1940 1.1 elric if(rspac.data) {
1941 1.1 elric krb5_pac p = NULL;
1942 1.1 elric krb5_data_free(&rspac);
1943 1.1.1.1.4.1 yamt ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
1944 1.1 elric NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
1945 1.1 elric if (ret) {
1946 1.1 elric const char *msg;
1947 1.1 elric
1948 1.1 elric /*
1949 1.1 elric * If the client belongs to the same realm as our krbtgt, it
1950 1.1 elric * should exist in the local database.
1951 1.1 elric *
1952 1.1 elric */
1953 1.1 elric
1954 1.1 elric if (ret == HDB_ERR_NOENTRY)
1955 1.1 elric ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1956 1.1 elric msg = krb5_get_error_message(context, ret);
1957 1.1.1.1.4.1 yamt kdc_log(context, config, 1,
1958 1.1.1.1.4.1 yamt "S2U4Self principal to impersonate %s not found in database: %s",
1959 1.1.1.1.4.1 yamt tpn, msg);
1960 1.1 elric krb5_free_error_message(context, msg);
1961 1.1 elric goto out;
1962 1.1 elric }
1963 1.1 elric ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
1964 1.1 elric if (ret) {
1965 1.1 elric kdc_log(context, config, 0, "PAC generation failed for -- %s",
1966 1.1.1.1.4.1 yamt tpn);
1967 1.1 elric goto out;
1968 1.1 elric }
1969 1.1 elric if (p != NULL) {
1970 1.1 elric ret = _krb5_pac_sign(context, p, ticket->ticket.authtime,
1971 1.1 elric s4u2self_impersonated_client->entry.principal,
1972 1.1 elric ekey, &tkey_sign->key,
1973 1.1 elric &rspac);
1974 1.1 elric krb5_pac_free(context, p);
1975 1.1 elric if (ret) {
1976 1.1 elric kdc_log(context, config, 0, "PAC signing failed for -- %s",
1977 1.1.1.1.4.1 yamt tpn);
1978 1.1 elric goto out;
1979 1.1 elric }
1980 1.1 elric }
1981 1.1 elric }
1982 1.1 elric
1983 1.1 elric /*
1984 1.1 elric * Check that service doing the impersonating is
1985 1.1 elric * requesting a ticket to it-self.
1986 1.1 elric */
1987 1.1 elric ret = check_s4u2self(context, config, clientdb, client, sp);
1988 1.1 elric if (ret) {
1989 1.1 elric kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
1990 1.1 elric "to impersonate to service "
1991 1.1 elric "(tried for user %s to service %s)",
1992 1.1.1.1.4.1 yamt cpn, tpn, spn);
1993 1.1 elric goto out;
1994 1.1 elric }
1995 1.1 elric
1996 1.1 elric /*
1997 1.1 elric * If the service isn't trusted for authentication to
1998 1.1 elric * delegation, remove the forward flag.
1999 1.1 elric */
2000 1.1 elric
2001 1.1 elric if (client->entry.flags.trusted_for_delegation) {
2002 1.1 elric str = "[forwardable]";
2003 1.1 elric } else {
2004 1.1 elric b->kdc_options.forwardable = 0;
2005 1.1 elric str = "";
2006 1.1 elric }
2007 1.1 elric kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
2008 1.1.1.1.4.1 yamt "service %s %s", cpn, tpn, spn, str);
2009 1.1 elric }
2010 1.1 elric }
2011 1.1 elric
2012 1.1 elric /*
2013 1.1 elric * Constrained delegation
2014 1.1 elric */
2015 1.1 elric
2016 1.1 elric if (client != NULL
2017 1.1 elric && b->additional_tickets != NULL
2018 1.1 elric && b->additional_tickets->len != 0
2019 1.1 elric && b->kdc_options.enc_tkt_in_skey == 0)
2020 1.1 elric {
2021 1.1 elric int ad_signedpath = 0;
2022 1.1 elric Key *clientkey;
2023 1.1 elric Ticket *t;
2024 1.1 elric
2025 1.1 elric /*
2026 1.1 elric * Require that the KDC have issued the service's krbtgt (not
2027 1.1 elric * self-issued ticket with kimpersonate(1).
2028 1.1 elric */
2029 1.1 elric if (!signedpath) {
2030 1.1 elric ret = KRB5KDC_ERR_BADOPTION;
2031 1.1 elric kdc_log(context, config, 0,
2032 1.1 elric "Constrained delegation done on service ticket %s/%s",
2033 1.1 elric cpn, spn);
2034 1.1 elric goto out;
2035 1.1 elric }
2036 1.1 elric
2037 1.1 elric t = &b->additional_tickets->val[0];
2038 1.1 elric
2039 1.1 elric ret = hdb_enctype2key(context, &client->entry,
2040 1.1 elric t->enc_part.etype, &clientkey);
2041 1.1 elric if(ret){
2042 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
2043 1.1 elric goto out;
2044 1.1 elric }
2045 1.1 elric
2046 1.1 elric ret = krb5_decrypt_ticket(context, t, &clientkey->key, &adtkt, 0);
2047 1.1 elric if (ret) {
2048 1.1 elric kdc_log(context, config, 0,
2049 1.1 elric "failed to decrypt ticket for "
2050 1.1 elric "constrained delegation from %s to %s ", cpn, spn);
2051 1.1 elric goto out;
2052 1.1 elric }
2053 1.1 elric
2054 1.1.1.1.4.1 yamt ret = _krb5_principalname2krb5_principal(context,
2055 1.1.1.1.4.1 yamt &tp,
2056 1.1.1.1.4.1 yamt adtkt.cname,
2057 1.1.1.1.4.1 yamt adtkt.crealm);
2058 1.1.1.1.4.1 yamt if (ret)
2059 1.1.1.1.4.1 yamt goto out;
2060 1.1.1.1.4.1 yamt
2061 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, tp, &tpn);
2062 1.1.1.1.4.1 yamt if (ret)
2063 1.1.1.1.4.1 yamt goto out;
2064 1.1.1.1.4.1 yamt
2065 1.1.1.1.4.1 yamt ret = _krb5_principalname2krb5_principal(context,
2066 1.1.1.1.4.1 yamt &dp,
2067 1.1.1.1.4.1 yamt t->sname,
2068 1.1.1.1.4.1 yamt t->realm);
2069 1.1.1.1.4.1 yamt if (ret)
2070 1.1.1.1.4.1 yamt goto out;
2071 1.1.1.1.4.1 yamt
2072 1.1.1.1.4.1 yamt ret = krb5_unparse_name(context, dp, &dpn);
2073 1.1.1.1.4.1 yamt if (ret)
2074 1.1.1.1.4.1 yamt goto out;
2075 1.1.1.1.4.1 yamt
2076 1.1 elric /* check that ticket is valid */
2077 1.1 elric if (adtkt.flags.forwardable == 0) {
2078 1.1 elric kdc_log(context, config, 0,
2079 1.1 elric "Missing forwardable flag on ticket for "
2080 1.1.1.1.4.1 yamt "constrained delegation from %s (%s) as %s to %s ",
2081 1.1.1.1.4.1 yamt cpn, dpn, tpn, spn);
2082 1.1 elric ret = KRB5KDC_ERR_BADOPTION;
2083 1.1 elric goto out;
2084 1.1 elric }
2085 1.1 elric
2086 1.1.1.1.4.1 yamt ret = check_constrained_delegation(context, config, clientdb,
2087 1.1.1.1.4.1 yamt client, server, sp);
2088 1.1 elric if (ret) {
2089 1.1 elric kdc_log(context, config, 0,
2090 1.1.1.1.4.1 yamt "constrained delegation from %s (%s) as %s to %s not allowed",
2091 1.1.1.1.4.1 yamt cpn, dpn, tpn, spn);
2092 1.1 elric goto out;
2093 1.1 elric }
2094 1.1 elric
2095 1.1.1.1.4.1 yamt ret = verify_flags(context, config, &adtkt, tpn);
2096 1.1.1.1.4.1 yamt if (ret) {
2097 1.1 elric goto out;
2098 1.1.1.1.4.1 yamt }
2099 1.1 elric
2100 1.1.1.1.4.1 yamt krb5_data_free(&rspac);
2101 1.1 elric
2102 1.1.1.1.4.1 yamt /*
2103 1.1.1.1.4.1 yamt * generate the PAC for the user.
2104 1.1.1.1.4.1 yamt *
2105 1.1.1.1.4.1 yamt * TODO: pass in t->sname and t->realm and build
2106 1.1.1.1.4.1 yamt * a S4U_DELEGATION_INFO blob to the PAC.
2107 1.1.1.1.4.1 yamt */
2108 1.1.1.1.4.1 yamt ret = check_PAC(context, config, tp, dp,
2109 1.1.1.1.4.1 yamt client, server, krbtgt,
2110 1.1.1.1.4.1 yamt &clientkey->key, &tkey_check->key,
2111 1.1.1.1.4.1 yamt ekey, &tkey_sign->key,
2112 1.1.1.1.4.1 yamt &adtkt, &rspac, &ad_signedpath);
2113 1.1 elric if (ret) {
2114 1.1.1.1.4.1 yamt const char *msg = krb5_get_error_message(context, ret);
2115 1.1.1.1.4.1 yamt kdc_log(context, config, 0,
2116 1.1.1.1.4.1 yamt "Verify delegated PAC failed to %s for client"
2117 1.1.1.1.4.1 yamt "%s (%s) as %s from %s with %s",
2118 1.1.1.1.4.1 yamt spn, cpn, dpn, tpn, from, msg);
2119 1.1.1.1.4.1 yamt krb5_free_error_message(context, msg);
2120 1.1 elric goto out;
2121 1.1 elric }
2122 1.1 elric
2123 1.1 elric /*
2124 1.1 elric * Check that the KDC issued the user's ticket.
2125 1.1 elric */
2126 1.1 elric ret = check_KRB5SignedPath(context,
2127 1.1 elric config,
2128 1.1 elric krbtgt,
2129 1.1 elric cp,
2130 1.1 elric &adtkt,
2131 1.1 elric NULL,
2132 1.1 elric &ad_signedpath);
2133 1.1 elric if (ret) {
2134 1.1 elric const char *msg = krb5_get_error_message(context, ret);
2135 1.1 elric kdc_log(context, config, 0,
2136 1.1 elric "KRB5SignedPath check from service %s failed "
2137 1.1.1.1.4.1 yamt "for delegation to %s for client %s (%s)"
2138 1.1 elric "from %s failed with %s",
2139 1.1.1.1.4.1 yamt spn, tpn, dpn, cpn, from, msg);
2140 1.1 elric krb5_free_error_message(context, msg);
2141 1.1.1.1.4.1 yamt goto out;
2142 1.1.1.1.4.1 yamt }
2143 1.1.1.1.4.1 yamt
2144 1.1.1.1.4.1 yamt if (!ad_signedpath) {
2145 1.1.1.1.4.1 yamt ret = KRB5KDC_ERR_BADOPTION;
2146 1.1.1.1.4.1 yamt kdc_log(context, config, 0,
2147 1.1.1.1.4.1 yamt "Ticket not signed with PAC nor SignedPath service %s failed "
2148 1.1.1.1.4.1 yamt "for delegation to %s for client %s (%s)"
2149 1.1.1.1.4.1 yamt "from %s",
2150 1.1.1.1.4.1 yamt spn, tpn, dpn, cpn, from);
2151 1.1 elric goto out;
2152 1.1 elric }
2153 1.1 elric
2154 1.1 elric kdc_log(context, config, 0, "constrained delegation for %s "
2155 1.1.1.1.4.1 yamt "from %s (%s) to %s", tpn, cpn, dpn, spn);
2156 1.1 elric }
2157 1.1 elric
2158 1.1 elric /*
2159 1.1 elric * Check flags
2160 1.1 elric */
2161 1.1 elric
2162 1.1 elric ret = kdc_check_flags(context, config,
2163 1.1 elric client, cpn,
2164 1.1 elric server, spn,
2165 1.1 elric FALSE);
2166 1.1 elric if(ret)
2167 1.1 elric goto out;
2168 1.1 elric
2169 1.1 elric if((b->kdc_options.validate || b->kdc_options.renew) &&
2170 1.1 elric !krb5_principal_compare(context,
2171 1.1 elric krbtgt->entry.principal,
2172 1.1 elric server->entry.principal)){
2173 1.1 elric kdc_log(context, config, 0, "Inconsistent request.");
2174 1.1 elric ret = KRB5KDC_ERR_SERVER_NOMATCH;
2175 1.1 elric goto out;
2176 1.1 elric }
2177 1.1 elric
2178 1.1 elric /* check for valid set of addresses */
2179 1.1 elric if(!_kdc_check_addresses(context, config, tgt->caddr, from_addr)) {
2180 1.1 elric ret = KRB5KRB_AP_ERR_BADADDR;
2181 1.1 elric kdc_log(context, config, 0, "Request from wrong address");
2182 1.1 elric goto out;
2183 1.1 elric }
2184 1.1.1.1.4.1 yamt
2185 1.1 elric /*
2186 1.1 elric * If this is an referral, add server referral data to the
2187 1.1 elric * auth_data reply .
2188 1.1 elric */
2189 1.1 elric if (ref_realm) {
2190 1.1 elric PA_DATA pa;
2191 1.1 elric krb5_crypto crypto;
2192 1.1 elric
2193 1.1 elric kdc_log(context, config, 0,
2194 1.1 elric "Adding server referral to %s", ref_realm);
2195 1.1 elric
2196 1.1 elric ret = krb5_crypto_init(context, &sessionkey, 0, &crypto);
2197 1.1 elric if (ret)
2198 1.1 elric goto out;
2199 1.1 elric
2200 1.1 elric ret = build_server_referral(context, config, crypto, ref_realm,
2201 1.1 elric NULL, s, &pa.padata_value);
2202 1.1 elric krb5_crypto_destroy(context, crypto);
2203 1.1 elric if (ret) {
2204 1.1 elric kdc_log(context, config, 0,
2205 1.1 elric "Failed building server referral");
2206 1.1 elric goto out;
2207 1.1 elric }
2208 1.1 elric pa.padata_type = KRB5_PADATA_SERVER_REFERRAL;
2209 1.1 elric
2210 1.1 elric ret = add_METHOD_DATA(&enc_pa_data, &pa);
2211 1.1 elric krb5_data_free(&pa.padata_value);
2212 1.1 elric if (ret) {
2213 1.1 elric kdc_log(context, config, 0,
2214 1.1 elric "Add server referral METHOD-DATA failed");
2215 1.1 elric goto out;
2216 1.1 elric }
2217 1.1 elric }
2218 1.1 elric
2219 1.1 elric /*
2220 1.1 elric *
2221 1.1 elric */
2222 1.1 elric
2223 1.1 elric ret = tgs_make_reply(context,
2224 1.1 elric config,
2225 1.1 elric b,
2226 1.1.1.1.4.1 yamt tp,
2227 1.1 elric tgt,
2228 1.1 elric replykey,
2229 1.1 elric rk_is_subkey,
2230 1.1 elric ekey,
2231 1.1 elric &sessionkey,
2232 1.1 elric kvno,
2233 1.1 elric *auth_data,
2234 1.1 elric server,
2235 1.1.1.1.4.1 yamt rsp,
2236 1.1 elric spn,
2237 1.1 elric client,
2238 1.1 elric cp,
2239 1.1 elric krbtgt_out,
2240 1.1 elric krbtgt_etype,
2241 1.1 elric spp,
2242 1.1 elric &rspac,
2243 1.1 elric &enc_pa_data,
2244 1.1 elric e_text,
2245 1.1 elric reply);
2246 1.1.1.1.4.1 yamt
2247 1.1 elric out:
2248 1.1.1.1.4.1 yamt if (tpn != cpn)
2249 1.1.1.1.4.1 yamt free(tpn);
2250 1.1 elric free(spn);
2251 1.1 elric free(cpn);
2252 1.1.1.1.4.1 yamt if (dpn)
2253 1.1.1.1.4.1 yamt free(dpn);
2254 1.1.1.1.4.1 yamt
2255 1.1 elric krb5_data_free(&rspac);
2256 1.1 elric krb5_free_keyblock_contents(context, &sessionkey);
2257 1.1 elric if(krbtgt_out)
2258 1.1 elric _kdc_free_ent(context, krbtgt_out);
2259 1.1 elric if(server)
2260 1.1 elric _kdc_free_ent(context, server);
2261 1.1 elric if(client)
2262 1.1 elric _kdc_free_ent(context, client);
2263 1.1 elric if(s4u2self_impersonated_client)
2264 1.1 elric _kdc_free_ent(context, s4u2self_impersonated_client);
2265 1.1 elric
2266 1.1.1.1.4.1 yamt if (tp && tp != cp)
2267 1.1.1.1.4.1 yamt krb5_free_principal(context, tp);
2268 1.1 elric if (cp)
2269 1.1 elric krb5_free_principal(context, cp);
2270 1.1.1.1.4.1 yamt if (dp)
2271 1.1.1.1.4.1 yamt krb5_free_principal(context, dp);
2272 1.1 elric if (sp)
2273 1.1 elric krb5_free_principal(context, sp);
2274 1.1 elric if (ref_realm)
2275 1.1 elric free(ref_realm);
2276 1.1 elric free_METHOD_DATA(&enc_pa_data);
2277 1.1 elric
2278 1.1 elric free_EncTicketPart(&adtkt);
2279 1.1 elric
2280 1.1 elric return ret;
2281 1.1 elric }
2282 1.1 elric
2283 1.1 elric /*
2284 1.1 elric *
2285 1.1 elric */
2286 1.1 elric
2287 1.1 elric krb5_error_code
2288 1.1 elric _kdc_tgs_rep(krb5_context context,
2289 1.1 elric krb5_kdc_configuration *config,
2290 1.1 elric KDC_REQ *req,
2291 1.1 elric krb5_data *data,
2292 1.1 elric const char *from,
2293 1.1 elric struct sockaddr *from_addr,
2294 1.1 elric int datagram_reply)
2295 1.1 elric {
2296 1.1 elric AuthorizationData *auth_data = NULL;
2297 1.1 elric krb5_error_code ret;
2298 1.1 elric int i = 0;
2299 1.1 elric const PA_DATA *tgs_req;
2300 1.1 elric
2301 1.1 elric hdb_entry_ex *krbtgt = NULL;
2302 1.1 elric krb5_ticket *ticket = NULL;
2303 1.1 elric const char *e_text = NULL;
2304 1.1 elric krb5_enctype krbtgt_etype = ETYPE_NULL;
2305 1.1 elric
2306 1.1 elric krb5_keyblock *replykey = NULL;
2307 1.1 elric int rk_is_subkey = 0;
2308 1.1 elric time_t *csec = NULL;
2309 1.1 elric int *cusec = NULL;
2310 1.1 elric
2311 1.1 elric if(req->padata == NULL){
2312 1.1 elric ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
2313 1.1 elric kdc_log(context, config, 0,
2314 1.1 elric "TGS-REQ from %s without PA-DATA", from);
2315 1.1 elric goto out;
2316 1.1 elric }
2317 1.1 elric
2318 1.1 elric tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ);
2319 1.1 elric
2320 1.1 elric if(tgs_req == NULL){
2321 1.1 elric ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
2322 1.1.1.1.4.1 yamt
2323 1.1 elric kdc_log(context, config, 0,
2324 1.1 elric "TGS-REQ from %s without PA-TGS-REQ", from);
2325 1.1 elric goto out;
2326 1.1 elric }
2327 1.1 elric ret = tgs_parse_request(context, config,
2328 1.1 elric &req->req_body, tgs_req,
2329 1.1 elric &krbtgt,
2330 1.1 elric &krbtgt_etype,
2331 1.1 elric &ticket,
2332 1.1 elric &e_text,
2333 1.1 elric from, from_addr,
2334 1.1 elric &csec, &cusec,
2335 1.1 elric &auth_data,
2336 1.1 elric &replykey,
2337 1.1 elric &rk_is_subkey);
2338 1.1 elric if (ret == HDB_ERR_NOT_FOUND_HERE) {
2339 1.1 elric /* kdc_log() is called in tgs_parse_request() */
2340 1.1 elric goto out;
2341 1.1 elric }
2342 1.1 elric if (ret) {
2343 1.1 elric kdc_log(context, config, 0,
2344 1.1 elric "Failed parsing TGS-REQ from %s", from);
2345 1.1 elric goto out;
2346 1.1 elric }
2347 1.1 elric
2348 1.1 elric ret = tgs_build_reply(context,
2349 1.1 elric config,
2350 1.1 elric req,
2351 1.1 elric &req->req_body,
2352 1.1 elric krbtgt,
2353 1.1 elric krbtgt_etype,
2354 1.1 elric replykey,
2355 1.1 elric rk_is_subkey,
2356 1.1 elric ticket,
2357 1.1 elric data,
2358 1.1 elric from,
2359 1.1 elric &e_text,
2360 1.1 elric &auth_data,
2361 1.1 elric from_addr);
2362 1.1 elric if (ret) {
2363 1.1 elric kdc_log(context, config, 0,
2364 1.1 elric "Failed building TGS-REP to %s", from);
2365 1.1 elric goto out;
2366 1.1 elric }
2367 1.1 elric
2368 1.1 elric /* */
2369 1.1 elric if (datagram_reply && data->length > config->max_datagram_reply_length) {
2370 1.1 elric krb5_data_free(data);
2371 1.1 elric ret = KRB5KRB_ERR_RESPONSE_TOO_BIG;
2372 1.1 elric e_text = "Reply packet too large";
2373 1.1 elric }
2374 1.1 elric
2375 1.1 elric out:
2376 1.1 elric if (replykey)
2377 1.1 elric krb5_free_keyblock(context, replykey);
2378 1.1 elric if(ret && ret != HDB_ERR_NOT_FOUND_HERE && data->data == NULL){
2379 1.1 elric krb5_mk_error(context,
2380 1.1 elric ret,
2381 1.1 elric NULL,
2382 1.1 elric NULL,
2383 1.1 elric NULL,
2384 1.1 elric NULL,
2385 1.1 elric csec,
2386 1.1 elric cusec,
2387 1.1 elric data);
2388 1.1 elric ret = 0;
2389 1.1 elric }
2390 1.1 elric free(csec);
2391 1.1 elric free(cusec);
2392 1.1 elric if (ticket)
2393 1.1 elric krb5_free_ticket(context, ticket);
2394 1.1 elric if(krbtgt)
2395 1.1 elric _kdc_free_ent(context, krbtgt);
2396 1.1 elric
2397 1.1 elric if (auth_data) {
2398 1.1 elric free_AuthorizationData(auth_data);
2399 1.1 elric free(auth_data);
2400 1.1 elric }
2401 1.1 elric
2402 1.1 elric return ret;
2403 1.1 elric }
2404