1 1.1 elric /* $NetBSD: krb5tgs.c,v 1.4 2023/06/19 21:41:41 christos 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.2 christos 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.3 christos krb5_const_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.2 christos 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.2 christos 129 1.3 christos spd.client = rk_UNCONST(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.2 christos 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.2 christos ret = hdb_enctype2key(context, &krbtgt->entry, NULL, 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.2 christos 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.2 christos ret = hdb_enctype2key(context, &krbtgt->entry, NULL, /* XXX use correct kvno! */ 232 1.2 christos sp.etype, &key); 233 1.1 elric if (ret == 0) 234 1.1 elric ret = krb5_crypto_init(context, &key->key, 0, &crypto); 235 1.1 elric if (ret) { 236 1.1 elric free(data.data); 237 1.1 elric free_KRB5SignedPath(&sp); 238 1.1 elric return ret; 239 1.1 elric } 240 1.1 elric } 241 1.1 elric ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 242 1.1 elric data.data, data.length, 243 1.1 elric &sp.cksum); 244 1.1 elric krb5_crypto_destroy(context, crypto); 245 1.1 elric free(data.data); 246 1.1 elric if (ret) { 247 1.1 elric free_KRB5SignedPath(&sp); 248 1.1 elric kdc_log(context, config, 5, 249 1.1 elric "KRB5SignedPath not signed correctly, not marking as signed"); 250 1.1 elric return 0; 251 1.1 elric } 252 1.1 elric 253 1.1 elric if (delegated && sp.delegated) { 254 1.1 elric 255 1.1 elric *delegated = malloc(sizeof(*sp.delegated)); 256 1.1 elric if (*delegated == NULL) { 257 1.1 elric free_KRB5SignedPath(&sp); 258 1.1 elric return ENOMEM; 259 1.1 elric } 260 1.1 elric 261 1.1 elric ret = copy_Principals(*delegated, sp.delegated); 262 1.1 elric if (ret) { 263 1.1 elric free_KRB5SignedPath(&sp); 264 1.1 elric free(*delegated); 265 1.1 elric *delegated = NULL; 266 1.1 elric return ret; 267 1.1 elric } 268 1.1 elric } 269 1.1 elric free_KRB5SignedPath(&sp); 270 1.1 elric 271 1.1 elric *signedpath = 1; 272 1.1 elric } 273 1.1 elric 274 1.1 elric return 0; 275 1.1 elric } 276 1.1 elric 277 1.1 elric /* 278 1.1 elric * 279 1.1 elric */ 280 1.1 elric 281 1.1 elric static krb5_error_code 282 1.1 elric check_PAC(krb5_context context, 283 1.1 elric krb5_kdc_configuration *config, 284 1.1 elric const krb5_principal client_principal, 285 1.2 christos const krb5_principal delegated_proxy_principal, 286 1.1 elric hdb_entry_ex *client, 287 1.1 elric hdb_entry_ex *server, 288 1.1 elric hdb_entry_ex *krbtgt, 289 1.2 christos const EncryptionKey *server_check_key, 290 1.2 christos 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.2 christos server_check_key, NULL); 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.2 christos 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.2 christos server_sign_key, krbtgt_sign_key, rspac); 360 1.1 elric } 361 1.1 elric krb5_pac_free(context, pac); 362 1.2 christos 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.3 christos static krb5_boolean 372 1.3 christos is_anon_tgs_request_p(const KDC_REQ_BODY *b, 373 1.3 christos const EncTicketPart *tgt) 374 1.3 christos { 375 1.3 christos KDCOptions f = b->kdc_options; 376 1.3 christos 377 1.3 christos /* 378 1.3 christos * Versions of Heimdal from 1.0 to 7.6, inclusive, send both the 379 1.3 christos * request-anonymous and cname-in-addl-tkt flags for constrained 380 1.3 christos * delegation requests. A true anonymous TGS request will only 381 1.3 christos * have the request-anonymous flag set. (A corollary of this is 382 1.3 christos * that it is not possible to support anonymous constrained 383 1.3 christos * delegation requests, although they would be of limited utility.) 384 1.3 christos */ 385 1.3 christos return tgt->flags.anonymous || 386 1.3 christos (f.request_anonymous && !f.cname_in_addl_tkt && !b->additional_tickets); 387 1.3 christos } 388 1.3 christos 389 1.1 elric /* 390 1.1 elric * 391 1.1 elric */ 392 1.1 elric 393 1.1 elric static krb5_error_code 394 1.1 elric check_tgs_flags(krb5_context context, 395 1.1 elric krb5_kdc_configuration *config, 396 1.3 christos KDC_REQ_BODY *b, 397 1.3 christos krb5_const_principal tgt_name, 398 1.3 christos const EncTicketPart *tgt, 399 1.3 christos EncTicketPart *et) 400 1.1 elric { 401 1.1 elric KDCOptions f = b->kdc_options; 402 1.2 christos 403 1.1 elric if(f.validate){ 404 1.1 elric if(!tgt->flags.invalid || tgt->starttime == NULL){ 405 1.1 elric kdc_log(context, config, 0, 406 1.1 elric "Bad request to validate ticket"); 407 1.1 elric return KRB5KDC_ERR_BADOPTION; 408 1.1 elric } 409 1.1 elric if(*tgt->starttime > kdc_time){ 410 1.1 elric kdc_log(context, config, 0, 411 1.1 elric "Early request to validate ticket"); 412 1.1 elric return KRB5KRB_AP_ERR_TKT_NYV; 413 1.1 elric } 414 1.1 elric /* XXX tkt = tgt */ 415 1.1 elric et->flags.invalid = 0; 416 1.1 elric }else if(tgt->flags.invalid){ 417 1.1 elric kdc_log(context, config, 0, 418 1.1 elric "Ticket-granting ticket has INVALID flag set"); 419 1.1 elric return KRB5KRB_AP_ERR_TKT_INVALID; 420 1.1 elric } 421 1.1 elric 422 1.1 elric if(f.forwardable){ 423 1.1 elric if(!tgt->flags.forwardable){ 424 1.1 elric kdc_log(context, config, 0, 425 1.1 elric "Bad request for forwardable ticket"); 426 1.1 elric return KRB5KDC_ERR_BADOPTION; 427 1.1 elric } 428 1.1 elric et->flags.forwardable = 1; 429 1.1 elric } 430 1.1 elric if(f.forwarded){ 431 1.1 elric if(!tgt->flags.forwardable){ 432 1.1 elric kdc_log(context, config, 0, 433 1.1 elric "Request to forward non-forwardable ticket"); 434 1.1 elric return KRB5KDC_ERR_BADOPTION; 435 1.1 elric } 436 1.1 elric et->flags.forwarded = 1; 437 1.1 elric et->caddr = b->addresses; 438 1.1 elric } 439 1.1 elric if(tgt->flags.forwarded) 440 1.1 elric et->flags.forwarded = 1; 441 1.2 christos 442 1.1 elric if(f.proxiable){ 443 1.1 elric if(!tgt->flags.proxiable){ 444 1.1 elric kdc_log(context, config, 0, 445 1.1 elric "Bad request for proxiable ticket"); 446 1.1 elric return KRB5KDC_ERR_BADOPTION; 447 1.1 elric } 448 1.1 elric et->flags.proxiable = 1; 449 1.1 elric } 450 1.1 elric if(f.proxy){ 451 1.1 elric if(!tgt->flags.proxiable){ 452 1.1 elric kdc_log(context, config, 0, 453 1.1 elric "Request to proxy non-proxiable ticket"); 454 1.1 elric return KRB5KDC_ERR_BADOPTION; 455 1.1 elric } 456 1.1 elric et->flags.proxy = 1; 457 1.1 elric et->caddr = b->addresses; 458 1.1 elric } 459 1.1 elric if(tgt->flags.proxy) 460 1.1 elric et->flags.proxy = 1; 461 1.1 elric 462 1.1 elric if(f.allow_postdate){ 463 1.1 elric if(!tgt->flags.may_postdate){ 464 1.1 elric kdc_log(context, config, 0, 465 1.1 elric "Bad request for post-datable ticket"); 466 1.1 elric return KRB5KDC_ERR_BADOPTION; 467 1.1 elric } 468 1.1 elric et->flags.may_postdate = 1; 469 1.1 elric } 470 1.1 elric if(f.postdated){ 471 1.1 elric if(!tgt->flags.may_postdate){ 472 1.1 elric kdc_log(context, config, 0, 473 1.1 elric "Bad request for postdated ticket"); 474 1.1 elric return KRB5KDC_ERR_BADOPTION; 475 1.1 elric } 476 1.1 elric if(b->from) 477 1.1 elric *et->starttime = *b->from; 478 1.1 elric et->flags.postdated = 1; 479 1.1 elric et->flags.invalid = 1; 480 1.1 elric }else if(b->from && *b->from > kdc_time + context->max_skew){ 481 1.1 elric kdc_log(context, config, 0, "Ticket cannot be postdated"); 482 1.1 elric return KRB5KDC_ERR_CANNOT_POSTDATE; 483 1.1 elric } 484 1.1 elric 485 1.1 elric if(f.renewable){ 486 1.1 elric if(!tgt->flags.renewable || tgt->renew_till == NULL){ 487 1.1 elric kdc_log(context, config, 0, 488 1.1 elric "Bad request for renewable ticket"); 489 1.1 elric return KRB5KDC_ERR_BADOPTION; 490 1.1 elric } 491 1.1 elric et->flags.renewable = 1; 492 1.1 elric ALLOC(et->renew_till); 493 1.1 elric _kdc_fix_time(&b->rtime); 494 1.1 elric *et->renew_till = *b->rtime; 495 1.1 elric } 496 1.1 elric if(f.renew){ 497 1.1 elric time_t old_life; 498 1.1 elric if(!tgt->flags.renewable || tgt->renew_till == NULL){ 499 1.1 elric kdc_log(context, config, 0, 500 1.1 elric "Request to renew non-renewable ticket"); 501 1.1 elric return KRB5KDC_ERR_BADOPTION; 502 1.1 elric } 503 1.1 elric old_life = tgt->endtime; 504 1.1 elric if(tgt->starttime) 505 1.1 elric old_life -= *tgt->starttime; 506 1.1 elric else 507 1.1 elric old_life -= tgt->authtime; 508 1.1 elric et->endtime = *et->starttime + old_life; 509 1.1 elric if (et->renew_till != NULL) 510 1.1 elric et->endtime = min(*et->renew_till, et->endtime); 511 1.2 christos } 512 1.1 elric 513 1.3 christos /* 514 1.3 christos * RFC 8062 section 3 defines an anonymous ticket as one containing 515 1.3 christos * the anonymous principal and the anonymous ticket flag. 516 1.3 christos */ 517 1.3 christos if (tgt->flags.anonymous && 518 1.3 christos !_kdc_is_anonymous(context, tgt_name)) { 519 1.1 elric kdc_log(context, config, 0, 520 1.3 christos "Anonymous ticket flag set without anonymous principal"); 521 1.1 elric return KRB5KDC_ERR_BADOPTION; 522 1.1 elric } 523 1.3 christos 524 1.3 christos /* 525 1.3 christos * RFC 8062 section 4.2 states that if the TGT is anonymous, the 526 1.3 christos * anonymous KDC option SHOULD be set, but it is not required. 527 1.3 christos * Treat an anonymous TGT as if the anonymous flag was set. 528 1.3 christos */ 529 1.3 christos if (is_anon_tgs_request_p(b, tgt)) 530 1.3 christos et->flags.anonymous = 1; 531 1.3 christos 532 1.1 elric return 0; 533 1.1 elric } 534 1.1 elric 535 1.1 elric /* 536 1.1 elric * Determine if constrained delegation is allowed from this client to this server 537 1.1 elric */ 538 1.1 elric 539 1.1 elric static krb5_error_code 540 1.1 elric check_constrained_delegation(krb5_context context, 541 1.1 elric krb5_kdc_configuration *config, 542 1.1 elric HDB *clientdb, 543 1.1 elric hdb_entry_ex *client, 544 1.2 christos hdb_entry_ex *server, 545 1.2 christos krb5_const_principal target) 546 1.1 elric { 547 1.1 elric const HDB_Ext_Constrained_delegation_acl *acl; 548 1.1 elric krb5_error_code ret; 549 1.2 christos size_t i; 550 1.1 elric 551 1.2 christos /* 552 1.2 christos * constrained_delegation (S4U2Proxy) only works within 553 1.2 christos * the same realm. We use the already canonicalized version 554 1.2 christos * of the principals here, while "target" is the principal 555 1.2 christos * provided by the client. 556 1.2 christos */ 557 1.2 christos if(!krb5_realm_compare(context, client->entry.principal, server->entry.principal)) { 558 1.2 christos ret = KRB5KDC_ERR_BADOPTION; 559 1.2 christos kdc_log(context, config, 0, 560 1.2 christos "Bad request for constrained delegation"); 561 1.2 christos return ret; 562 1.2 christos } 563 1.1 elric 564 1.1 elric if (clientdb->hdb_check_constrained_delegation) { 565 1.2 christos ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, target); 566 1.1 elric if (ret == 0) 567 1.1 elric return 0; 568 1.1 elric } else { 569 1.2 christos /* if client delegates to itself, that ok */ 570 1.2 christos if (krb5_principal_compare(context, client->entry.principal, server->entry.principal) == TRUE) 571 1.2 christos return 0; 572 1.2 christos 573 1.1 elric ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl); 574 1.1 elric if (ret) { 575 1.1 elric krb5_clear_error_message(context); 576 1.1 elric return ret; 577 1.1 elric } 578 1.2 christos 579 1.1 elric if (acl) { 580 1.1 elric for (i = 0; i < acl->len; i++) { 581 1.2 christos if (krb5_principal_compare(context, target, &acl->val[i]) == TRUE) 582 1.1 elric return 0; 583 1.1 elric } 584 1.1 elric } 585 1.1 elric ret = KRB5KDC_ERR_BADOPTION; 586 1.1 elric } 587 1.1 elric kdc_log(context, config, 0, 588 1.1 elric "Bad request for constrained delegation"); 589 1.1 elric return ret; 590 1.1 elric } 591 1.1 elric 592 1.1 elric /* 593 1.1 elric * Determine if s4u2self is allowed from this client to this server 594 1.1 elric * 595 1.1 elric * For example, regardless of the principal being impersonated, if the 596 1.1 elric * 'client' and 'server' are the same, then it's safe. 597 1.1 elric */ 598 1.1 elric 599 1.1 elric static krb5_error_code 600 1.1 elric check_s4u2self(krb5_context context, 601 1.1 elric krb5_kdc_configuration *config, 602 1.1 elric HDB *clientdb, 603 1.1 elric hdb_entry_ex *client, 604 1.1 elric krb5_const_principal server) 605 1.1 elric { 606 1.1 elric krb5_error_code ret; 607 1.1 elric 608 1.1 elric /* if client does a s4u2self to itself, that ok */ 609 1.1 elric if (krb5_principal_compare(context, client->entry.principal, server) == TRUE) 610 1.1 elric return 0; 611 1.1 elric 612 1.1 elric if (clientdb->hdb_check_s4u2self) { 613 1.1 elric ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server); 614 1.1 elric if (ret == 0) 615 1.1 elric return 0; 616 1.1 elric } else { 617 1.1 elric ret = KRB5KDC_ERR_BADOPTION; 618 1.1 elric } 619 1.1 elric return ret; 620 1.1 elric } 621 1.1 elric 622 1.1 elric /* 623 1.1 elric * 624 1.1 elric */ 625 1.1 elric 626 1.1 elric static krb5_error_code 627 1.1 elric verify_flags (krb5_context context, 628 1.1 elric krb5_kdc_configuration *config, 629 1.1 elric const EncTicketPart *et, 630 1.1 elric const char *pstr) 631 1.1 elric { 632 1.1 elric if(et->endtime < kdc_time){ 633 1.1 elric kdc_log(context, config, 0, "Ticket expired (%s)", pstr); 634 1.1 elric return KRB5KRB_AP_ERR_TKT_EXPIRED; 635 1.1 elric } 636 1.1 elric if(et->flags.invalid){ 637 1.1 elric kdc_log(context, config, 0, "Ticket not valid (%s)", pstr); 638 1.1 elric return KRB5KRB_AP_ERR_TKT_NYV; 639 1.1 elric } 640 1.1 elric return 0; 641 1.1 elric } 642 1.1 elric 643 1.1 elric /* 644 1.1 elric * 645 1.1 elric */ 646 1.1 elric 647 1.1 elric static krb5_error_code 648 1.1 elric fix_transited_encoding(krb5_context context, 649 1.1 elric krb5_kdc_configuration *config, 650 1.1 elric krb5_boolean check_policy, 651 1.1 elric const TransitedEncoding *tr, 652 1.1 elric EncTicketPart *et, 653 1.1 elric const char *client_realm, 654 1.1 elric const char *server_realm, 655 1.1 elric const char *tgt_realm) 656 1.1 elric { 657 1.1 elric krb5_error_code ret = 0; 658 1.1 elric char **realms, **tmp; 659 1.1 elric unsigned int num_realms; 660 1.2 christos size_t i; 661 1.1 elric 662 1.1 elric switch (tr->tr_type) { 663 1.1 elric case DOMAIN_X500_COMPRESS: 664 1.1 elric break; 665 1.1 elric case 0: 666 1.1 elric /* 667 1.1 elric * Allow empty content of type 0 because that is was Microsoft 668 1.1 elric * generates in their TGT. 669 1.1 elric */ 670 1.1 elric if (tr->contents.length == 0) 671 1.1 elric break; 672 1.1 elric kdc_log(context, config, 0, 673 1.1 elric "Transited type 0 with non empty content"); 674 1.1 elric return KRB5KDC_ERR_TRTYPE_NOSUPP; 675 1.1 elric default: 676 1.1 elric kdc_log(context, config, 0, 677 1.1 elric "Unknown transited type: %u", tr->tr_type); 678 1.1 elric return KRB5KDC_ERR_TRTYPE_NOSUPP; 679 1.1 elric } 680 1.1 elric 681 1.1 elric ret = krb5_domain_x500_decode(context, 682 1.1 elric tr->contents, 683 1.1 elric &realms, 684 1.1 elric &num_realms, 685 1.1 elric client_realm, 686 1.1 elric server_realm); 687 1.1 elric if(ret){ 688 1.1 elric krb5_warn(context, ret, 689 1.1 elric "Decoding transited encoding"); 690 1.1 elric return ret; 691 1.1 elric } 692 1.3 christos 693 1.3 christos /* 694 1.3 christos * If the realm of the presented tgt is neither the client nor the server 695 1.3 christos * realm, it is a transit realm and must be added to transited set. 696 1.3 christos */ 697 1.1 elric if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) { 698 1.1 elric if (num_realms + 1 > UINT_MAX/sizeof(*realms)) { 699 1.1 elric ret = ERANGE; 700 1.1 elric goto free_realms; 701 1.1 elric } 702 1.1 elric tmp = realloc(realms, (num_realms + 1) * sizeof(*realms)); 703 1.1 elric if(tmp == NULL){ 704 1.1 elric ret = ENOMEM; 705 1.1 elric goto free_realms; 706 1.1 elric } 707 1.1 elric realms = tmp; 708 1.1 elric realms[num_realms] = strdup(tgt_realm); 709 1.1 elric if(realms[num_realms] == NULL){ 710 1.1 elric ret = ENOMEM; 711 1.1 elric goto free_realms; 712 1.1 elric } 713 1.1 elric num_realms++; 714 1.1 elric } 715 1.1 elric if(num_realms == 0) { 716 1.1 elric if(strcmp(client_realm, server_realm)) 717 1.1 elric kdc_log(context, config, 0, 718 1.1 elric "cross-realm %s -> %s", client_realm, server_realm); 719 1.1 elric } else { 720 1.1 elric size_t l = 0; 721 1.1 elric char *rs; 722 1.1 elric for(i = 0; i < num_realms; i++) 723 1.1 elric l += strlen(realms[i]) + 2; 724 1.1 elric rs = malloc(l); 725 1.1 elric if(rs != NULL) { 726 1.1 elric *rs = '\0'; 727 1.1 elric for(i = 0; i < num_realms; i++) { 728 1.1 elric if(i > 0) 729 1.1 elric strlcat(rs, ", ", l); 730 1.1 elric strlcat(rs, realms[i], l); 731 1.1 elric } 732 1.1 elric kdc_log(context, config, 0, 733 1.1 elric "cross-realm %s -> %s via [%s]", 734 1.1 elric client_realm, server_realm, rs); 735 1.1 elric free(rs); 736 1.1 elric } 737 1.1 elric } 738 1.1 elric if(check_policy) { 739 1.1 elric ret = krb5_check_transited(context, client_realm, 740 1.1 elric server_realm, 741 1.1 elric realms, num_realms, NULL); 742 1.1 elric if(ret) { 743 1.1 elric krb5_warn(context, ret, "cross-realm %s -> %s", 744 1.1 elric client_realm, server_realm); 745 1.1 elric goto free_realms; 746 1.1 elric } 747 1.1 elric et->flags.transited_policy_checked = 1; 748 1.1 elric } 749 1.1 elric et->transited.tr_type = DOMAIN_X500_COMPRESS; 750 1.1 elric ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents); 751 1.1 elric if(ret) 752 1.1 elric krb5_warn(context, ret, "Encoding transited encoding"); 753 1.1 elric free_realms: 754 1.1 elric for(i = 0; i < num_realms; i++) 755 1.1 elric free(realms[i]); 756 1.1 elric free(realms); 757 1.1 elric return ret; 758 1.1 elric } 759 1.1 elric 760 1.1 elric 761 1.1 elric static krb5_error_code 762 1.1 elric tgs_make_reply(krb5_context context, 763 1.1 elric krb5_kdc_configuration *config, 764 1.1 elric KDC_REQ_BODY *b, 765 1.1 elric krb5_const_principal tgt_name, 766 1.1 elric const EncTicketPart *tgt, 767 1.1 elric const krb5_keyblock *replykey, 768 1.1 elric int rk_is_subkey, 769 1.1 elric const EncryptionKey *serverkey, 770 1.1 elric const krb5_keyblock *sessionkey, 771 1.1 elric krb5_kvno kvno, 772 1.1 elric AuthorizationData *auth_data, 773 1.1 elric hdb_entry_ex *server, 774 1.1 elric krb5_principal server_principal, 775 1.1 elric const char *server_name, 776 1.1 elric hdb_entry_ex *client, 777 1.1 elric krb5_principal client_principal, 778 1.3 christos const char *tgt_realm, 779 1.1 elric hdb_entry_ex *krbtgt, 780 1.1 elric krb5_enctype krbtgt_etype, 781 1.1 elric krb5_principals spp, 782 1.1 elric const krb5_data *rspac, 783 1.1 elric const METHOD_DATA *enc_pa_data, 784 1.1 elric const char **e_text, 785 1.1 elric krb5_data *reply) 786 1.1 elric { 787 1.1 elric KDC_REP rep; 788 1.1 elric EncKDCRepPart ek; 789 1.1 elric EncTicketPart et; 790 1.1 elric KDCOptions f = b->kdc_options; 791 1.1 elric krb5_error_code ret; 792 1.1 elric int is_weak = 0; 793 1.1 elric 794 1.1 elric memset(&rep, 0, sizeof(rep)); 795 1.1 elric memset(&et, 0, sizeof(et)); 796 1.1 elric memset(&ek, 0, sizeof(ek)); 797 1.1 elric 798 1.1 elric rep.pvno = 5; 799 1.1 elric rep.msg_type = krb_tgs_rep; 800 1.1 elric 801 1.1 elric et.authtime = tgt->authtime; 802 1.1 elric _kdc_fix_time(&b->till); 803 1.1 elric et.endtime = min(tgt->endtime, *b->till); 804 1.1 elric ALLOC(et.starttime); 805 1.1 elric *et.starttime = kdc_time; 806 1.1 elric 807 1.3 christos ret = check_tgs_flags(context, config, b, tgt_name, tgt, &et); 808 1.1 elric if(ret) 809 1.1 elric goto out; 810 1.1 elric 811 1.1 elric /* We should check the transited encoding if: 812 1.1 elric 1) the request doesn't ask not to be checked 813 1.1 elric 2) globally enforcing a check 814 1.1 elric 3) principal requires checking 815 1.1 elric 4) we allow non-check per-principal, but principal isn't marked as allowing this 816 1.1 elric 5) we don't globally allow this 817 1.1 elric */ 818 1.1 elric 819 1.1 elric #define GLOBAL_FORCE_TRANSITED_CHECK \ 820 1.1 elric (config->trpolicy == TRPOLICY_ALWAYS_CHECK) 821 1.1 elric #define GLOBAL_ALLOW_PER_PRINCIPAL \ 822 1.1 elric (config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL) 823 1.1 elric #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK \ 824 1.1 elric (config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST) 825 1.1 elric 826 1.1 elric /* these will consult the database in future release */ 827 1.1 elric #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0 828 1.1 elric #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0 829 1.1 elric 830 1.1 elric ret = fix_transited_encoding(context, config, 831 1.1 elric !f.disable_transited_check || 832 1.1 elric GLOBAL_FORCE_TRANSITED_CHECK || 833 1.1 elric PRINCIPAL_FORCE_TRANSITED_CHECK(server) || 834 1.1 elric !((GLOBAL_ALLOW_PER_PRINCIPAL && 835 1.1 elric PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) || 836 1.1 elric GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK), 837 1.1 elric &tgt->transited, &et, 838 1.1 elric krb5_principal_get_realm(context, client_principal), 839 1.1 elric krb5_principal_get_realm(context, server->entry.principal), 840 1.3 christos tgt_realm); 841 1.1 elric if(ret) 842 1.1 elric goto out; 843 1.1 elric 844 1.3 christos ret = copy_Realm(&server_principal->realm, &rep.ticket.realm); 845 1.3 christos if (ret) 846 1.3 christos goto out; 847 1.1 elric _krb5_principal2principalname(&rep.ticket.sname, server_principal); 848 1.3 christos ret = copy_Realm(&tgt_name->realm, &rep.crealm); 849 1.3 christos if (ret) 850 1.3 christos goto out; 851 1.1 elric 852 1.3 christos /* 853 1.3 christos * RFC 8062 states "if the ticket in the TGS request is an anonymous 854 1.3 christos * one, the client and client realm are copied from that ticket". So 855 1.3 christos * whilst the TGT flag check below is superfluous, it is included in 856 1.3 christos * order to follow the specification to its letter. 857 1.3 christos */ 858 1.3 christos if (et.flags.anonymous && !tgt->flags.anonymous) 859 1.3 christos _kdc_make_anonymous_principalname(&rep.cname); 860 1.3 christos else 861 1.3 christos ret = copy_PrincipalName(&tgt_name->name, &rep.cname); 862 1.3 christos if (ret) 863 1.3 christos goto out; 864 1.1 elric rep.ticket.tkt_vno = 5; 865 1.1 elric 866 1.1 elric ek.caddr = et.caddr; 867 1.1 elric 868 1.1 elric { 869 1.1 elric time_t life; 870 1.1 elric life = et.endtime - *et.starttime; 871 1.1 elric if(client && client->entry.max_life) 872 1.1 elric life = min(life, *client->entry.max_life); 873 1.1 elric if(server->entry.max_life) 874 1.1 elric life = min(life, *server->entry.max_life); 875 1.1 elric et.endtime = *et.starttime + life; 876 1.1 elric } 877 1.1 elric if(f.renewable_ok && tgt->flags.renewable && 878 1.1 elric et.renew_till == NULL && et.endtime < *b->till && 879 1.1 elric tgt->renew_till != NULL) 880 1.1 elric { 881 1.1 elric et.flags.renewable = 1; 882 1.1 elric ALLOC(et.renew_till); 883 1.1 elric *et.renew_till = *b->till; 884 1.1 elric } 885 1.1 elric if(et.renew_till){ 886 1.1 elric time_t renew; 887 1.2 christos renew = *et.renew_till - *et.starttime; 888 1.1 elric if(client && client->entry.max_renew) 889 1.1 elric renew = min(renew, *client->entry.max_renew); 890 1.1 elric if(server->entry.max_renew) 891 1.1 elric renew = min(renew, *server->entry.max_renew); 892 1.2 christos *et.renew_till = *et.starttime + renew; 893 1.1 elric } 894 1.2 christos 895 1.1 elric if(et.renew_till){ 896 1.1 elric *et.renew_till = min(*et.renew_till, *tgt->renew_till); 897 1.1 elric *et.starttime = min(*et.starttime, *et.renew_till); 898 1.1 elric et.endtime = min(et.endtime, *et.renew_till); 899 1.1 elric } 900 1.1 elric 901 1.1 elric *et.starttime = min(*et.starttime, et.endtime); 902 1.1 elric 903 1.1 elric if(*et.starttime == et.endtime){ 904 1.1 elric ret = KRB5KDC_ERR_NEVER_VALID; 905 1.1 elric goto out; 906 1.1 elric } 907 1.1 elric if(et.renew_till && et.endtime == *et.renew_till){ 908 1.1 elric free(et.renew_till); 909 1.1 elric et.renew_till = NULL; 910 1.1 elric et.flags.renewable = 0; 911 1.1 elric } 912 1.1 elric 913 1.1 elric et.flags.pre_authent = tgt->flags.pre_authent; 914 1.1 elric et.flags.hw_authent = tgt->flags.hw_authent; 915 1.1 elric et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate; 916 1.1 elric 917 1.4 christos /* See MS-KILE 3.3.5.1 */ 918 1.4 christos if (!server->entry.flags.forwardable) 919 1.4 christos et.flags.forwardable = 0; 920 1.4 christos if (!server->entry.flags.proxiable) 921 1.4 christos et.flags.proxiable = 0; 922 1.4 christos 923 1.3 christos /* 924 1.3 christos * For anonymous tickets, we should filter out positive authorization data 925 1.3 christos * that could reveal the client's identity, and return a policy error for 926 1.3 christos * restrictive authorization data. Policy for unknown authorization types 927 1.3 christos * is implementation dependent. 928 1.3 christos */ 929 1.3 christos if (rspac->length && !et.flags.anonymous) { 930 1.1 elric /* 931 1.1 elric * No not need to filter out the any PAC from the 932 1.1 elric * auth_data since it's signed by the KDC. 933 1.1 elric */ 934 1.1 elric ret = _kdc_tkt_add_if_relevant_ad(context, &et, 935 1.1 elric KRB5_AUTHDATA_WIN2K_PAC, rspac); 936 1.1 elric if (ret) 937 1.1 elric goto out; 938 1.1 elric } 939 1.2 christos 940 1.1 elric if (auth_data) { 941 1.1 elric unsigned int i = 0; 942 1.1 elric 943 1.1 elric /* XXX check authdata */ 944 1.1 elric 945 1.1 elric if (et.authorization_data == NULL) { 946 1.1 elric et.authorization_data = calloc(1, sizeof(*et.authorization_data)); 947 1.1 elric if (et.authorization_data == NULL) { 948 1.1 elric ret = ENOMEM; 949 1.1 elric krb5_set_error_message(context, ret, "malloc: out of memory"); 950 1.1 elric goto out; 951 1.1 elric } 952 1.1 elric } 953 1.1 elric for(i = 0; i < auth_data->len ; i++) { 954 1.1 elric ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]); 955 1.1 elric if (ret) { 956 1.1 elric krb5_set_error_message(context, ret, "malloc: out of memory"); 957 1.1 elric goto out; 958 1.1 elric } 959 1.1 elric } 960 1.1 elric 961 1.1 elric /* Filter out type KRB5SignedPath */ 962 1.1 elric ret = find_KRB5SignedPath(context, et.authorization_data, NULL); 963 1.1 elric if (ret == 0) { 964 1.1 elric if (et.authorization_data->len == 1) { 965 1.1 elric free_AuthorizationData(et.authorization_data); 966 1.1 elric free(et.authorization_data); 967 1.1 elric et.authorization_data = NULL; 968 1.1 elric } else { 969 1.1 elric AuthorizationData *ad = et.authorization_data; 970 1.1 elric free_AuthorizationDataElement(&ad->val[ad->len - 1]); 971 1.1 elric ad->len--; 972 1.1 elric } 973 1.1 elric } 974 1.1 elric } 975 1.1 elric 976 1.1 elric ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key); 977 1.1 elric if (ret) 978 1.1 elric goto out; 979 1.3 christos et.crealm = rep.crealm; 980 1.3 christos et.cname = rep.cname; 981 1.2 christos 982 1.1 elric ek.key = et.key; 983 1.1 elric /* MIT must have at least one last_req */ 984 1.1 elric ek.last_req.val = calloc(1, sizeof(*ek.last_req.val)); 985 1.1 elric if (ek.last_req.val == NULL) { 986 1.1 elric ret = ENOMEM; 987 1.1 elric goto out; 988 1.1 elric } 989 1.2 christos ek.last_req.len = 1; /* set after alloc to avoid null deref on cleanup */ 990 1.1 elric ek.nonce = b->nonce; 991 1.1 elric ek.flags = et.flags; 992 1.1 elric ek.authtime = et.authtime; 993 1.1 elric ek.starttime = et.starttime; 994 1.1 elric ek.endtime = et.endtime; 995 1.1 elric ek.renew_till = et.renew_till; 996 1.1 elric ek.srealm = rep.ticket.realm; 997 1.1 elric ek.sname = rep.ticket.sname; 998 1.1 elric 999 1.1 elric _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, 1000 1.1 elric et.endtime, et.renew_till); 1001 1.1 elric 1002 1.1 elric /* Don't sign cross realm tickets, they can't be checked anyway */ 1003 1.1 elric { 1004 1.1 elric char *r = get_krbtgt_realm(&ek.sname); 1005 1.1 elric 1006 1.1 elric if (r == NULL || strcmp(r, ek.srealm) == 0) { 1007 1.1 elric ret = _kdc_add_KRB5SignedPath(context, 1008 1.1 elric config, 1009 1.1 elric krbtgt, 1010 1.1 elric krbtgt_etype, 1011 1.1 elric client_principal, 1012 1.1 elric NULL, 1013 1.1 elric spp, 1014 1.1 elric &et); 1015 1.1 elric if (ret) 1016 1.1 elric goto out; 1017 1.1 elric } 1018 1.1 elric } 1019 1.1 elric 1020 1.1 elric if (enc_pa_data->len) { 1021 1.1 elric rep.padata = calloc(1, sizeof(*rep.padata)); 1022 1.1 elric if (rep.padata == NULL) { 1023 1.1 elric ret = ENOMEM; 1024 1.1 elric goto out; 1025 1.1 elric } 1026 1.1 elric ret = copy_METHOD_DATA(enc_pa_data, rep.padata); 1027 1.1 elric if (ret) 1028 1.1 elric goto out; 1029 1.1 elric } 1030 1.1 elric 1031 1.2 christos if (krb5_enctype_valid(context, serverkey->keytype) != 0 1032 1.2 christos && _kdc_is_weak_exception(server->entry.principal, serverkey->keytype)) 1033 1.1 elric { 1034 1.2 christos krb5_enctype_enable(context, serverkey->keytype); 1035 1.1 elric is_weak = 1; 1036 1.1 elric } 1037 1.1 elric 1038 1.1 elric 1039 1.1 elric /* It is somewhat unclear where the etype in the following 1040 1.1 elric encryption should come from. What we have is a session 1041 1.1 elric key in the passed tgt, and a list of preferred etypes 1042 1.1 elric *for the new ticket*. Should we pick the best possible 1043 1.1 elric etype, given the keytype in the tgt, or should we look 1044 1.1 elric at the etype list here as well? What if the tgt 1045 1.1 elric session key is DES3 and we want a ticket with a (say) 1046 1.1 elric CAST session key. Should the DES3 etype be added to the 1047 1.1 elric etype list, even if we don't want a session key with 1048 1.1 elric DES3? */ 1049 1.2 christos ret = _kdc_encode_reply(context, config, NULL, 0, 1050 1.2 christos &rep, &et, &ek, serverkey->keytype, 1051 1.1 elric kvno, 1052 1.1 elric serverkey, 0, replykey, rk_is_subkey, 1053 1.1 elric e_text, reply); 1054 1.1 elric if (is_weak) 1055 1.2 christos krb5_enctype_disable(context, serverkey->keytype); 1056 1.1 elric 1057 1.1 elric out: 1058 1.1 elric free_TGS_REP(&rep); 1059 1.1 elric free_TransitedEncoding(&et.transited); 1060 1.1 elric if(et.starttime) 1061 1.1 elric free(et.starttime); 1062 1.1 elric if(et.renew_till) 1063 1.1 elric free(et.renew_till); 1064 1.1 elric if(et.authorization_data) { 1065 1.1 elric free_AuthorizationData(et.authorization_data); 1066 1.1 elric free(et.authorization_data); 1067 1.1 elric } 1068 1.1 elric free_LastReq(&ek.last_req); 1069 1.1 elric memset(et.key.keyvalue.data, 0, et.key.keyvalue.length); 1070 1.1 elric free_EncryptionKey(&et.key); 1071 1.1 elric return ret; 1072 1.1 elric } 1073 1.1 elric 1074 1.1 elric static krb5_error_code 1075 1.1 elric tgs_check_authenticator(krb5_context context, 1076 1.1 elric krb5_kdc_configuration *config, 1077 1.1 elric krb5_auth_context ac, 1078 1.1 elric KDC_REQ_BODY *b, 1079 1.1 elric const char **e_text, 1080 1.1 elric krb5_keyblock *key) 1081 1.1 elric { 1082 1.1 elric krb5_authenticator auth; 1083 1.2 christos size_t len = 0; 1084 1.1 elric unsigned char *buf; 1085 1.1 elric size_t buf_size; 1086 1.1 elric krb5_error_code ret; 1087 1.1 elric krb5_crypto crypto; 1088 1.1 elric 1089 1.1 elric krb5_auth_con_getauthenticator(context, ac, &auth); 1090 1.1 elric if(auth->cksum == NULL){ 1091 1.1 elric kdc_log(context, config, 0, "No authenticator in request"); 1092 1.1 elric ret = KRB5KRB_AP_ERR_INAPP_CKSUM; 1093 1.1 elric goto out; 1094 1.1 elric } 1095 1.1 elric /* 1096 1.1 elric * according to RFC1510 it doesn't need to be keyed, 1097 1.1 elric * but according to the latest draft it needs to. 1098 1.1 elric */ 1099 1.1 elric if ( 1100 1.1 elric #if 0 1101 1.1 elric !krb5_checksum_is_keyed(context, auth->cksum->cksumtype) 1102 1.1 elric || 1103 1.1 elric #endif 1104 1.1 elric !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) { 1105 1.1 elric kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", 1106 1.1 elric auth->cksum->cksumtype); 1107 1.1 elric ret = KRB5KRB_AP_ERR_INAPP_CKSUM; 1108 1.1 elric goto out; 1109 1.1 elric } 1110 1.2 christos 1111 1.1 elric /* XXX should not re-encode this */ 1112 1.1 elric ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret); 1113 1.1 elric if(ret){ 1114 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1115 1.1 elric kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", msg); 1116 1.1 elric krb5_free_error_message(context, msg); 1117 1.1 elric goto out; 1118 1.1 elric } 1119 1.1 elric if(buf_size != len) { 1120 1.1 elric free(buf); 1121 1.1 elric kdc_log(context, config, 0, "Internal error in ASN.1 encoder"); 1122 1.1 elric *e_text = "KDC internal error"; 1123 1.1 elric ret = KRB5KRB_ERR_GENERIC; 1124 1.1 elric goto out; 1125 1.1 elric } 1126 1.1 elric ret = krb5_crypto_init(context, key, 0, &crypto); 1127 1.1 elric if (ret) { 1128 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1129 1.1 elric free(buf); 1130 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 1131 1.1 elric krb5_free_error_message(context, msg); 1132 1.1 elric goto out; 1133 1.1 elric } 1134 1.1 elric ret = krb5_verify_checksum(context, 1135 1.1 elric crypto, 1136 1.1 elric KRB5_KU_TGS_REQ_AUTH_CKSUM, 1137 1.1 elric buf, 1138 1.1 elric len, 1139 1.1 elric auth->cksum); 1140 1.1 elric free(buf); 1141 1.1 elric krb5_crypto_destroy(context, crypto); 1142 1.1 elric if(ret){ 1143 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1144 1.1 elric kdc_log(context, config, 0, 1145 1.1 elric "Failed to verify authenticator checksum: %s", msg); 1146 1.1 elric krb5_free_error_message(context, msg); 1147 1.1 elric } 1148 1.1 elric out: 1149 1.1 elric free_Authenticator(auth); 1150 1.1 elric free(auth); 1151 1.1 elric return ret; 1152 1.1 elric } 1153 1.1 elric 1154 1.1 elric static krb5_boolean 1155 1.1 elric need_referral(krb5_context context, krb5_kdc_configuration *config, 1156 1.1 elric const KDCOptions * const options, krb5_principal server, 1157 1.1 elric krb5_realm **realms) 1158 1.1 elric { 1159 1.1 elric const char *name; 1160 1.1 elric 1161 1.1 elric if(!options->canonicalize && server->name.name_type != KRB5_NT_SRV_INST) 1162 1.1 elric return FALSE; 1163 1.1 elric 1164 1.1 elric if (server->name.name_string.len == 1) 1165 1.1 elric name = server->name.name_string.val[0]; 1166 1.2 christos else if (server->name.name_string.len == 3) { 1167 1.2 christos /* 1168 1.2 christos This is used to give referrals for the 1169 1.2 christos E3514235-4B06-11D1-AB04-00C04FC2DCD2/NTDSGUID/DNSDOMAIN 1170 1.2 christos SPN form, which is used for inter-domain communication in AD 1171 1.2 christos */ 1172 1.2 christos name = server->name.name_string.val[2]; 1173 1.2 christos kdc_log(context, config, 0, "Giving 3 part referral for %s", name); 1174 1.2 christos *realms = malloc(sizeof(char *)*2); 1175 1.2 christos if (*realms == NULL) { 1176 1.2 christos krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 1177 1.2 christos return FALSE; 1178 1.2 christos } 1179 1.2 christos (*realms)[0] = strdup(name); 1180 1.2 christos (*realms)[1] = NULL; 1181 1.2 christos return TRUE; 1182 1.2 christos } else if (server->name.name_string.len > 1) 1183 1.1 elric name = server->name.name_string.val[1]; 1184 1.1 elric else 1185 1.1 elric return FALSE; 1186 1.1 elric 1187 1.1 elric kdc_log(context, config, 0, "Searching referral for %s", name); 1188 1.1 elric 1189 1.1 elric return _krb5_get_host_realm_int(context, name, FALSE, realms) == 0; 1190 1.1 elric } 1191 1.1 elric 1192 1.1 elric static krb5_error_code 1193 1.1 elric tgs_parse_request(krb5_context context, 1194 1.1 elric krb5_kdc_configuration *config, 1195 1.1 elric KDC_REQ_BODY *b, 1196 1.1 elric const PA_DATA *tgs_req, 1197 1.1 elric hdb_entry_ex **krbtgt, 1198 1.1 elric krb5_enctype *krbtgt_etype, 1199 1.1 elric krb5_ticket **ticket, 1200 1.1 elric const char **e_text, 1201 1.1 elric const char *from, 1202 1.1 elric const struct sockaddr *from_addr, 1203 1.1 elric time_t **csec, 1204 1.1 elric int **cusec, 1205 1.1 elric AuthorizationData **auth_data, 1206 1.1 elric krb5_keyblock **replykey, 1207 1.1 elric int *rk_is_subkey) 1208 1.1 elric { 1209 1.2 christos static char failed[] = "<unparse_name failed>"; 1210 1.1 elric krb5_ap_req ap_req; 1211 1.1 elric krb5_error_code ret; 1212 1.1 elric krb5_principal princ; 1213 1.1 elric krb5_auth_context ac = NULL; 1214 1.1 elric krb5_flags ap_req_options; 1215 1.1 elric krb5_flags verify_ap_req_flags; 1216 1.1 elric krb5_crypto crypto; 1217 1.2 christos krb5uint32 krbtgt_kvno; /* kvno used for the PA-TGS-REQ AP-REQ Ticket */ 1218 1.2 christos krb5uint32 krbtgt_kvno_try; 1219 1.2 christos int kvno_search_tries = 4; /* number of kvnos to try when tkt_vno == 0 */ 1220 1.2 christos const Keys *krbtgt_keys;/* keyset for TGT tkt_vno */ 1221 1.1 elric Key *tkey; 1222 1.1 elric krb5_keyblock *subkey = NULL; 1223 1.1 elric unsigned usage; 1224 1.1 elric 1225 1.1 elric *auth_data = NULL; 1226 1.1 elric *csec = NULL; 1227 1.1 elric *cusec = NULL; 1228 1.1 elric *replykey = NULL; 1229 1.1 elric 1230 1.1 elric memset(&ap_req, 0, sizeof(ap_req)); 1231 1.1 elric ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req); 1232 1.1 elric if(ret){ 1233 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1234 1.1 elric kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", msg); 1235 1.1 elric krb5_free_error_message(context, msg); 1236 1.1 elric goto out; 1237 1.1 elric } 1238 1.1 elric 1239 1.1 elric if(!get_krbtgt_realm(&ap_req.ticket.sname)){ 1240 1.1 elric /* XXX check for ticket.sname == req.sname */ 1241 1.1 elric kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket"); 1242 1.1 elric ret = KRB5KDC_ERR_POLICY; /* ? */ 1243 1.1 elric goto out; 1244 1.1 elric } 1245 1.1 elric 1246 1.1 elric _krb5_principalname2krb5_principal(context, 1247 1.1 elric &princ, 1248 1.1 elric ap_req.ticket.sname, 1249 1.1 elric ap_req.ticket.realm); 1250 1.1 elric 1251 1.2 christos krbtgt_kvno = ap_req.ticket.enc_part.kvno ? *ap_req.ticket.enc_part.kvno : 0; 1252 1.2 christos ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, 1253 1.2 christos &krbtgt_kvno, NULL, krbtgt); 1254 1.1 elric 1255 1.2 christos if (ret == HDB_ERR_NOT_FOUND_HERE) { 1256 1.2 christos /* XXX Factor out this unparsing of the same princ all over */ 1257 1.1 elric char *p; 1258 1.1 elric ret = krb5_unparse_name(context, princ, &p); 1259 1.1 elric if (ret != 0) 1260 1.2 christos p = failed; 1261 1.1 elric krb5_free_principal(context, princ); 1262 1.2 christos kdc_log(context, config, 5, 1263 1.2 christos "Ticket-granting ticket account %s does not have secrets at " 1264 1.2 christos "this KDC, need to proxy", p); 1265 1.1 elric if (ret == 0) 1266 1.1 elric free(p); 1267 1.1 elric ret = HDB_ERR_NOT_FOUND_HERE; 1268 1.1 elric goto out; 1269 1.2 christos } else if (ret == HDB_ERR_KVNO_NOT_FOUND) { 1270 1.1 elric char *p; 1271 1.1 elric ret = krb5_unparse_name(context, princ, &p); 1272 1.1 elric if (ret != 0) 1273 1.2 christos p = failed; 1274 1.1 elric krb5_free_principal(context, princ); 1275 1.2 christos kdc_log(context, config, 5, 1276 1.2 christos "Ticket-granting ticket account %s does not have keys for " 1277 1.2 christos "kvno %d at this KDC", p, krbtgt_kvno); 1278 1.1 elric if (ret == 0) 1279 1.1 elric free(p); 1280 1.2 christos ret = HDB_ERR_KVNO_NOT_FOUND; 1281 1.1 elric goto out; 1282 1.2 christos } else if (ret == HDB_ERR_NO_MKEY) { 1283 1.1 elric char *p; 1284 1.2 christos ret = krb5_unparse_name(context, princ, &p); 1285 1.2 christos if (ret != 0) 1286 1.2 christos p = failed; 1287 1.1 elric krb5_free_principal(context, princ); 1288 1.2 christos kdc_log(context, config, 5, 1289 1.2 christos "Missing master key for decrypting keys for ticket-granting " 1290 1.2 christos "ticket account %s with kvno %d at this KDC", p, krbtgt_kvno); 1291 1.2 christos if (ret == 0) 1292 1.2 christos free(p); 1293 1.2 christos ret = HDB_ERR_KVNO_NOT_FOUND; 1294 1.2 christos goto out; 1295 1.2 christos } else if (ret) { 1296 1.2 christos const char *msg = krb5_get_error_message(context, ret); 1297 1.2 christos char *p; 1298 1.2 christos ret = krb5_unparse_name(context, princ, &p); 1299 1.1 elric if (ret != 0) 1300 1.2 christos p = failed; 1301 1.2 christos krb5_free_principal(context, princ); 1302 1.1 elric kdc_log(context, config, 0, 1303 1.2 christos "Ticket-granting ticket not found in database: %s", msg); 1304 1.2 christos krb5_free_error_message(context, msg); 1305 1.1 elric if (ret == 0) 1306 1.2 christos free(p); 1307 1.2 christos ret = KRB5KRB_AP_ERR_NOT_US; 1308 1.1 elric goto out; 1309 1.1 elric } 1310 1.1 elric 1311 1.2 christos krbtgt_kvno_try = krbtgt_kvno ? krbtgt_kvno : (*krbtgt)->entry.kvno; 1312 1.1 elric *krbtgt_etype = ap_req.ticket.enc_part.etype; 1313 1.1 elric 1314 1.2 christos next_kvno: 1315 1.2 christos krbtgt_keys = hdb_kvno2keys(context, &(*krbtgt)->entry, krbtgt_kvno_try); 1316 1.2 christos ret = hdb_enctype2key(context, &(*krbtgt)->entry, krbtgt_keys, 1317 1.1 elric ap_req.ticket.enc_part.etype, &tkey); 1318 1.2 christos if (ret && krbtgt_kvno == 0 && kvno_search_tries > 0) { 1319 1.2 christos kvno_search_tries--; 1320 1.2 christos krbtgt_kvno_try--; 1321 1.2 christos goto next_kvno; 1322 1.2 christos } else if (ret) { 1323 1.1 elric char *str = NULL, *p = NULL; 1324 1.1 elric 1325 1.1 elric krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str); 1326 1.1 elric krb5_unparse_name(context, princ, &p); 1327 1.1 elric kdc_log(context, config, 0, 1328 1.1 elric "No server key with enctype %s found for %s", 1329 1.1 elric str ? str : "<unknown enctype>", 1330 1.1 elric p ? p : "<unparse_name failed>"); 1331 1.1 elric free(str); 1332 1.1 elric free(p); 1333 1.1 elric ret = KRB5KRB_AP_ERR_BADKEYVER; 1334 1.1 elric goto out; 1335 1.1 elric } 1336 1.1 elric 1337 1.1 elric if (b->kdc_options.validate) 1338 1.1 elric verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID; 1339 1.1 elric else 1340 1.1 elric verify_ap_req_flags = 0; 1341 1.1 elric 1342 1.1 elric ret = krb5_verify_ap_req2(context, 1343 1.1 elric &ac, 1344 1.1 elric &ap_req, 1345 1.1 elric princ, 1346 1.1 elric &tkey->key, 1347 1.1 elric verify_ap_req_flags, 1348 1.1 elric &ap_req_options, 1349 1.1 elric ticket, 1350 1.1 elric KRB5_KU_TGS_REQ_AUTH); 1351 1.2 christos if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY && kvno_search_tries > 0) { 1352 1.2 christos kvno_search_tries--; 1353 1.2 christos krbtgt_kvno_try--; 1354 1.2 christos goto next_kvno; 1355 1.2 christos } 1356 1.2 christos 1357 1.1 elric krb5_free_principal(context, princ); 1358 1.1 elric if(ret) { 1359 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1360 1.1 elric kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", msg); 1361 1.1 elric krb5_free_error_message(context, msg); 1362 1.1 elric goto out; 1363 1.1 elric } 1364 1.1 elric 1365 1.1 elric { 1366 1.1 elric krb5_authenticator auth; 1367 1.1 elric 1368 1.1 elric ret = krb5_auth_con_getauthenticator(context, ac, &auth); 1369 1.1 elric if (ret == 0) { 1370 1.1 elric *csec = malloc(sizeof(**csec)); 1371 1.1 elric if (*csec == NULL) { 1372 1.1 elric krb5_free_authenticator(context, &auth); 1373 1.1 elric kdc_log(context, config, 0, "malloc failed"); 1374 1.1 elric goto out; 1375 1.1 elric } 1376 1.1 elric **csec = auth->ctime; 1377 1.1 elric *cusec = malloc(sizeof(**cusec)); 1378 1.1 elric if (*cusec == NULL) { 1379 1.1 elric krb5_free_authenticator(context, &auth); 1380 1.1 elric kdc_log(context, config, 0, "malloc failed"); 1381 1.1 elric goto out; 1382 1.1 elric } 1383 1.1 elric **cusec = auth->cusec; 1384 1.1 elric krb5_free_authenticator(context, &auth); 1385 1.1 elric } 1386 1.1 elric } 1387 1.1 elric 1388 1.1 elric ret = tgs_check_authenticator(context, config, 1389 1.1 elric ac, b, e_text, &(*ticket)->ticket.key); 1390 1.1 elric if (ret) { 1391 1.1 elric krb5_auth_con_free(context, ac); 1392 1.1 elric goto out; 1393 1.1 elric } 1394 1.1 elric 1395 1.1 elric usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY; 1396 1.1 elric *rk_is_subkey = 1; 1397 1.1 elric 1398 1.1 elric ret = krb5_auth_con_getremotesubkey(context, ac, &subkey); 1399 1.1 elric if(ret){ 1400 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1401 1.1 elric krb5_auth_con_free(context, ac); 1402 1.1 elric kdc_log(context, config, 0, "Failed to get remote subkey: %s", msg); 1403 1.1 elric krb5_free_error_message(context, msg); 1404 1.1 elric goto out; 1405 1.1 elric } 1406 1.1 elric if(subkey == NULL){ 1407 1.1 elric usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION; 1408 1.1 elric *rk_is_subkey = 0; 1409 1.1 elric 1410 1.1 elric ret = krb5_auth_con_getkey(context, ac, &subkey); 1411 1.1 elric if(ret) { 1412 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1413 1.1 elric krb5_auth_con_free(context, ac); 1414 1.1 elric kdc_log(context, config, 0, "Failed to get session key: %s", msg); 1415 1.1 elric krb5_free_error_message(context, msg); 1416 1.1 elric goto out; 1417 1.1 elric } 1418 1.1 elric } 1419 1.1 elric if(subkey == NULL){ 1420 1.1 elric krb5_auth_con_free(context, ac); 1421 1.1 elric kdc_log(context, config, 0, 1422 1.1 elric "Failed to get key for enc-authorization-data"); 1423 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1424 1.1 elric goto out; 1425 1.1 elric } 1426 1.1 elric 1427 1.1 elric *replykey = subkey; 1428 1.1 elric 1429 1.1 elric if (b->enc_authorization_data) { 1430 1.1 elric krb5_data ad; 1431 1.1 elric 1432 1.1 elric ret = krb5_crypto_init(context, subkey, 0, &crypto); 1433 1.1 elric if (ret) { 1434 1.1 elric const char *msg = krb5_get_error_message(context, ret); 1435 1.1 elric krb5_auth_con_free(context, ac); 1436 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 1437 1.1 elric krb5_free_error_message(context, msg); 1438 1.1 elric goto out; 1439 1.1 elric } 1440 1.1 elric ret = krb5_decrypt_EncryptedData (context, 1441 1.1 elric crypto, 1442 1.1 elric usage, 1443 1.1 elric b->enc_authorization_data, 1444 1.1 elric &ad); 1445 1.1 elric krb5_crypto_destroy(context, crypto); 1446 1.1 elric if(ret){ 1447 1.1 elric krb5_auth_con_free(context, ac); 1448 1.1 elric kdc_log(context, config, 0, 1449 1.1 elric "Failed to decrypt enc-authorization-data"); 1450 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1451 1.1 elric goto out; 1452 1.1 elric } 1453 1.1 elric ALLOC(*auth_data); 1454 1.1 elric if (*auth_data == NULL) { 1455 1.1 elric krb5_auth_con_free(context, ac); 1456 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1457 1.1 elric goto out; 1458 1.1 elric } 1459 1.1 elric ret = decode_AuthorizationData(ad.data, ad.length, *auth_data, NULL); 1460 1.1 elric if(ret){ 1461 1.1 elric krb5_auth_con_free(context, ac); 1462 1.1 elric free(*auth_data); 1463 1.1 elric *auth_data = NULL; 1464 1.1 elric kdc_log(context, config, 0, "Failed to decode authorization data"); 1465 1.1 elric ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1466 1.1 elric goto out; 1467 1.1 elric } 1468 1.1 elric } 1469 1.1 elric 1470 1.1 elric krb5_auth_con_free(context, ac); 1471 1.1 elric 1472 1.1 elric out: 1473 1.1 elric free_AP_REQ(&ap_req); 1474 1.1 elric 1475 1.1 elric return ret; 1476 1.1 elric } 1477 1.1 elric 1478 1.1 elric static krb5_error_code 1479 1.1 elric build_server_referral(krb5_context context, 1480 1.1 elric krb5_kdc_configuration *config, 1481 1.1 elric krb5_crypto session, 1482 1.1 elric krb5_const_realm referred_realm, 1483 1.1 elric const PrincipalName *true_principal_name, 1484 1.1 elric const PrincipalName *requested_principal, 1485 1.1 elric krb5_data *outdata) 1486 1.2 christos { 1487 1.1 elric PA_ServerReferralData ref; 1488 1.1 elric krb5_error_code ret; 1489 1.1 elric EncryptedData ed; 1490 1.1 elric krb5_data data; 1491 1.2 christos size_t size = 0; 1492 1.1 elric 1493 1.1 elric memset(&ref, 0, sizeof(ref)); 1494 1.1 elric 1495 1.1 elric if (referred_realm) { 1496 1.1 elric ALLOC(ref.referred_realm); 1497 1.1 elric if (ref.referred_realm == NULL) 1498 1.1 elric goto eout; 1499 1.1 elric *ref.referred_realm = strdup(referred_realm); 1500 1.1 elric if (*ref.referred_realm == NULL) 1501 1.1 elric goto eout; 1502 1.1 elric } 1503 1.1 elric if (true_principal_name) { 1504 1.1 elric ALLOC(ref.true_principal_name); 1505 1.1 elric if (ref.true_principal_name == NULL) 1506 1.1 elric goto eout; 1507 1.1 elric ret = copy_PrincipalName(true_principal_name, ref.true_principal_name); 1508 1.1 elric if (ret) 1509 1.1 elric goto eout; 1510 1.1 elric } 1511 1.1 elric if (requested_principal) { 1512 1.1 elric ALLOC(ref.requested_principal_name); 1513 1.1 elric if (ref.requested_principal_name == NULL) 1514 1.1 elric goto eout; 1515 1.1 elric ret = copy_PrincipalName(requested_principal, 1516 1.1 elric ref.requested_principal_name); 1517 1.1 elric if (ret) 1518 1.1 elric goto eout; 1519 1.1 elric } 1520 1.1 elric 1521 1.1 elric ASN1_MALLOC_ENCODE(PA_ServerReferralData, 1522 1.1 elric data.data, data.length, 1523 1.1 elric &ref, &size, ret); 1524 1.1 elric free_PA_ServerReferralData(&ref); 1525 1.1 elric if (ret) 1526 1.1 elric return ret; 1527 1.1 elric if (data.length != size) 1528 1.1 elric krb5_abortx(context, "internal asn.1 encoder error"); 1529 1.1 elric 1530 1.1 elric ret = krb5_encrypt_EncryptedData(context, session, 1531 1.1 elric KRB5_KU_PA_SERVER_REFERRAL, 1532 1.1 elric data.data, data.length, 1533 1.1 elric 0 /* kvno */, &ed); 1534 1.1 elric free(data.data); 1535 1.1 elric if (ret) 1536 1.1 elric return ret; 1537 1.1 elric 1538 1.1 elric ASN1_MALLOC_ENCODE(EncryptedData, 1539 1.1 elric outdata->data, outdata->length, 1540 1.1 elric &ed, &size, ret); 1541 1.1 elric free_EncryptedData(&ed); 1542 1.1 elric if (ret) 1543 1.1 elric return ret; 1544 1.1 elric if (outdata->length != size) 1545 1.1 elric krb5_abortx(context, "internal asn.1 encoder error"); 1546 1.1 elric 1547 1.1 elric return 0; 1548 1.1 elric eout: 1549 1.1 elric free_PA_ServerReferralData(&ref); 1550 1.1 elric krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 1551 1.1 elric return ENOMEM; 1552 1.1 elric } 1553 1.1 elric 1554 1.1 elric static krb5_error_code 1555 1.1 elric tgs_build_reply(krb5_context context, 1556 1.1 elric krb5_kdc_configuration *config, 1557 1.1 elric KDC_REQ *req, 1558 1.1 elric KDC_REQ_BODY *b, 1559 1.1 elric hdb_entry_ex *krbtgt, 1560 1.1 elric krb5_enctype krbtgt_etype, 1561 1.1 elric const krb5_keyblock *replykey, 1562 1.1 elric int rk_is_subkey, 1563 1.1 elric krb5_ticket *ticket, 1564 1.1 elric krb5_data *reply, 1565 1.1 elric const char *from, 1566 1.1 elric const char **e_text, 1567 1.1 elric AuthorizationData **auth_data, 1568 1.1 elric const struct sockaddr *from_addr) 1569 1.1 elric { 1570 1.3 christos krb5_error_code ret, ret2; 1571 1.2 christos krb5_principal cp = NULL, sp = NULL, rsp = NULL, tp = NULL, dp = NULL; 1572 1.2 christos krb5_principal krbtgt_out_principal = NULL; 1573 1.2 christos char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL, *krbtgt_out_n = NULL; 1574 1.1 elric hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; 1575 1.1 elric HDB *clientdb, *s4u2self_impersonated_clientdb; 1576 1.1 elric krb5_realm ref_realm = NULL; 1577 1.1 elric EncTicketPart *tgt = &ticket->ticket; 1578 1.1 elric krb5_principals spp = NULL; 1579 1.1 elric const EncryptionKey *ekey; 1580 1.1 elric krb5_keyblock sessionkey; 1581 1.1 elric krb5_kvno kvno; 1582 1.1 elric krb5_data rspac; 1583 1.3 christos const char *tgt_realm = /* Realm of TGT issuer */ 1584 1.3 christos krb5_principal_get_realm(context, krbtgt->entry.principal); 1585 1.2 christos const char *our_realm = /* Realm of this KDC */ 1586 1.2 christos krb5_principal_get_comp_string(context, krbtgt->entry.principal, 1); 1587 1.2 christos char **capath = NULL; 1588 1.2 christos size_t num_capath = 0; 1589 1.1 elric 1590 1.1 elric hdb_entry_ex *krbtgt_out = NULL; 1591 1.1 elric 1592 1.1 elric METHOD_DATA enc_pa_data; 1593 1.1 elric 1594 1.1 elric PrincipalName *s; 1595 1.1 elric Realm r; 1596 1.1 elric EncTicketPart adtkt; 1597 1.1 elric char opt_str[128]; 1598 1.1 elric int signedpath = 0; 1599 1.1 elric 1600 1.1 elric Key *tkey_check; 1601 1.1 elric Key *tkey_sign; 1602 1.2 christos int flags = HDB_F_FOR_TGS_REQ; 1603 1.1 elric 1604 1.1 elric memset(&sessionkey, 0, sizeof(sessionkey)); 1605 1.1 elric memset(&adtkt, 0, sizeof(adtkt)); 1606 1.1 elric krb5_data_zero(&rspac); 1607 1.1 elric memset(&enc_pa_data, 0, sizeof(enc_pa_data)); 1608 1.1 elric 1609 1.1 elric s = b->sname; 1610 1.1 elric r = b->realm; 1611 1.1 elric 1612 1.2 christos /* 1613 1.2 christos * Always to do CANON, see comment below about returned server principal (rsp). 1614 1.2 christos */ 1615 1.2 christos flags |= HDB_F_CANON; 1616 1.2 christos 1617 1.1 elric if(b->kdc_options.enc_tkt_in_skey){ 1618 1.1 elric Ticket *t; 1619 1.1 elric hdb_entry_ex *uu; 1620 1.1 elric krb5_principal p; 1621 1.1 elric Key *uukey; 1622 1.2 christos krb5uint32 second_kvno = 0; 1623 1.2 christos krb5uint32 *kvno_ptr = NULL; 1624 1.2 christos 1625 1.1 elric if(b->additional_tickets == NULL || 1626 1.1 elric b->additional_tickets->len == 0){ 1627 1.1 elric ret = KRB5KDC_ERR_BADOPTION; /* ? */ 1628 1.1 elric kdc_log(context, config, 0, 1629 1.1 elric "No second ticket present in request"); 1630 1.1 elric goto out; 1631 1.1 elric } 1632 1.1 elric t = &b->additional_tickets->val[0]; 1633 1.1 elric if(!get_krbtgt_realm(&t->sname)){ 1634 1.1 elric kdc_log(context, config, 0, 1635 1.1 elric "Additional ticket is not a ticket-granting ticket"); 1636 1.1 elric ret = KRB5KDC_ERR_POLICY; 1637 1.1 elric goto out; 1638 1.1 elric } 1639 1.1 elric _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); 1640 1.2 christos if(t->enc_part.kvno){ 1641 1.2 christos second_kvno = *t->enc_part.kvno; 1642 1.2 christos kvno_ptr = &second_kvno; 1643 1.2 christos } 1644 1.1 elric ret = _kdc_db_fetch(context, config, p, 1645 1.2 christos HDB_F_GET_KRBTGT, kvno_ptr, 1646 1.1 elric NULL, &uu); 1647 1.1 elric krb5_free_principal(context, p); 1648 1.1 elric if(ret){ 1649 1.1 elric if (ret == HDB_ERR_NOENTRY) 1650 1.1 elric ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1651 1.1 elric goto out; 1652 1.1 elric } 1653 1.2 christos ret = hdb_enctype2key(context, &uu->entry, NULL, 1654 1.1 elric t->enc_part.etype, &uukey); 1655 1.1 elric if(ret){ 1656 1.1 elric _kdc_free_ent(context, uu); 1657 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ 1658 1.1 elric goto out; 1659 1.1 elric } 1660 1.1 elric ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0); 1661 1.1 elric _kdc_free_ent(context, uu); 1662 1.1 elric if(ret) 1663 1.1 elric goto out; 1664 1.1 elric 1665 1.1 elric ret = verify_flags(context, config, &adtkt, spn); 1666 1.1 elric if (ret) 1667 1.1 elric goto out; 1668 1.1 elric 1669 1.1 elric s = &adtkt.cname; 1670 1.1 elric r = adtkt.crealm; 1671 1.4 christos } else if (s == NULL) { 1672 1.4 christos ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1673 1.4 christos kdc_log(context, config, 0, "No server in request"); 1674 1.4 christos goto out; 1675 1.1 elric } 1676 1.1 elric 1677 1.1 elric _krb5_principalname2krb5_principal(context, &sp, *s, r); 1678 1.2 christos ret = krb5_unparse_name(context, sp, &spn); 1679 1.1 elric if (ret) 1680 1.1 elric goto out; 1681 1.1 elric _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm); 1682 1.1 elric ret = krb5_unparse_name(context, cp, &cpn); 1683 1.1 elric if (ret) 1684 1.1 elric goto out; 1685 1.1 elric unparse_flags (KDCOptions2int(b->kdc_options), 1686 1.1 elric asn1_KDCOptions_units(), 1687 1.1 elric opt_str, sizeof(opt_str)); 1688 1.1 elric if(*opt_str) 1689 1.1 elric kdc_log(context, config, 0, 1690 1.1 elric "TGS-REQ %s from %s for %s [%s]", 1691 1.1 elric cpn, from, spn, opt_str); 1692 1.1 elric else 1693 1.1 elric kdc_log(context, config, 0, 1694 1.1 elric "TGS-REQ %s from %s for %s", cpn, from, spn); 1695 1.1 elric 1696 1.1 elric /* 1697 1.1 elric * Fetch server 1698 1.1 elric */ 1699 1.1 elric 1700 1.1 elric server_lookup: 1701 1.2 christos ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags, 1702 1.1 elric NULL, NULL, &server); 1703 1.1 elric 1704 1.2 christos if (ret == HDB_ERR_NOT_FOUND_HERE) { 1705 1.1 elric kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp); 1706 1.1 elric goto out; 1707 1.2 christos } else if (ret == HDB_ERR_WRONG_REALM) { 1708 1.2 christos free(ref_realm); 1709 1.2 christos ref_realm = strdup(server->entry.principal->realm); 1710 1.2 christos if (ref_realm == NULL) { 1711 1.2 christos ret = krb5_enomem(context); 1712 1.2 christos goto out; 1713 1.2 christos } 1714 1.2 christos 1715 1.2 christos kdc_log(context, config, 5, 1716 1.2 christos "Returning a referral to realm %s for " 1717 1.2 christos "server %s.", 1718 1.2 christos ref_realm, spn); 1719 1.2 christos krb5_free_principal(context, sp); 1720 1.2 christos sp = NULL; 1721 1.2 christos ret = krb5_make_principal(context, &sp, r, KRB5_TGS_NAME, 1722 1.2 christos ref_realm, NULL); 1723 1.2 christos if (ret) 1724 1.2 christos goto out; 1725 1.2 christos free(spn); 1726 1.2 christos spn = NULL; 1727 1.2 christos ret = krb5_unparse_name(context, sp, &spn); 1728 1.2 christos if (ret) 1729 1.2 christos goto out; 1730 1.2 christos 1731 1.2 christos goto server_lookup; 1732 1.2 christos } else if (ret) { 1733 1.1 elric const char *new_rlm, *msg; 1734 1.1 elric Realm req_rlm; 1735 1.1 elric krb5_realm *realms; 1736 1.1 elric 1737 1.1 elric if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) { 1738 1.2 christos if (capath == NULL) { 1739 1.2 christos /* With referalls, hierarchical capaths are always enabled */ 1740 1.3 christos ret2 = _krb5_find_capath(context, tgt->crealm, our_realm, 1741 1.3 christos req_rlm, TRUE, &capath, &num_capath); 1742 1.3 christos if (ret2) { 1743 1.3 christos ret = ret2; 1744 1.2 christos goto out; 1745 1.3 christos } 1746 1.2 christos } 1747 1.2 christos new_rlm = num_capath > 0 ? capath[--num_capath] : NULL; 1748 1.2 christos if (new_rlm) { 1749 1.2 christos kdc_log(context, config, 5, "krbtgt from %s via %s for " 1750 1.2 christos "realm %s not found, trying %s", tgt->crealm, 1751 1.2 christos our_realm, req_rlm, new_rlm); 1752 1.2 christos 1753 1.2 christos free(ref_realm); 1754 1.2 christos ref_realm = strdup(new_rlm); 1755 1.2 christos if (ref_realm == NULL) { 1756 1.2 christos ret = krb5_enomem(context); 1757 1.2 christos goto out; 1758 1.2 christos } 1759 1.2 christos 1760 1.2 christos krb5_free_principal(context, sp); 1761 1.2 christos sp = NULL; 1762 1.2 christos krb5_make_principal(context, &sp, r, 1763 1.2 christos KRB5_TGS_NAME, ref_realm, NULL); 1764 1.2 christos free(spn); 1765 1.2 christos spn = NULL; 1766 1.2 christos ret = krb5_unparse_name(context, sp, &spn); 1767 1.2 christos if (ret) 1768 1.2 christos goto out; 1769 1.2 christos goto server_lookup; 1770 1.2 christos } 1771 1.2 christos } else if (need_referral(context, config, &b->kdc_options, sp, &realms)) { 1772 1.1 elric if (strcmp(realms[0], sp->realm) != 0) { 1773 1.1 elric kdc_log(context, config, 5, 1774 1.1 elric "Returning a referral to realm %s for " 1775 1.1 elric "server %s that was not found", 1776 1.1 elric realms[0], spn); 1777 1.1 elric krb5_free_principal(context, sp); 1778 1.2 christos sp = NULL; 1779 1.1 elric krb5_make_principal(context, &sp, r, KRB5_TGS_NAME, 1780 1.1 elric realms[0], NULL); 1781 1.2 christos free(spn); 1782 1.2 christos spn = NULL; 1783 1.1 elric ret = krb5_unparse_name(context, sp, &spn); 1784 1.2 christos if (ret) { 1785 1.2 christos krb5_free_host_realm(context, realms); 1786 1.1 elric goto out; 1787 1.2 christos } 1788 1.1 elric 1789 1.2 christos free(ref_realm); 1790 1.1 elric ref_realm = strdup(realms[0]); 1791 1.1 elric 1792 1.1 elric krb5_free_host_realm(context, realms); 1793 1.1 elric goto server_lookup; 1794 1.1 elric } 1795 1.1 elric krb5_free_host_realm(context, realms); 1796 1.1 elric } 1797 1.1 elric msg = krb5_get_error_message(context, ret); 1798 1.1 elric kdc_log(context, config, 0, 1799 1.1 elric "Server not found in database: %s: %s", spn, msg); 1800 1.1 elric krb5_free_error_message(context, msg); 1801 1.1 elric if (ret == HDB_ERR_NOENTRY) 1802 1.1 elric ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1803 1.1 elric goto out; 1804 1.1 elric } 1805 1.1 elric 1806 1.2 christos /* the name returned to the client depend on what was asked for, 1807 1.2 christos * return canonical name if kdc_options.canonicalize was set, the 1808 1.2 christos * client wants the true name of the principal, if not it just 1809 1.2 christos * wants the name its asked for. 1810 1.2 christos */ 1811 1.2 christos 1812 1.2 christos if (b->kdc_options.canonicalize) 1813 1.2 christos rsp = server->entry.principal; 1814 1.2 christos else 1815 1.2 christos rsp = sp; 1816 1.2 christos 1817 1.2 christos 1818 1.1 elric /* 1819 1.1 elric * Select enctype, return key and kvno. 1820 1.1 elric */ 1821 1.1 elric 1822 1.1 elric { 1823 1.1 elric krb5_enctype etype; 1824 1.1 elric 1825 1.1 elric if(b->kdc_options.enc_tkt_in_skey) { 1826 1.2 christos size_t i; 1827 1.1 elric ekey = &adtkt.key; 1828 1.1 elric for(i = 0; i < b->etype.len; i++) 1829 1.1 elric if (b->etype.val[i] == adtkt.key.keytype) 1830 1.1 elric break; 1831 1.1 elric if(i == b->etype.len) { 1832 1.1 elric kdc_log(context, config, 0, 1833 1.1 elric "Addition ticket have not matching etypes"); 1834 1.1 elric krb5_clear_error_message(context); 1835 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP; 1836 1.1 elric goto out; 1837 1.1 elric } 1838 1.1 elric etype = b->etype.val[i]; 1839 1.1 elric kvno = 0; 1840 1.1 elric } else { 1841 1.1 elric Key *skey; 1842 1.2 christos 1843 1.2 christos ret = _kdc_find_etype(context, 1844 1.2 christos krb5_principal_is_krbtgt(context, sp) ? 1845 1.2 christos config->tgt_use_strongest_session_key : 1846 1.2 christos config->svc_use_strongest_session_key, FALSE, 1847 1.2 christos server, b->etype.val, b->etype.len, &etype, 1848 1.2 christos NULL); 1849 1.1 elric if(ret) { 1850 1.1 elric kdc_log(context, config, 0, 1851 1.1 elric "Server (%s) has no support for etypes", spn); 1852 1.1 elric goto out; 1853 1.1 elric } 1854 1.2 christos ret = _kdc_get_preferred_key(context, config, server, spn, 1855 1.2 christos NULL, &skey); 1856 1.2 christos if(ret) { 1857 1.2 christos kdc_log(context, config, 0, 1858 1.2 christos "Server (%s) has no supported etypes", spn); 1859 1.2 christos goto out; 1860 1.2 christos } 1861 1.1 elric ekey = &skey->key; 1862 1.1 elric kvno = server->entry.kvno; 1863 1.1 elric } 1864 1.2 christos 1865 1.1 elric ret = krb5_generate_random_keyblock(context, etype, &sessionkey); 1866 1.1 elric if (ret) 1867 1.1 elric goto out; 1868 1.1 elric } 1869 1.1 elric 1870 1.1 elric /* 1871 1.1 elric * Check that service is in the same realm as the krbtgt. If it's 1872 1.1 elric * not the same, it's someone that is using a uni-directional trust 1873 1.1 elric * backward. 1874 1.1 elric */ 1875 1.1 elric 1876 1.1 elric /* 1877 1.1 elric * Validate authoriation data 1878 1.1 elric */ 1879 1.1 elric 1880 1.2 christos ret = hdb_enctype2key(context, &krbtgt->entry, NULL, /* XXX use the right kvno! */ 1881 1.1 elric krbtgt_etype, &tkey_check); 1882 1.1 elric if(ret) { 1883 1.1 elric kdc_log(context, config, 0, 1884 1.1 elric "Failed to find key for krbtgt PAC check"); 1885 1.1 elric goto out; 1886 1.1 elric } 1887 1.1 elric 1888 1.2 christos /* 1889 1.2 christos * Now refetch the primary krbtgt, and get the current kvno (the 1890 1.1 elric * sign check may have been on an old kvno, and the server may 1891 1.2 christos * have been an incoming trust) 1892 1.2 christos */ 1893 1.2 christos 1894 1.2 christos ret = krb5_make_principal(context, 1895 1.2 christos &krbtgt_out_principal, 1896 1.2 christos our_realm, 1897 1.2 christos KRB5_TGS_NAME, 1898 1.2 christos our_realm, 1899 1.2 christos NULL); 1900 1.2 christos if (ret) { 1901 1.2 christos kdc_log(context, config, 0, 1902 1.2 christos "Failed to make krbtgt principal name object for " 1903 1.2 christos "authz-data signatures"); 1904 1.2 christos goto out; 1905 1.2 christos } 1906 1.2 christos ret = krb5_unparse_name(context, krbtgt_out_principal, &krbtgt_out_n); 1907 1.2 christos if (ret) { 1908 1.2 christos kdc_log(context, config, 0, 1909 1.2 christos "Failed to make krbtgt principal name object for " 1910 1.2 christos "authz-data signatures"); 1911 1.2 christos goto out; 1912 1.1 elric } 1913 1.1 elric 1914 1.2 christos ret = _kdc_db_fetch(context, config, krbtgt_out_principal, 1915 1.2 christos HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out); 1916 1.1 elric if (ret) { 1917 1.2 christos char *ktpn = NULL; 1918 1.2 christos ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn); 1919 1.1 elric kdc_log(context, config, 0, 1920 1.2 christos "No such principal %s (needed for authz-data signature keys) " 1921 1.2 christos "while processing TGS-REQ for service %s with krbtg %s", 1922 1.2 christos krbtgt_out_n, spn, (ret == 0) ? ktpn : "<unknown>"); 1923 1.2 christos free(ktpn); 1924 1.1 elric ret = KRB5KRB_AP_ERR_NOT_US; 1925 1.1 elric goto out; 1926 1.1 elric } 1927 1.1 elric 1928 1.2 christos /* 1929 1.2 christos * The first realm is the realm of the service, the second is 1930 1.1 elric * krbtgt/<this>/@REALM component of the krbtgt DN the request was 1931 1.1 elric * encrypted to. The redirection via the krbtgt_out entry allows 1932 1.1 elric * the DB to possibly correct the case of the realm (Samba4 does 1933 1.2 christos * this) before the strcmp() 1934 1.2 christos */ 1935 1.1 elric if (strcmp(krb5_principal_get_realm(context, server->entry.principal), 1936 1.1 elric krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) { 1937 1.2 christos char *ktpn; 1938 1.2 christos ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn); 1939 1.1 elric kdc_log(context, config, 0, 1940 1.1 elric "Request with wrong krbtgt: %s", 1941 1.2 christos (ret == 0) ? ktpn : "<unknown>"); 1942 1.1 elric if(ret == 0) 1943 1.2 christos free(ktpn); 1944 1.1 elric ret = KRB5KRB_AP_ERR_NOT_US; 1945 1.2 christos goto out; 1946 1.1 elric } 1947 1.1 elric 1948 1.2 christos ret = _kdc_get_preferred_key(context, config, krbtgt_out, krbtgt_out_n, 1949 1.2 christos NULL, &tkey_sign); 1950 1.2 christos if (ret) { 1951 1.2 christos kdc_log(context, config, 0, 1952 1.2 christos "Failed to find key for krbtgt PAC signature"); 1953 1.2 christos goto out; 1954 1.2 christos } 1955 1.2 christos ret = hdb_enctype2key(context, &krbtgt_out->entry, NULL, 1956 1.2 christos tkey_sign->key.keytype, &tkey_sign); 1957 1.1 elric if(ret) { 1958 1.1 elric kdc_log(context, config, 0, 1959 1.1 elric "Failed to find key for krbtgt PAC signature"); 1960 1.1 elric goto out; 1961 1.1 elric } 1962 1.1 elric 1963 1.2 christos ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, 1964 1.1 elric NULL, &clientdb, &client); 1965 1.1 elric if(ret == HDB_ERR_NOT_FOUND_HERE) { 1966 1.1 elric /* This is OK, we are just trying to find out if they have 1967 1.1 elric * been disabled or deleted in the meantime, missing secrets 1968 1.1 elric * is OK */ 1969 1.1 elric } else if(ret){ 1970 1.1 elric const char *krbtgt_realm, *msg; 1971 1.1 elric 1972 1.1 elric /* 1973 1.1 elric * If the client belongs to the same realm as our krbtgt, it 1974 1.1 elric * should exist in the local database. 1975 1.1 elric * 1976 1.1 elric */ 1977 1.1 elric 1978 1.1 elric krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal); 1979 1.1 elric 1980 1.1 elric if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { 1981 1.1 elric if (ret == HDB_ERR_NOENTRY) 1982 1.1 elric ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 1983 1.1 elric kdc_log(context, config, 1, "Client no longer in database: %s", 1984 1.1 elric cpn); 1985 1.1 elric goto out; 1986 1.1 elric } 1987 1.1 elric 1988 1.1 elric msg = krb5_get_error_message(context, ret); 1989 1.1 elric kdc_log(context, config, 1, "Client not found in database: %s", msg); 1990 1.1 elric krb5_free_error_message(context, msg); 1991 1.1 elric } 1992 1.1 elric 1993 1.2 christos ret = check_PAC(context, config, cp, NULL, 1994 1.2 christos client, server, krbtgt, 1995 1.2 christos &tkey_check->key, 1996 1.2 christos ekey, &tkey_sign->key, 1997 1.1 elric tgt, &rspac, &signedpath); 1998 1.1 elric if (ret) { 1999 1.1 elric const char *msg = krb5_get_error_message(context, ret); 2000 1.1 elric kdc_log(context, config, 0, 2001 1.1 elric "Verify PAC failed for %s (%s) from %s with %s", 2002 1.1 elric spn, cpn, from, msg); 2003 1.1 elric krb5_free_error_message(context, msg); 2004 1.1 elric goto out; 2005 1.1 elric } 2006 1.1 elric 2007 1.1 elric /* also check the krbtgt for signature */ 2008 1.1 elric ret = check_KRB5SignedPath(context, 2009 1.1 elric config, 2010 1.1 elric krbtgt, 2011 1.1 elric cp, 2012 1.1 elric tgt, 2013 1.1 elric &spp, 2014 1.1 elric &signedpath); 2015 1.1 elric if (ret) { 2016 1.1 elric const char *msg = krb5_get_error_message(context, ret); 2017 1.1 elric kdc_log(context, config, 0, 2018 1.1 elric "KRB5SignedPath check failed for %s (%s) from %s with %s", 2019 1.1 elric spn, cpn, from, msg); 2020 1.1 elric krb5_free_error_message(context, msg); 2021 1.1 elric goto out; 2022 1.1 elric } 2023 1.1 elric 2024 1.1 elric /* 2025 1.1 elric * Process request 2026 1.1 elric */ 2027 1.1 elric 2028 1.2 christos /* by default the tgt principal matches the client principal */ 2029 1.2 christos tp = cp; 2030 1.2 christos tpn = cpn; 2031 1.1 elric 2032 1.1 elric if (client) { 2033 1.1 elric const PA_DATA *sdata; 2034 1.1 elric int i = 0; 2035 1.1 elric 2036 1.1 elric sdata = _kdc_find_padata(req, &i, KRB5_PADATA_FOR_USER); 2037 1.1 elric if (sdata) { 2038 1.1 elric krb5_crypto crypto; 2039 1.1 elric krb5_data datack; 2040 1.1 elric PA_S4U2Self self; 2041 1.1 elric const char *str; 2042 1.1 elric 2043 1.1 elric ret = decode_PA_S4U2Self(sdata->padata_value.data, 2044 1.1 elric sdata->padata_value.length, 2045 1.1 elric &self, NULL); 2046 1.1 elric if (ret) { 2047 1.1 elric kdc_log(context, config, 0, "Failed to decode PA-S4U2Self"); 2048 1.1 elric goto out; 2049 1.1 elric } 2050 1.1 elric 2051 1.3 christos if (!krb5_checksum_is_keyed(context, self.cksum.cksumtype)) { 2052 1.3 christos free_PA_S4U2Self(&self); 2053 1.3 christos kdc_log(context, config, 0, "Reject PA-S4U2Self with unkeyed checksum"); 2054 1.3 christos ret = KRB5KRB_AP_ERR_INAPP_CKSUM; 2055 1.3 christos goto out; 2056 1.3 christos } 2057 1.3 christos 2058 1.1 elric ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack); 2059 1.1 elric if (ret) 2060 1.1 elric goto out; 2061 1.1 elric 2062 1.1 elric ret = krb5_crypto_init(context, &tgt->key, 0, &crypto); 2063 1.1 elric if (ret) { 2064 1.1 elric const char *msg = krb5_get_error_message(context, ret); 2065 1.1 elric free_PA_S4U2Self(&self); 2066 1.1 elric krb5_data_free(&datack); 2067 1.1 elric kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 2068 1.1 elric krb5_free_error_message(context, msg); 2069 1.1 elric goto out; 2070 1.1 elric } 2071 1.1 elric 2072 1.3 christos /* Allow HMAC_MD5 checksum with any key type */ 2073 1.3 christos if (self.cksum.cksumtype == CKSUMTYPE_HMAC_MD5) { 2074 1.3 christos unsigned char csdata[16]; 2075 1.3 christos Checksum cs; 2076 1.3 christos 2077 1.3 christos cs.checksum.length = sizeof(csdata); 2078 1.3 christos cs.checksum.data = &csdata; 2079 1.3 christos 2080 1.3 christos ret = _krb5_HMAC_MD5_checksum(context, &crypto->key, 2081 1.3 christos datack.data, datack.length, 2082 1.3 christos KRB5_KU_OTHER_CKSUM, &cs); 2083 1.3 christos if (ret == 0 && 2084 1.3 christos krb5_data_ct_cmp(&cs.checksum, &self.cksum.checksum) != 0) 2085 1.3 christos ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2086 1.3 christos } 2087 1.3 christos else { 2088 1.3 christos ret = krb5_verify_checksum(context, 2089 1.3 christos crypto, 2090 1.3 christos KRB5_KU_OTHER_CKSUM, 2091 1.3 christos datack.data, 2092 1.3 christos datack.length, 2093 1.3 christos &self.cksum); 2094 1.3 christos } 2095 1.1 elric krb5_data_free(&datack); 2096 1.1 elric krb5_crypto_destroy(context, crypto); 2097 1.1 elric if (ret) { 2098 1.1 elric const char *msg = krb5_get_error_message(context, ret); 2099 1.1 elric free_PA_S4U2Self(&self); 2100 1.1 elric kdc_log(context, config, 0, 2101 1.1 elric "krb5_verify_checksum failed for S4U2Self: %s", msg); 2102 1.1 elric krb5_free_error_message(context, msg); 2103 1.1 elric goto out; 2104 1.1 elric } 2105 1.1 elric 2106 1.1 elric ret = _krb5_principalname2krb5_principal(context, 2107 1.2 christos &tp, 2108 1.1 elric self.name, 2109 1.1 elric self.realm); 2110 1.1 elric free_PA_S4U2Self(&self); 2111 1.1 elric if (ret) 2112 1.1 elric goto out; 2113 1.1 elric 2114 1.2 christos ret = krb5_unparse_name(context, tp, &tpn); 2115 1.1 elric if (ret) 2116 1.1 elric goto out; 2117 1.1 elric 2118 1.4 christos ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags, 2119 1.4 christos NULL, &s4u2self_impersonated_clientdb, 2120 1.4 christos &s4u2self_impersonated_client); 2121 1.4 christos if (ret) { 2122 1.4 christos const char *msg; 2123 1.4 christos 2124 1.4 christos /* 2125 1.4 christos * If the client belongs to the same realm as our krbtgt, it 2126 1.4 christos * should exist in the local database. 2127 1.4 christos * 2128 1.4 christos */ 2129 1.4 christos 2130 1.4 christos if (ret == HDB_ERR_NOENTRY) 2131 1.4 christos ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 2132 1.4 christos msg = krb5_get_error_message(context, ret); 2133 1.4 christos kdc_log(context, config, 2, 2134 1.4 christos "S4U2Self principal to impersonate %s not found in database: %s", 2135 1.4 christos tpn, msg); 2136 1.4 christos krb5_free_error_message(context, msg); 2137 1.4 christos goto out; 2138 1.4 christos } 2139 1.4 christos 2140 1.4 christos /* Ignore require_pwchange and pw_end attributes (as Windows does), 2141 1.4 christos * since S4U2Self is not password authentication. */ 2142 1.4 christos s4u2self_impersonated_client->entry.flags.require_pwchange = FALSE; 2143 1.4 christos free(s4u2self_impersonated_client->entry.pw_end); 2144 1.4 christos s4u2self_impersonated_client->entry.pw_end = NULL; 2145 1.4 christos 2146 1.4 christos ret = kdc_check_flags(context, config, s4u2self_impersonated_client, tpn, 2147 1.4 christos NULL, NULL, FALSE); 2148 1.4 christos if (ret) 2149 1.4 christos goto out; 2150 1.4 christos 2151 1.1 elric /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */ 2152 1.1 elric if(rspac.data) { 2153 1.1 elric krb5_pac p = NULL; 2154 1.1 elric krb5_data_free(&rspac); 2155 1.1 elric ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p); 2156 1.1 elric if (ret) { 2157 1.1 elric kdc_log(context, config, 0, "PAC generation failed for -- %s", 2158 1.2 christos tpn); 2159 1.1 elric goto out; 2160 1.1 elric } 2161 1.1 elric if (p != NULL) { 2162 1.1 elric ret = _krb5_pac_sign(context, p, ticket->ticket.authtime, 2163 1.1 elric s4u2self_impersonated_client->entry.principal, 2164 1.1 elric ekey, &tkey_sign->key, 2165 1.1 elric &rspac); 2166 1.1 elric krb5_pac_free(context, p); 2167 1.1 elric if (ret) { 2168 1.1 elric kdc_log(context, config, 0, "PAC signing failed for -- %s", 2169 1.2 christos tpn); 2170 1.1 elric goto out; 2171 1.1 elric } 2172 1.1 elric } 2173 1.1 elric } 2174 1.1 elric 2175 1.1 elric /* 2176 1.1 elric * Check that service doing the impersonating is 2177 1.1 elric * requesting a ticket to it-self. 2178 1.1 elric */ 2179 1.1 elric ret = check_s4u2self(context, config, clientdb, client, sp); 2180 1.1 elric if (ret) { 2181 1.1 elric kdc_log(context, config, 0, "S4U2Self: %s is not allowed " 2182 1.1 elric "to impersonate to service " 2183 1.1 elric "(tried for user %s to service %s)", 2184 1.2 christos cpn, tpn, spn); 2185 1.1 elric goto out; 2186 1.1 elric } 2187 1.1 elric 2188 1.1 elric /* 2189 1.1 elric * If the service isn't trusted for authentication to 2190 1.4 christos * delegation or if the impersonate client is disallowed 2191 1.4 christos * forwardable, remove the forwardable flag. 2192 1.1 elric */ 2193 1.1 elric 2194 1.4 christos if (client->entry.flags.trusted_for_delegation && 2195 1.4 christos s4u2self_impersonated_client->entry.flags.forwardable) { 2196 1.1 elric str = "[forwardable]"; 2197 1.1 elric } else { 2198 1.1 elric b->kdc_options.forwardable = 0; 2199 1.1 elric str = ""; 2200 1.1 elric } 2201 1.1 elric kdc_log(context, config, 0, "s4u2self %s impersonating %s to " 2202 1.2 christos "service %s %s", cpn, tpn, spn, str); 2203 1.1 elric } 2204 1.1 elric } 2205 1.1 elric 2206 1.1 elric /* 2207 1.1 elric * Constrained delegation 2208 1.1 elric */ 2209 1.1 elric 2210 1.1 elric if (client != NULL 2211 1.1 elric && b->additional_tickets != NULL 2212 1.1 elric && b->additional_tickets->len != 0 2213 1.3 christos && b->kdc_options.cname_in_addl_tkt 2214 1.1 elric && b->kdc_options.enc_tkt_in_skey == 0) 2215 1.1 elric { 2216 1.1 elric int ad_signedpath = 0; 2217 1.1 elric Key *clientkey; 2218 1.1 elric Ticket *t; 2219 1.1 elric 2220 1.1 elric /* 2221 1.1 elric * Require that the KDC have issued the service's krbtgt (not 2222 1.1 elric * self-issued ticket with kimpersonate(1). 2223 1.1 elric */ 2224 1.1 elric if (!signedpath) { 2225 1.1 elric ret = KRB5KDC_ERR_BADOPTION; 2226 1.1 elric kdc_log(context, config, 0, 2227 1.1 elric "Constrained delegation done on service ticket %s/%s", 2228 1.1 elric cpn, spn); 2229 1.1 elric goto out; 2230 1.1 elric } 2231 1.1 elric 2232 1.1 elric t = &b->additional_tickets->val[0]; 2233 1.1 elric 2234 1.1 elric ret = hdb_enctype2key(context, &client->entry, 2235 1.2 christos hdb_kvno2keys(context, &client->entry, 2236 1.2 christos t->enc_part.kvno ? * t->enc_part.kvno : 0), 2237 1.1 elric t->enc_part.etype, &clientkey); 2238 1.1 elric if(ret){ 2239 1.1 elric ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ 2240 1.1 elric goto out; 2241 1.1 elric } 2242 1.1 elric 2243 1.1 elric ret = krb5_decrypt_ticket(context, t, &clientkey->key, &adtkt, 0); 2244 1.1 elric if (ret) { 2245 1.1 elric kdc_log(context, config, 0, 2246 1.1 elric "failed to decrypt ticket for " 2247 1.1 elric "constrained delegation from %s to %s ", cpn, spn); 2248 1.1 elric goto out; 2249 1.1 elric } 2250 1.1 elric 2251 1.2 christos ret = _krb5_principalname2krb5_principal(context, 2252 1.2 christos &tp, 2253 1.2 christos adtkt.cname, 2254 1.2 christos adtkt.crealm); 2255 1.2 christos if (ret) 2256 1.2 christos goto out; 2257 1.2 christos 2258 1.2 christos ret = krb5_unparse_name(context, tp, &tpn); 2259 1.2 christos if (ret) 2260 1.2 christos goto out; 2261 1.2 christos 2262 1.2 christos ret = _krb5_principalname2krb5_principal(context, 2263 1.2 christos &dp, 2264 1.2 christos t->sname, 2265 1.2 christos t->realm); 2266 1.2 christos if (ret) 2267 1.2 christos goto out; 2268 1.2 christos 2269 1.2 christos ret = krb5_unparse_name(context, dp, &dpn); 2270 1.2 christos if (ret) 2271 1.2 christos goto out; 2272 1.2 christos 2273 1.1 elric /* check that ticket is valid */ 2274 1.1 elric if (adtkt.flags.forwardable == 0) { 2275 1.1 elric kdc_log(context, config, 0, 2276 1.1 elric "Missing forwardable flag on ticket for " 2277 1.2 christos "constrained delegation from %s (%s) as %s to %s ", 2278 1.2 christos cpn, dpn, tpn, spn); 2279 1.1 elric ret = KRB5KDC_ERR_BADOPTION; 2280 1.1 elric goto out; 2281 1.1 elric } 2282 1.1 elric 2283 1.2 christos ret = check_constrained_delegation(context, config, clientdb, 2284 1.2 christos client, server, sp); 2285 1.1 elric if (ret) { 2286 1.1 elric kdc_log(context, config, 0, 2287 1.2 christos "constrained delegation from %s (%s) as %s to %s not allowed", 2288 1.2 christos cpn, dpn, tpn, spn); 2289 1.1 elric goto out; 2290 1.1 elric } 2291 1.1 elric 2292 1.2 christos ret = verify_flags(context, config, &adtkt, tpn); 2293 1.2 christos if (ret) { 2294 1.1 elric goto out; 2295 1.2 christos } 2296 1.1 elric 2297 1.2 christos krb5_data_free(&rspac); 2298 1.1 elric 2299 1.2 christos /* 2300 1.2 christos * generate the PAC for the user. 2301 1.2 christos * 2302 1.2 christos * TODO: pass in t->sname and t->realm and build 2303 1.2 christos * a S4U_DELEGATION_INFO blob to the PAC. 2304 1.2 christos */ 2305 1.2 christos ret = check_PAC(context, config, tp, dp, 2306 1.2 christos client, server, krbtgt, 2307 1.2 christos &clientkey->key, 2308 1.2 christos ekey, &tkey_sign->key, 2309 1.2 christos &adtkt, &rspac, &ad_signedpath); 2310 1.1 elric if (ret) { 2311 1.2 christos const char *msg = krb5_get_error_message(context, ret); 2312 1.2 christos kdc_log(context, config, 0, 2313 1.2 christos "Verify delegated PAC failed to %s for client" 2314 1.2 christos "%s (%s) as %s from %s with %s", 2315 1.2 christos spn, cpn, dpn, tpn, from, msg); 2316 1.2 christos krb5_free_error_message(context, msg); 2317 1.1 elric goto out; 2318 1.1 elric } 2319 1.1 elric 2320 1.1 elric /* 2321 1.1 elric * Check that the KDC issued the user's ticket. 2322 1.1 elric */ 2323 1.1 elric ret = check_KRB5SignedPath(context, 2324 1.1 elric config, 2325 1.1 elric krbtgt, 2326 1.1 elric cp, 2327 1.1 elric &adtkt, 2328 1.1 elric NULL, 2329 1.1 elric &ad_signedpath); 2330 1.1 elric if (ret) { 2331 1.1 elric const char *msg = krb5_get_error_message(context, ret); 2332 1.1 elric kdc_log(context, config, 0, 2333 1.1 elric "KRB5SignedPath check from service %s failed " 2334 1.2 christos "for delegation to %s for client %s (%s)" 2335 1.1 elric "from %s failed with %s", 2336 1.2 christos spn, tpn, dpn, cpn, from, msg); 2337 1.1 elric krb5_free_error_message(context, msg); 2338 1.2 christos goto out; 2339 1.2 christos } 2340 1.2 christos 2341 1.2 christos if (!ad_signedpath) { 2342 1.2 christos ret = KRB5KDC_ERR_BADOPTION; 2343 1.2 christos kdc_log(context, config, 0, 2344 1.2 christos "Ticket not signed with PAC nor SignedPath service %s failed " 2345 1.2 christos "for delegation to %s for client %s (%s)" 2346 1.2 christos "from %s", 2347 1.2 christos spn, tpn, dpn, cpn, from); 2348 1.1 elric goto out; 2349 1.1 elric } 2350 1.1 elric 2351 1.1 elric kdc_log(context, config, 0, "constrained delegation for %s " 2352 1.2 christos "from %s (%s) to %s", tpn, cpn, dpn, spn); 2353 1.1 elric } 2354 1.1 elric 2355 1.1 elric /* 2356 1.1 elric * Check flags 2357 1.1 elric */ 2358 1.1 elric 2359 1.1 elric ret = kdc_check_flags(context, config, 2360 1.1 elric client, cpn, 2361 1.1 elric server, spn, 2362 1.1 elric FALSE); 2363 1.1 elric if(ret) 2364 1.1 elric goto out; 2365 1.1 elric 2366 1.1 elric if((b->kdc_options.validate || b->kdc_options.renew) && 2367 1.1 elric !krb5_principal_compare(context, 2368 1.1 elric krbtgt->entry.principal, 2369 1.1 elric server->entry.principal)){ 2370 1.1 elric kdc_log(context, config, 0, "Inconsistent request."); 2371 1.1 elric ret = KRB5KDC_ERR_SERVER_NOMATCH; 2372 1.1 elric goto out; 2373 1.1 elric } 2374 1.1 elric 2375 1.1 elric /* check for valid set of addresses */ 2376 1.1 elric if(!_kdc_check_addresses(context, config, tgt->caddr, from_addr)) { 2377 1.1 elric ret = KRB5KRB_AP_ERR_BADADDR; 2378 1.1 elric kdc_log(context, config, 0, "Request from wrong address"); 2379 1.1 elric goto out; 2380 1.1 elric } 2381 1.2 christos 2382 1.3 christos /* check local and per-principal anonymous ticket issuance policy */ 2383 1.3 christos if (is_anon_tgs_request_p(b, tgt)) { 2384 1.3 christos ret = _kdc_check_anon_policy(context, config, client, server); 2385 1.3 christos if (ret) 2386 1.3 christos goto out; 2387 1.3 christos } 2388 1.3 christos 2389 1.1 elric /* 2390 1.1 elric * If this is an referral, add server referral data to the 2391 1.1 elric * auth_data reply . 2392 1.1 elric */ 2393 1.1 elric if (ref_realm) { 2394 1.1 elric PA_DATA pa; 2395 1.1 elric krb5_crypto crypto; 2396 1.1 elric 2397 1.1 elric kdc_log(context, config, 0, 2398 1.1 elric "Adding server referral to %s", ref_realm); 2399 1.1 elric 2400 1.1 elric ret = krb5_crypto_init(context, &sessionkey, 0, &crypto); 2401 1.1 elric if (ret) 2402 1.1 elric goto out; 2403 1.1 elric 2404 1.1 elric ret = build_server_referral(context, config, crypto, ref_realm, 2405 1.1 elric NULL, s, &pa.padata_value); 2406 1.1 elric krb5_crypto_destroy(context, crypto); 2407 1.1 elric if (ret) { 2408 1.1 elric kdc_log(context, config, 0, 2409 1.1 elric "Failed building server referral"); 2410 1.1 elric goto out; 2411 1.1 elric } 2412 1.1 elric pa.padata_type = KRB5_PADATA_SERVER_REFERRAL; 2413 1.1 elric 2414 1.1 elric ret = add_METHOD_DATA(&enc_pa_data, &pa); 2415 1.1 elric krb5_data_free(&pa.padata_value); 2416 1.1 elric if (ret) { 2417 1.1 elric kdc_log(context, config, 0, 2418 1.1 elric "Add server referral METHOD-DATA failed"); 2419 1.1 elric goto out; 2420 1.1 elric } 2421 1.1 elric } 2422 1.1 elric 2423 1.1 elric /* 2424 1.1 elric * 2425 1.1 elric */ 2426 1.1 elric 2427 1.1 elric ret = tgs_make_reply(context, 2428 1.1 elric config, 2429 1.1 elric b, 2430 1.2 christos tp, 2431 1.1 elric tgt, 2432 1.1 elric replykey, 2433 1.1 elric rk_is_subkey, 2434 1.1 elric ekey, 2435 1.1 elric &sessionkey, 2436 1.1 elric kvno, 2437 1.1 elric *auth_data, 2438 1.1 elric server, 2439 1.2 christos rsp, 2440 1.1 elric spn, 2441 1.1 elric client, 2442 1.1 elric cp, 2443 1.3 christos tgt_realm, 2444 1.1 elric krbtgt_out, 2445 1.2 christos tkey_sign->key.keytype, 2446 1.1 elric spp, 2447 1.1 elric &rspac, 2448 1.1 elric &enc_pa_data, 2449 1.1 elric e_text, 2450 1.1 elric reply); 2451 1.2 christos 2452 1.1 elric out: 2453 1.2 christos if (tpn != cpn) 2454 1.2 christos free(tpn); 2455 1.1 elric free(spn); 2456 1.1 elric free(cpn); 2457 1.2 christos free(dpn); 2458 1.2 christos free(krbtgt_out_n); 2459 1.2 christos _krb5_free_capath(context, capath); 2460 1.2 christos 2461 1.1 elric krb5_data_free(&rspac); 2462 1.1 elric krb5_free_keyblock_contents(context, &sessionkey); 2463 1.1 elric if(krbtgt_out) 2464 1.1 elric _kdc_free_ent(context, krbtgt_out); 2465 1.1 elric if(server) 2466 1.1 elric _kdc_free_ent(context, server); 2467 1.1 elric if(client) 2468 1.1 elric _kdc_free_ent(context, client); 2469 1.1 elric if(s4u2self_impersonated_client) 2470 1.1 elric _kdc_free_ent(context, s4u2self_impersonated_client); 2471 1.1 elric 2472 1.2 christos if (tp && tp != cp) 2473 1.2 christos krb5_free_principal(context, tp); 2474 1.2 christos krb5_free_principal(context, cp); 2475 1.2 christos krb5_free_principal(context, dp); 2476 1.2 christos krb5_free_principal(context, sp); 2477 1.2 christos krb5_free_principal(context, krbtgt_out_principal); 2478 1.2 christos free(ref_realm); 2479 1.1 elric free_METHOD_DATA(&enc_pa_data); 2480 1.1 elric 2481 1.1 elric free_EncTicketPart(&adtkt); 2482 1.1 elric 2483 1.1 elric return ret; 2484 1.1 elric } 2485 1.1 elric 2486 1.1 elric /* 2487 1.1 elric * 2488 1.1 elric */ 2489 1.1 elric 2490 1.1 elric krb5_error_code 2491 1.1 elric _kdc_tgs_rep(krb5_context context, 2492 1.1 elric krb5_kdc_configuration *config, 2493 1.1 elric KDC_REQ *req, 2494 1.1 elric krb5_data *data, 2495 1.1 elric const char *from, 2496 1.1 elric struct sockaddr *from_addr, 2497 1.1 elric int datagram_reply) 2498 1.1 elric { 2499 1.1 elric AuthorizationData *auth_data = NULL; 2500 1.1 elric krb5_error_code ret; 2501 1.1 elric int i = 0; 2502 1.1 elric const PA_DATA *tgs_req; 2503 1.1 elric 2504 1.1 elric hdb_entry_ex *krbtgt = NULL; 2505 1.1 elric krb5_ticket *ticket = NULL; 2506 1.1 elric const char *e_text = NULL; 2507 1.1 elric krb5_enctype krbtgt_etype = ETYPE_NULL; 2508 1.1 elric 2509 1.1 elric krb5_keyblock *replykey = NULL; 2510 1.1 elric int rk_is_subkey = 0; 2511 1.1 elric time_t *csec = NULL; 2512 1.1 elric int *cusec = NULL; 2513 1.1 elric 2514 1.1 elric if(req->padata == NULL){ 2515 1.1 elric ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */ 2516 1.1 elric kdc_log(context, config, 0, 2517 1.1 elric "TGS-REQ from %s without PA-DATA", from); 2518 1.1 elric goto out; 2519 1.1 elric } 2520 1.1 elric 2521 1.1 elric tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ); 2522 1.1 elric 2523 1.1 elric if(tgs_req == NULL){ 2524 1.1 elric ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; 2525 1.2 christos 2526 1.1 elric kdc_log(context, config, 0, 2527 1.1 elric "TGS-REQ from %s without PA-TGS-REQ", from); 2528 1.1 elric goto out; 2529 1.1 elric } 2530 1.1 elric ret = tgs_parse_request(context, config, 2531 1.1 elric &req->req_body, tgs_req, 2532 1.1 elric &krbtgt, 2533 1.1 elric &krbtgt_etype, 2534 1.1 elric &ticket, 2535 1.1 elric &e_text, 2536 1.1 elric from, from_addr, 2537 1.1 elric &csec, &cusec, 2538 1.1 elric &auth_data, 2539 1.1 elric &replykey, 2540 1.1 elric &rk_is_subkey); 2541 1.1 elric if (ret == HDB_ERR_NOT_FOUND_HERE) { 2542 1.1 elric /* kdc_log() is called in tgs_parse_request() */ 2543 1.1 elric goto out; 2544 1.1 elric } 2545 1.1 elric if (ret) { 2546 1.1 elric kdc_log(context, config, 0, 2547 1.1 elric "Failed parsing TGS-REQ from %s", from); 2548 1.1 elric goto out; 2549 1.1 elric } 2550 1.1 elric 2551 1.2 christos { 2552 1.2 christos const PA_DATA *pa = _kdc_find_padata(req, &i, KRB5_PADATA_FX_FAST); 2553 1.2 christos if (pa) 2554 1.2 christos kdc_log(context, config, 10, "Got TGS FAST request"); 2555 1.2 christos } 2556 1.2 christos 2557 1.2 christos 2558 1.1 elric ret = tgs_build_reply(context, 2559 1.1 elric config, 2560 1.1 elric req, 2561 1.1 elric &req->req_body, 2562 1.1 elric krbtgt, 2563 1.1 elric krbtgt_etype, 2564 1.1 elric replykey, 2565 1.1 elric rk_is_subkey, 2566 1.1 elric ticket, 2567 1.1 elric data, 2568 1.1 elric from, 2569 1.1 elric &e_text, 2570 1.1 elric &auth_data, 2571 1.1 elric from_addr); 2572 1.1 elric if (ret) { 2573 1.1 elric kdc_log(context, config, 0, 2574 1.1 elric "Failed building TGS-REP to %s", from); 2575 1.1 elric goto out; 2576 1.1 elric } 2577 1.1 elric 2578 1.1 elric /* */ 2579 1.1 elric if (datagram_reply && data->length > config->max_datagram_reply_length) { 2580 1.1 elric krb5_data_free(data); 2581 1.1 elric ret = KRB5KRB_ERR_RESPONSE_TOO_BIG; 2582 1.1 elric e_text = "Reply packet too large"; 2583 1.1 elric } 2584 1.1 elric 2585 1.1 elric out: 2586 1.1 elric if (replykey) 2587 1.1 elric krb5_free_keyblock(context, replykey); 2588 1.2 christos 2589 1.1 elric if(ret && ret != HDB_ERR_NOT_FOUND_HERE && data->data == NULL){ 2590 1.2 christos /* XXX add fast wrapping on the error */ 2591 1.2 christos METHOD_DATA error_method = { 0, NULL }; 2592 1.2 christos 2593 1.2 christos 2594 1.2 christos kdc_log(context, config, 10, "tgs-req: sending error: %d to client", ret); 2595 1.2 christos ret = _kdc_fast_mk_error(context, NULL, 2596 1.2 christos &error_method, 2597 1.2 christos NULL, 2598 1.2 christos NULL, 2599 1.2 christos ret, NULL, 2600 1.2 christos NULL, 2601 1.2 christos NULL, NULL, 2602 1.2 christos csec, cusec, 2603 1.2 christos data); 2604 1.2 christos free_METHOD_DATA(&error_method); 2605 1.1 elric } 2606 1.1 elric free(csec); 2607 1.1 elric free(cusec); 2608 1.1 elric if (ticket) 2609 1.1 elric krb5_free_ticket(context, ticket); 2610 1.1 elric if(krbtgt) 2611 1.1 elric _kdc_free_ent(context, krbtgt); 2612 1.1 elric 2613 1.1 elric if (auth_data) { 2614 1.1 elric free_AuthorizationData(auth_data); 2615 1.1 elric free(auth_data); 2616 1.1 elric } 2617 1.1 elric 2618 1.1 elric return ret; 2619 1.1 elric } 2620