Changeset 745 for trunk/server/source4/heimdal/kdc/krb5tgs.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/heimdal/kdc/krb5tgs.c
r414 r745 34 34 #include "kdc_locl.h" 35 35 36 RCSID("$Id$");37 38 36 /* 39 37 * return the realm of a krbtgt-ticket or NULL … … 107 105 hdb_entry_ex *krbtgt, 108 106 krb5_enctype enctype, 107 krb5_principal client, 109 108 krb5_const_principal server, 110 109 krb5_principals principals, … … 126 125 KRB5SignedPathData spd; 127 126 128 spd.encticket = *tkt; 127 spd.client = client; 128 spd.authtime = tkt->authtime; 129 129 spd.delegated = principals; 130 spd.method_data = NULL; 130 131 131 132 ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, … … 154 155 sp.etype = enctype; 155 156 sp.delegated = principals; 157 sp.method_data = NULL; 156 158 157 159 ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0, … … 186 188 krb5_kdc_configuration *config, 187 189 hdb_entry_ex *krbtgt, 190 krb5_principal cp, 188 191 EncTicketPart *tkt, 189 192 krb5_principals *delegated, … … 201 204 KRB5SignedPathData spd; 202 205 KRB5SignedPath sp; 203 AuthorizationData *ad;204 206 size_t size; 205 207 … … 209 211 return ret; 210 212 211 spd.encticket = *tkt; 212 /* the KRB5SignedPath is the last entry */ 213 ad = spd.encticket.authorization_data; 214 if (--ad->len == 0) 215 spd.encticket.authorization_data = NULL; 213 spd.client = cp; 214 spd.authtime = tkt->authtime; 216 215 spd.delegated = sp.delegated; 216 spd.method_data = sp.method_data; 217 217 218 218 ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, 219 219 &spd, &size, ret); 220 ad->len++;221 spd.encticket.authorization_data = ad;222 220 if (ret) { 223 221 free_KRB5SignedPath(&sp); … … 245 243 if (ret) { 246 244 free_KRB5SignedPath(&sp); 247 return ret; 245 kdc_log(context, config, 5, 246 "KRB5SignedPath not signed correctly, not marking as signed"); 247 return 0; 248 248 } 249 249 … … 282 282 hdb_entry_ex *client, 283 283 hdb_entry_ex *server, 284 hdb_entry_ex *krbtgt, 284 285 const EncryptionKey *server_key, 285 const EncryptionKey *krbtgt_key, 286 const EncryptionKey *krbtgt_check_key, 287 const EncryptionKey *krbtgt_sign_key, 286 288 EncTicketPart *tkt, 287 289 krb5_data *rspac, … … 313 315 314 316 if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { 317 int signed_pac = 0; 315 318 krb5_pac pac; 316 319 … … 326 329 ret = krb5_pac_verify(context, pac, tkt->authtime, 327 330 client_principal, 328 krbtgt_ key, NULL);331 krbtgt_check_key, NULL); 329 332 if (ret) { 330 333 krb5_pac_free(context, pac); … … 333 336 334 337 ret = _kdc_pac_verify(context, client_principal, 335 client, server, &pac);338 client, server, krbtgt, &pac, &signed_pac); 336 339 if (ret) { 337 340 krb5_pac_free(context, pac); 338 341 return ret; 339 342 } 340 *signedpath = 1; 341 342 ret = _krb5_pac_sign(context, pac, tkt->authtime, 343 client_principal, 344 server_key, krbtgt_key, rspac); 345 343 344 /* 345 * Only re-sign PAC if we could verify it with the PAC 346 * function. The no-verify case happens when we get in 347 * a PAC from cross realm from a Windows domain and 348 * that there is no PAC verification function. 349 */ 350 if (signed_pac) { 351 *signedpath = 1; 352 ret = _krb5_pac_sign(context, pac, tkt->authtime, 353 client_principal, 354 server_key, krbtgt_sign_key, rspac); 355 } 346 356 krb5_pac_free(context, pac); 347 357 348 358 return ret; 349 359 } … … 448 458 449 459 if(f.renewable){ 450 if(!tgt->flags.renewable ){460 if(!tgt->flags.renewable || tgt->renew_till == NULL){ 451 461 kdc_log(context, config, 0, 452 462 "Bad request for renewable ticket"); … … 487 497 488 498 /* 489 * 499 * Determine if constrained delegation is allowed from this client to this server 490 500 */ 491 501 … … 526 536 kdc_log(context, config, 0, 527 537 "Bad request for constrained delegation"); 538 return ret; 539 } 540 541 /* 542 * Determine if s4u2self is allowed from this client to this server 543 * 544 * For example, regardless of the principal being impersonated, if the 545 * 'client' and 'server' are the same, then it's safe. 546 */ 547 548 static krb5_error_code 549 check_s4u2self(krb5_context context, 550 krb5_kdc_configuration *config, 551 HDB *clientdb, 552 hdb_entry_ex *client, 553 krb5_const_principal server) 554 { 555 krb5_error_code ret; 556 557 /* if client does a s4u2self to itself, that ok */ 558 if (krb5_principal_compare(context, client->entry.principal, server) == TRUE) 559 return 0; 560 561 if (clientdb->hdb_check_s4u2self) { 562 ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server); 563 if (ret == 0) 564 return 0; 565 } else { 566 ret = KRB5KDC_ERR_BADOPTION; 567 } 528 568 return ret; 529 569 } … … 670 710 krb5_const_principal tgt_name, 671 711 const EncTicketPart *tgt, 712 const krb5_keyblock *replykey, 713 int rk_is_subkey, 672 714 const EncryptionKey *serverkey, 673 715 const krb5_keyblock *sessionkey, … … 769 811 } 770 812 if(f.renewable_ok && tgt->flags.renewable && 771 et.renew_till == NULL && et.endtime < *b->till){ 813 et.renew_till == NULL && et.endtime < *b->till && 814 tgt->renew_till != NULL) 815 { 772 816 et.flags.renewable = 1; 773 817 ALLOC(et.renew_till); … … 822 866 823 867 /* XXX check authdata */ 868 824 869 if (et.authorization_data == NULL) { 825 ret = ENOMEM; 826 krb5_set_error_message(context, ret, "malloc: out of memory"); 827 goto out; 870 et.authorization_data = calloc(1, sizeof(*et.authorization_data)); 871 if (et.authorization_data == NULL) { 872 ret = ENOMEM; 873 krb5_set_error_message(context, ret, "malloc: out of memory"); 874 goto out; 875 } 828 876 } 829 877 for(i = 0; i < auth_data->len ; i++) { … … 885 933 krbtgt, 886 934 krbtgt_etype, 935 client_principal, 887 936 NULL, 888 937 spp, … … 925 974 &rep, &et, &ek, et.key.keytype, 926 975 kvno, 927 serverkey, 0, &tgt->key, e_text, reply); 976 serverkey, 0, replykey, rk_is_subkey, 977 e_text, reply); 928 978 if (is_weak) 929 979 krb5_enctype_disable(context, et.key.keytype); … … 986 1036 ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret); 987 1037 if(ret){ 988 kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", 989 krb5_get_err_text(context, ret)); 1038 const char *msg = krb5_get_error_message(context, ret); 1039 kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", msg); 1040 krb5_free_error_message(context, msg); 990 1041 goto out; 991 1042 } … … 999 1050 ret = krb5_crypto_init(context, key, 0, &crypto); 1000 1051 if (ret) { 1052 const char *msg = krb5_get_error_message(context, ret); 1001 1053 free(buf); 1002 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", 1003 krb5_get_err_text(context, ret));1054 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 1055 krb5_free_error_message(context, msg); 1004 1056 goto out; 1005 1057 } … … 1013 1065 krb5_crypto_destroy(context, crypto); 1014 1066 if(ret){ 1067 const char *msg = krb5_get_error_message(context, ret); 1015 1068 kdc_log(context, config, 0, 1016 "Failed to verify authenticator checksum: %s", 1017 krb5_get_err_text(context, ret));1069 "Failed to verify authenticator checksum: %s", msg); 1070 krb5_free_error_message(context, msg); 1018 1071 } 1019 1072 out: … … 1075 1128 time_t **csec, 1076 1129 int **cusec, 1077 AuthorizationData **auth_data) 1130 AuthorizationData **auth_data, 1131 krb5_keyblock **replykey, 1132 int *rk_is_subkey) 1078 1133 { 1079 1134 krb5_ap_req ap_req; … … 1085 1140 krb5_crypto crypto; 1086 1141 Key *tkey; 1142 krb5_keyblock *subkey = NULL; 1143 unsigned usage; 1087 1144 1088 1145 *auth_data = NULL; 1089 1146 *csec = NULL; 1090 1147 *cusec = NULL; 1148 *replykey = NULL; 1091 1149 1092 1150 memset(&ap_req, 0, sizeof(ap_req)); 1093 1151 ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req); 1094 1152 if(ret){ 1095 kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", 1096 krb5_get_err_text(context, ret)); 1153 const char *msg = krb5_get_error_message(context, ret); 1154 kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", msg); 1155 krb5_free_error_message(context, msg); 1097 1156 goto out; 1098 1157 } … … 1110 1169 ap_req.ticket.realm); 1111 1170 1112 ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt); 1113 1114 if(ret) { 1171 ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, ap_req.ticket.enc_part.kvno, NULL, krbtgt); 1172 1173 if(ret == HDB_ERR_NOT_FOUND_HERE) { 1174 char *p; 1175 ret = krb5_unparse_name(context, princ, &p); 1176 if (ret != 0) 1177 p = "<unparse_name failed>"; 1178 krb5_free_principal(context, princ); 1179 kdc_log(context, config, 5, "Ticket-granting ticket account %s does not have secrets at this KDC, need to proxy", p); 1180 if (ret == 0) 1181 free(p); 1182 ret = HDB_ERR_NOT_FOUND_HERE; 1183 goto out; 1184 } else if(ret){ 1185 const char *msg = krb5_get_error_message(context, ret); 1115 1186 char *p; 1116 1187 ret = krb5_unparse_name(context, princ, &p); … … 1119 1190 krb5_free_principal(context, princ); 1120 1191 kdc_log(context, config, 0, 1121 "Ticket-granting ticket not found in database: %s : %s",1122 p, krb5_get_err_text(context, ret));1192 "Ticket-granting ticket not found in database: %s", msg); 1193 krb5_free_error_message(context, msg); 1123 1194 if (ret == 0) 1124 1195 free(p); … … 1182 1253 krb5_free_principal(context, princ); 1183 1254 if(ret) { 1184 kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", 1185 krb5_get_err_text(context, ret)); 1255 const char *msg = krb5_get_error_message(context, ret); 1256 kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", msg); 1257 krb5_free_error_message(context, msg); 1186 1258 goto out; 1187 1259 } … … 1217 1289 } 1218 1290 1291 usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY; 1292 *rk_is_subkey = 1; 1293 1294 ret = krb5_auth_con_getremotesubkey(context, ac, &subkey); 1295 if(ret){ 1296 const char *msg = krb5_get_error_message(context, ret); 1297 krb5_auth_con_free(context, ac); 1298 kdc_log(context, config, 0, "Failed to get remote subkey: %s", msg); 1299 krb5_free_error_message(context, msg); 1300 goto out; 1301 } 1302 if(subkey == NULL){ 1303 usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION; 1304 *rk_is_subkey = 0; 1305 1306 ret = krb5_auth_con_getkey(context, ac, &subkey); 1307 if(ret) { 1308 const char *msg = krb5_get_error_message(context, ret); 1309 krb5_auth_con_free(context, ac); 1310 kdc_log(context, config, 0, "Failed to get session key: %s", msg); 1311 krb5_free_error_message(context, msg); 1312 goto out; 1313 } 1314 } 1315 if(subkey == NULL){ 1316 krb5_auth_con_free(context, ac); 1317 kdc_log(context, config, 0, 1318 "Failed to get key for enc-authorization-data"); 1319 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1320 goto out; 1321 } 1322 1323 *replykey = subkey; 1324 1219 1325 if (b->enc_authorization_data) { 1220 unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;1221 krb5_keyblock *subkey;1222 1326 krb5_data ad; 1223 1327 1224 ret = krb5_auth_con_getremotesubkey(context, ac, &subkey); 1225 if(ret){ 1328 ret = krb5_crypto_init(context, subkey, 0, &crypto); 1329 if (ret) { 1330 const char *msg = krb5_get_error_message(context, ret); 1226 1331 krb5_auth_con_free(context, ac); 1227 kdc_log(context, config, 0, "Failed to get remote subkey: %s", 1228 krb5_get_err_text(context, ret)); 1229 goto out; 1230 } 1231 if(subkey == NULL){ 1232 usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION; 1233 ret = krb5_auth_con_getkey(context, ac, &subkey); 1234 if(ret) { 1235 krb5_auth_con_free(context, ac); 1236 kdc_log(context, config, 0, "Failed to get session key: %s", 1237 krb5_get_err_text(context, ret)); 1238 goto out; 1239 } 1240 } 1241 if(subkey == NULL){ 1242 krb5_auth_con_free(context, ac); 1243 kdc_log(context, config, 0, 1244 "Failed to get key for enc-authorization-data"); 1245 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ 1246 goto out; 1247 } 1248 ret = krb5_crypto_init(context, subkey, 0, &crypto); 1249 krb5_free_keyblock(context, subkey); 1250 if (ret) { 1251 krb5_auth_con_free(context, ac); 1252 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", 1253 krb5_get_err_text(context, ret)); 1332 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 1333 krb5_free_error_message(context, msg); 1254 1334 goto out; 1255 1335 } … … 1375 1455 hdb_entry_ex *krbtgt, 1376 1456 krb5_enctype krbtgt_etype, 1457 const krb5_keyblock *replykey, 1458 int rk_is_subkey, 1377 1459 krb5_ticket *ticket, 1378 1460 krb5_data *reply, … … 1385 1467 krb5_principal cp = NULL, sp = NULL; 1386 1468 krb5_principal client_principal = NULL; 1469 krb5_principal krbtgt_principal = NULL; 1387 1470 char *spn = NULL, *cpn = NULL; 1388 hdb_entry_ex *server = NULL, *client = NULL ;1389 HDB *clientdb ;1471 hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; 1472 HDB *clientdb, *s4u2self_impersonated_clientdb; 1390 1473 krb5_realm ref_realm = NULL; 1391 1474 EncTicketPart *tgt = &ticket->ticket; … … 1396 1479 krb5_data rspac; 1397 1480 1481 hdb_entry_ex *krbtgt_out = NULL; 1482 1398 1483 METHOD_DATA enc_pa_data; 1399 1484 … … 1405 1490 int signedpath = 0; 1406 1491 1407 Key *tkey; 1492 Key *tkey_check; 1493 Key *tkey_sign; 1408 1494 1409 1495 memset(&sessionkey, 0, sizeof(sessionkey)); … … 1437 1523 _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm); 1438 1524 ret = _kdc_db_fetch(context, config, p, 1439 HDB_F_GET_ CLIENT|HDB_F_GET_SERVER,1525 HDB_F_GET_KRBTGT, t->enc_part.kvno, 1440 1526 NULL, &uu); 1441 1527 krb5_free_principal(context, p); … … 1490 1576 server_lookup: 1491 1577 ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | HDB_F_CANON, 1492 NULL, &server); 1493 1494 if(ret){ 1495 const char *new_rlm; 1578 NULL, NULL, &server); 1579 1580 if(ret == HDB_ERR_NOT_FOUND_HERE) { 1581 kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp); 1582 goto out; 1583 } else if(ret){ 1584 const char *new_rlm, *msg; 1496 1585 Realm req_rlm; 1497 1586 krb5_realm *realms; … … 1541 1630 krb5_free_host_realm(context, realms); 1542 1631 } 1632 msg = krb5_get_error_message(context, ret); 1543 1633 kdc_log(context, config, 0, 1544 "Server not found in database: %s: %s", spn, 1545 krb5_get_err_text(context, ret));1634 "Server not found in database: %s: %s", spn, msg); 1635 krb5_free_error_message(context, msg); 1546 1636 if (ret == HDB_ERR_NOENTRY) 1547 1637 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 1548 1638 goto out; 1549 }1550 1551 ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,1552 &clientdb, &client);1553 if(ret) {1554 const char *krbtgt_realm;1555 1556 /*1557 * If the client belongs to the same realm as our krbtgt, it1558 * should exist in the local database.1559 *1560 */1561 1562 krbtgt_realm =1563 krb5_principal_get_comp_string(context,1564 krbtgt->entry.principal, 1);1565 1566 if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {1567 if (ret == HDB_ERR_NOENTRY)1568 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;1569 kdc_log(context, config, 1, "Client no longer in database: %s",1570 cpn);1571 goto out;1572 }1573 1574 kdc_log(context, config, 1, "Client not found in database: %s: %s",1575 cpn, krb5_get_err_text(context, ret));1576 1639 } 1577 1640 … … 1601 1664 Key *skey; 1602 1665 1603 ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,1604 &skey, &etype);1666 ret = _kdc_find_etype(context, server, 1667 b->etype.val, b->etype.len, &skey); 1605 1668 if(ret) { 1606 1669 kdc_log(context, config, 0, … … 1609 1672 } 1610 1673 ekey = &skey->key; 1674 etype = skey->key.keytype; 1611 1675 kvno = server->entry.kvno; 1612 1676 } … … 1623 1687 */ 1624 1688 1625 if (strcmp(krb5_principal_get_realm(context, sp), 1626 krb5_principal_get_comp_string(context, 1627 krbtgt->entry.principal, 1628 1)) != 0) { 1689 /* 1690 * Validate authoriation data 1691 */ 1692 1693 ret = hdb_enctype2key(context, &krbtgt->entry, 1694 krbtgt_etype, &tkey_check); 1695 if(ret) { 1696 kdc_log(context, config, 0, 1697 "Failed to find key for krbtgt PAC check"); 1698 goto out; 1699 } 1700 1701 /* Now refetch the primary krbtgt, and get the current kvno (the 1702 * sign check may have been on an old kvno, and the server may 1703 * have been an incoming trust) */ 1704 ret = krb5_make_principal(context, &krbtgt_principal, 1705 krb5_principal_get_comp_string(context, 1706 krbtgt->entry.principal, 1707 1), 1708 KRB5_TGS_NAME, 1709 krb5_principal_get_comp_string(context, 1710 krbtgt->entry.principal, 1711 1), NULL); 1712 if(ret) { 1713 kdc_log(context, config, 0, 1714 "Failed to generate krbtgt principal"); 1715 goto out; 1716 } 1717 1718 ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out); 1719 krb5_free_principal(context, krbtgt_principal); 1720 if (ret) { 1721 krb5_error_code ret2; 1722 char *tpn, *tpn2; 1723 ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn); 1724 ret2 = krb5_unparse_name(context, krbtgt->entry.principal, &tpn2); 1725 kdc_log(context, config, 0, 1726 "Request with wrong krbtgt: %s, %s not found in our database", 1727 (ret == 0) ? tpn : "<unknown>", (ret2 == 0) ? tpn2 : "<unknown>"); 1728 if(ret == 0) 1729 free(tpn); 1730 if(ret2 == 0) 1731 free(tpn2); 1732 ret = KRB5KRB_AP_ERR_NOT_US; 1733 goto out; 1734 } 1735 1736 /* The first realm is the realm of the service, the second is 1737 * krbtgt/<this>/@REALM component of the krbtgt DN the request was 1738 * encrypted to. The redirection via the krbtgt_out entry allows 1739 * the DB to possibly correct the case of the realm (Samba4 does 1740 * this) before the strcmp() */ 1741 if (strcmp(krb5_principal_get_realm(context, server->entry.principal), 1742 krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) { 1629 1743 char *tpn; 1630 ret = krb5_unparse_name(context, krbtgt ->entry.principal, &tpn);1744 ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &tpn); 1631 1745 kdc_log(context, config, 0, 1632 1746 "Request with wrong krbtgt: %s", … … 1635 1749 free(tpn); 1636 1750 ret = KRB5KRB_AP_ERR_NOT_US; 1637 goto out; 1638 } 1639 1640 /* 1641 * Validate authoriation data 1642 */ 1643 1644 ret = hdb_enctype2key(context, &krbtgt->entry, 1645 krbtgt_etype, &tkey); 1751 } 1752 1753 ret = hdb_enctype2key(context, &krbtgt_out->entry, 1754 krbtgt_etype, &tkey_sign); 1646 1755 if(ret) { 1647 1756 kdc_log(context, config, 0, 1648 "Failed to find key for krbtgt PAC check"); 1649 goto out; 1757 "Failed to find key for krbtgt PAC signature"); 1758 goto out; 1759 } 1760 1761 ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON, 1762 NULL, &clientdb, &client); 1763 if(ret == HDB_ERR_NOT_FOUND_HERE) { 1764 /* This is OK, we are just trying to find out if they have 1765 * been disabled or deleted in the meantime, missing secrets 1766 * is OK */ 1767 } else if(ret){ 1768 const char *krbtgt_realm, *msg; 1769 1770 /* 1771 * If the client belongs to the same realm as our krbtgt, it 1772 * should exist in the local database. 1773 * 1774 */ 1775 1776 krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal); 1777 1778 if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { 1779 if (ret == HDB_ERR_NOENTRY) 1780 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 1781 kdc_log(context, config, 1, "Client no longer in database: %s", 1782 cpn); 1783 goto out; 1784 } 1785 1786 msg = krb5_get_error_message(context, ret); 1787 kdc_log(context, config, 1, "Client not found in database: %s", msg); 1788 krb5_free_error_message(context, msg); 1650 1789 } 1651 1790 1652 1791 ret = check_PAC(context, config, cp, 1653 client, server, ekey, &tkey->key,1792 client, server, krbtgt, ekey, &tkey_check->key, &tkey_sign->key, 1654 1793 tgt, &rspac, &signedpath); 1655 1794 if (ret) { 1795 const char *msg = krb5_get_error_message(context, ret); 1656 1796 kdc_log(context, config, 0, 1657 1797 "Verify PAC failed for %s (%s) from %s with %s", 1658 spn, cpn, from, krb5_get_err_text(context, ret)); 1798 spn, cpn, from, msg); 1799 krb5_free_error_message(context, msg); 1659 1800 goto out; 1660 1801 } … … 1664 1805 config, 1665 1806 krbtgt, 1807 cp, 1666 1808 tgt, 1667 1809 &spp, 1668 1810 &signedpath); 1669 1811 if (ret) { 1812 const char *msg = krb5_get_error_message(context, ret); 1670 1813 kdc_log(context, config, 0, 1671 1814 "KRB5SignedPath check failed for %s (%s) from %s with %s", 1672 spn, cpn, from, krb5_get_err_text(context, ret)); 1815 spn, cpn, from, msg); 1816 krb5_free_error_message(context, msg); 1673 1817 goto out; 1674 1818 } … … 1706 1850 ret = krb5_crypto_init(context, &tgt->key, 0, &crypto); 1707 1851 if (ret) { 1852 const char *msg = krb5_get_error_message(context, ret); 1708 1853 free_PA_S4U2Self(&self); 1709 1854 krb5_data_free(&datack); 1710 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", 1711 krb5_get_err_text(context, ret));1855 kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg); 1856 krb5_free_error_message(context, msg); 1712 1857 goto out; 1713 1858 } … … 1722 1867 krb5_crypto_destroy(context, crypto); 1723 1868 if (ret) { 1869 const char *msg = krb5_get_error_message(context, ret); 1724 1870 free_PA_S4U2Self(&self); 1725 1871 kdc_log(context, config, 0, 1726 "krb5_verify_checksum failed for S4U2Self: %s", 1727 krb5_get_err_text(context, ret));1872 "krb5_verify_checksum failed for S4U2Self: %s", msg); 1873 krb5_free_error_message(context, msg); 1728 1874 goto out; 1729 1875 } … … 1741 1887 goto out; 1742 1888 1889 /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */ 1890 if(rspac.data) { 1891 krb5_pac p = NULL; 1892 krb5_data_free(&rspac); 1893 ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON, 1894 NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client); 1895 if (ret) { 1896 const char *msg; 1897 1898 /* 1899 * If the client belongs to the same realm as our krbtgt, it 1900 * should exist in the local database. 1901 * 1902 */ 1903 1904 if (ret == HDB_ERR_NOENTRY) 1905 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 1906 msg = krb5_get_error_message(context, ret); 1907 kdc_log(context, config, 1, "S2U4Self principal to impersonate %s not found in database: %s", cpn, msg); 1908 krb5_free_error_message(context, msg); 1909 goto out; 1910 } 1911 ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p); 1912 if (ret) { 1913 kdc_log(context, config, 0, "PAC generation failed for -- %s", 1914 selfcpn); 1915 goto out; 1916 } 1917 if (p != NULL) { 1918 ret = _krb5_pac_sign(context, p, ticket->ticket.authtime, 1919 s4u2self_impersonated_client->entry.principal, 1920 ekey, &tkey_sign->key, 1921 &rspac); 1922 krb5_pac_free(context, p); 1923 if (ret) { 1924 kdc_log(context, config, 0, "PAC signing failed for -- %s", 1925 selfcpn); 1926 goto out; 1927 } 1928 } 1929 } 1930 1743 1931 /* 1744 1932 * Check that service doing the impersonating is 1745 1933 * requesting a ticket to it-self. 1746 1934 */ 1747 if (krb5_principal_compare(context, cp, sp) != TRUE) { 1935 ret = check_s4u2self(context, config, clientdb, client, sp); 1936 if (ret) { 1748 1937 kdc_log(context, config, 0, "S4U2Self: %s is not allowed " 1749 "to impersonate some other user"1938 "to impersonate to service " 1750 1939 "(tried for user %s to service %s)", 1751 1940 cpn, selfcpn, spn); 1752 1941 free(selfcpn); 1753 ret = KRB5KDC_ERR_BADOPTION; /* ? */1754 1942 goto out; 1755 1943 } … … 1856 2044 config, 1857 2045 krbtgt, 2046 cp, 1858 2047 &adtkt, 1859 2048 NULL, … … 1862 2051 ret = KRB5KDC_ERR_BADOPTION; 1863 2052 if (ret) { 2053 const char *msg = krb5_get_error_message(context, ret); 1864 2054 kdc_log(context, config, 0, 1865 2055 "KRB5SignedPath check from service %s failed " 1866 2056 "for delegation to %s for client %s " 1867 2057 "from %s failed with %s", 1868 spn, str, cpn, from, krb5_get_err_text(context, ret)); 2058 spn, str, cpn, from, msg); 2059 krb5_free_error_message(context, msg); 1869 2060 free(str); 1870 2061 goto out; … … 1946 2137 client_principal, 1947 2138 tgt, 2139 replykey, 2140 rk_is_subkey, 1948 2141 ekey, 1949 2142 &sessionkey, … … 1951 2144 *auth_data, 1952 2145 server, 1953 s p,2146 server->entry.principal, 1954 2147 spn, 1955 2148 client, 1956 2149 cp, 1957 krbtgt ,2150 krbtgt_out, 1958 2151 krbtgt_etype, 1959 2152 spp, … … 1969 2162 krb5_data_free(&rspac); 1970 2163 krb5_free_keyblock_contents(context, &sessionkey); 2164 if(krbtgt_out) 2165 _kdc_free_ent(context, krbtgt_out); 1971 2166 if(server) 1972 2167 _kdc_free_ent(context, server); 1973 2168 if(client) 1974 2169 _kdc_free_ent(context, client); 2170 if(s4u2self_impersonated_client) 2171 _kdc_free_ent(context, s4u2self_impersonated_client); 1975 2172 1976 2173 if (client_principal && client_principal != cp) … … 2012 2209 krb5_enctype krbtgt_etype = ETYPE_NULL; 2013 2210 2211 krb5_keyblock *replykey = NULL; 2212 int rk_is_subkey = 0; 2014 2213 time_t *csec = NULL; 2015 2214 int *cusec = NULL; … … 2039 2238 from, from_addr, 2040 2239 &csec, &cusec, 2041 &auth_data); 2240 &auth_data, 2241 &replykey, 2242 &rk_is_subkey); 2243 if (ret == HDB_ERR_NOT_FOUND_HERE) { 2244 /* kdc_log() is called in tgs_parse_request() */ 2245 goto out; 2246 } 2042 2247 if (ret) { 2043 2248 kdc_log(context, config, 0, … … 2052 2257 krbtgt, 2053 2258 krbtgt_etype, 2259 replykey, 2260 rk_is_subkey, 2054 2261 ticket, 2055 2262 data, … … 2072 2279 2073 2280 out: 2074 if(ret && data->data == NULL){ 2281 if (replykey) 2282 krb5_free_keyblock(context, replykey); 2283 if(ret && ret != HDB_ERR_NOT_FOUND_HERE && data->data == NULL){ 2075 2284 krb5_mk_error(context, 2076 2285 ret, … … 2082 2291 cusec, 2083 2292 data); 2293 ret = 0; 2084 2294 } 2085 2295 free(csec); … … 2095 2305 } 2096 2306 2097 return 0;2307 return ret; 2098 2308 }
Note:
See TracChangeset
for help on using the changeset viewer.