Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/heimdal/kdc/krb5tgs.c

    r414 r745  
    3434#include "kdc_locl.h"
    3535
    36 RCSID("$Id$");
    37 
    3836/*
    3937 * return the realm of a krbtgt-ticket or NULL
     
    107105                        hdb_entry_ex *krbtgt,
    108106                        krb5_enctype enctype,
     107                        krb5_principal client,
    109108                        krb5_const_principal server,
    110109                        krb5_principals principals,
     
    126125        KRB5SignedPathData spd;
    127126       
    128         spd.encticket = *tkt;
     127        spd.client = client;
     128        spd.authtime = tkt->authtime;
    129129        spd.delegated = principals;
     130        spd.method_data = NULL;
    130131       
    131132        ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
     
    154155    sp.etype = enctype;
    155156    sp.delegated = principals;
     157    sp.method_data = NULL;
    156158
    157159    ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,
     
    186188                     krb5_kdc_configuration *config,
    187189                     hdb_entry_ex *krbtgt,
     190                     krb5_principal cp,
    188191                     EncTicketPart *tkt,
    189192                     krb5_principals *delegated,
     
    201204        KRB5SignedPathData spd;
    202205        KRB5SignedPath sp;
    203         AuthorizationData *ad;
    204206        size_t size;
    205207
     
    209211            return ret;
    210212
    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;
    216215        spd.delegated = sp.delegated;
     216        spd.method_data = sp.method_data;
    217217
    218218        ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
    219219                           &spd, &size, ret);
    220         ad->len++;
    221         spd.encticket.authorization_data = ad;
    222220        if (ret) {
    223221            free_KRB5SignedPath(&sp);
     
    245243        if (ret) {
    246244            free_KRB5SignedPath(&sp);
    247             return ret;
     245            kdc_log(context, config, 5,
     246                    "KRB5SignedPath not signed correctly, not marking as signed");
     247            return 0;
    248248        }
    249249
     
    282282          hdb_entry_ex *client,
    283283          hdb_entry_ex *server,
     284          hdb_entry_ex *krbtgt,
    284285          const EncryptionKey *server_key,
    285           const EncryptionKey *krbtgt_key,
     286          const EncryptionKey *krbtgt_check_key,
     287          const EncryptionKey *krbtgt_sign_key,
    286288          EncTicketPart *tkt,
    287289          krb5_data *rspac,
     
    313315
    314316            if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) {
     317                int signed_pac = 0;
    315318                krb5_pac pac;
    316319
     
    326329                ret = krb5_pac_verify(context, pac, tkt->authtime,
    327330                                      client_principal,
    328                                       krbtgt_key, NULL);
     331                                      krbtgt_check_key, NULL);
    329332                if (ret) {
    330333                    krb5_pac_free(context, pac);
     
    333336
    334337                ret = _kdc_pac_verify(context, client_principal,
    335                                       client, server, &pac);
     338                                      client, server, krbtgt, &pac, &signed_pac);
    336339                if (ret) {
    337340                    krb5_pac_free(context, pac);
    338341                    return ret;
    339342                }
    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                }
    346356                krb5_pac_free(context, pac);
    347 
     357               
    348358                return ret;
    349359            }
     
    448458
    449459    if(f.renewable){
    450         if(!tgt->flags.renewable){
     460        if(!tgt->flags.renewable || tgt->renew_till == NULL){
    451461            kdc_log(context, config, 0,
    452462                    "Bad request for renewable ticket");
     
    487497
    488498/*
    489  *
     499 * Determine if constrained delegation is allowed from this client to this server
    490500 */
    491501
     
    526536    kdc_log(context, config, 0,
    527537            "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
     548static krb5_error_code
     549check_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    }
    528568    return ret;
    529569}
     
    670710               krb5_const_principal tgt_name,
    671711               const EncTicketPart *tgt,
     712               const krb5_keyblock *replykey,
     713               int rk_is_subkey,
    672714               const EncryptionKey *serverkey,
    673715               const krb5_keyblock *sessionkey,
     
    769811    }
    770812    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    {
    772816        et.flags.renewable = 1;
    773817        ALLOC(et.renew_till);
     
    822866
    823867        /* XXX check authdata */
     868
    824869        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            }
    828876        }
    829877        for(i = 0; i < auth_data->len ; i++) {
     
    885933                                          krbtgt,
    886934                                          krbtgt_etype,
     935                                          client_principal,
    887936                                          NULL,
    888937                                          spp,
     
    925974                            &rep, &et, &ek, et.key.keytype,
    926975                            kvno,
    927                             serverkey, 0, &tgt->key, e_text, reply);
     976                            serverkey, 0, replykey, rk_is_subkey,
     977                            e_text, reply);
    928978    if (is_weak)
    929979        krb5_enctype_disable(context, et.key.keytype);
     
    9861036    ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
    9871037    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);
    9901041        goto out;
    9911042    }
     
    9991050    ret = krb5_crypto_init(context, key, 0, &crypto);
    10001051    if (ret) {
     1052        const char *msg = krb5_get_error_message(context, ret);
    10011053        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);
    10041056        goto out;
    10051057    }
     
    10131065    krb5_crypto_destroy(context, crypto);
    10141066    if(ret){
     1067        const char *msg = krb5_get_error_message(context, ret);
    10151068        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);
    10181071    }
    10191072out:
     
    10751128                  time_t **csec,
    10761129                  int **cusec,
    1077                   AuthorizationData **auth_data)
     1130                  AuthorizationData **auth_data,
     1131                  krb5_keyblock **replykey,
     1132                  int *rk_is_subkey)
    10781133{
    10791134    krb5_ap_req ap_req;
     
    10851140    krb5_crypto crypto;
    10861141    Key *tkey;
     1142    krb5_keyblock *subkey = NULL;
     1143    unsigned usage;
    10871144
    10881145    *auth_data = NULL;
    10891146    *csec  = NULL;
    10901147    *cusec = NULL;
     1148    *replykey = NULL;
    10911149
    10921150    memset(&ap_req, 0, sizeof(ap_req));
    10931151    ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
    10941152    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);
    10971156        goto out;
    10981157    }
     
    11101169                                       ap_req.ticket.realm);
    11111170
    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);
    11151186        char *p;
    11161187        ret = krb5_unparse_name(context, princ, &p);
     
    11191190        krb5_free_principal(context, princ);
    11201191        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);
    11231194        if (ret == 0)
    11241195            free(p);
     
    11821253    krb5_free_principal(context, princ);
    11831254    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);
    11861258        goto out;
    11871259    }
     
    12171289    }
    12181290
     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
    12191325    if (b->enc_authorization_data) {
    1220         unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
    1221         krb5_keyblock *subkey;
    12221326        krb5_data ad;
    12231327
    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);
    12261331            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);
    12541334            goto out;
    12551335        }
     
    13751455                hdb_entry_ex *krbtgt,
    13761456                krb5_enctype krbtgt_etype,
     1457                const krb5_keyblock *replykey,
     1458                int rk_is_subkey,
    13771459                krb5_ticket *ticket,
    13781460                krb5_data *reply,
     
    13851467    krb5_principal cp = NULL, sp = NULL;
    13861468    krb5_principal client_principal = NULL;
     1469    krb5_principal krbtgt_principal = NULL;
    13871470    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;
    13901473    krb5_realm ref_realm = NULL;
    13911474    EncTicketPart *tgt = &ticket->ticket;
     
    13961479    krb5_data rspac;
    13971480
     1481    hdb_entry_ex *krbtgt_out = NULL;
     1482
    13981483    METHOD_DATA enc_pa_data;
    13991484
     
    14051490    int signedpath = 0;
    14061491
    1407     Key *tkey;
     1492    Key *tkey_check;
     1493    Key *tkey_sign;
    14081494
    14091495    memset(&sessionkey, 0, sizeof(sessionkey));
     
    14371523        _krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
    14381524        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,
    14401526                            NULL, &uu);
    14411527        krb5_free_principal(context, p);
     
    14901576server_lookup:
    14911577    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;
    14961585        Realm req_rlm;
    14971586        krb5_realm *realms;
     
    15411630            krb5_free_host_realm(context, realms);
    15421631        }
     1632        msg = krb5_get_error_message(context, ret);
    15431633        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);
    15461636        if (ret == HDB_ERR_NOENTRY)
    15471637            ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
    15481638        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, it
    1558          * 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));
    15761639    }
    15771640
     
    16011664            Key *skey;
    16021665       
    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);
    16051668            if(ret) {
    16061669                kdc_log(context, config, 0,
     
    16091672            }
    16101673            ekey = &skey->key;
     1674            etype = skey->key.keytype;
    16111675            kvno = server->entry.kvno;
    16121676        }
     
    16231687     */
    16241688
    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) {
    16291743        char *tpn;
    1630         ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
     1744        ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &tpn);
    16311745        kdc_log(context, config, 0,
    16321746                "Request with wrong krbtgt: %s",
     
    16351749            free(tpn);
    16361750        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);
    16461755    if(ret) {
    16471756        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);
    16501789    }
    16511790
    16521791    ret = check_PAC(context, config, cp,
    1653                     client, server, ekey, &tkey->key,
     1792                    client, server, krbtgt, ekey, &tkey_check->key, &tkey_sign->key,
    16541793                    tgt, &rspac, &signedpath);
    16551794    if (ret) {
     1795        const char *msg = krb5_get_error_message(context, ret);
    16561796        kdc_log(context, config, 0,
    16571797                "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);
    16591800        goto out;
    16601801    }
     
    16641805                               config,
    16651806                               krbtgt,
     1807                               cp,
    16661808                               tgt,
    16671809                               &spp,
    16681810                               &signedpath);
    16691811    if (ret) {
     1812        const char *msg = krb5_get_error_message(context, ret);
    16701813        kdc_log(context, config, 0,
    16711814                "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);
    16731817        goto out;
    16741818    }
     
    17061850            ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
    17071851            if (ret) {
     1852                const char *msg = krb5_get_error_message(context, ret);
    17081853                free_PA_S4U2Self(&self);
    17091854                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);
    17121857                goto out;
    17131858            }
     
    17221867            krb5_crypto_destroy(context, crypto);
    17231868            if (ret) {
     1869                const char *msg = krb5_get_error_message(context, ret);
    17241870                free_PA_S4U2Self(&self);
    17251871                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);
    17281874                goto out;
    17291875            }
     
    17411887                goto out;
    17421888
     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
    17431931            /*
    17441932             * Check that service doing the impersonating is
    17451933             * requesting a ticket to it-self.
    17461934             */
    1747             if (krb5_principal_compare(context, cp, sp) != TRUE) {
     1935            ret = check_s4u2self(context, config, clientdb, client, sp);
     1936            if (ret) {
    17481937                kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
    1749                         "to impersonate some other user "
     1938                        "to impersonate to service "
    17501939                        "(tried for user %s to service %s)",
    17511940                        cpn, selfcpn, spn);
    17521941                free(selfcpn);
    1753                 ret = KRB5KDC_ERR_BADOPTION; /* ? */
    17541942                goto out;
    17551943            }
     
    18562044                                   config,
    18572045                                   krbtgt,
     2046                                   cp,
    18582047                                   &adtkt,
    18592048                                   NULL,
     
    18622051            ret = KRB5KDC_ERR_BADOPTION;
    18632052        if (ret) {
     2053            const char *msg = krb5_get_error_message(context, ret);
    18642054            kdc_log(context, config, 0,
    18652055                    "KRB5SignedPath check from service %s failed "
    18662056                    "for delegation to %s for client %s "
    18672057                    "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);
    18692060            free(str);
    18702061            goto out;
     
    19462137                         client_principal,
    19472138                         tgt,
     2139                         replykey,
     2140                         rk_is_subkey,
    19482141                         ekey,
    19492142                         &sessionkey,
     
    19512144                         *auth_data,
    19522145                         server,
    1953                          sp,
     2146                         server->entry.principal,
    19542147                         spn,
    19552148                         client,
    19562149                         cp,
    1957                          krbtgt,
     2150                         krbtgt_out,
    19582151                         krbtgt_etype,
    19592152                         spp,
     
    19692162    krb5_data_free(&rspac);
    19702163    krb5_free_keyblock_contents(context, &sessionkey);
     2164    if(krbtgt_out)
     2165        _kdc_free_ent(context, krbtgt_out);
    19712166    if(server)
    19722167        _kdc_free_ent(context, server);
    19732168    if(client)
    19742169        _kdc_free_ent(context, client);
     2170    if(s4u2self_impersonated_client)
     2171        _kdc_free_ent(context, s4u2self_impersonated_client);
    19752172
    19762173    if (client_principal && client_principal != cp)
     
    20122209    krb5_enctype krbtgt_etype = ETYPE_NULL;
    20132210
     2211    krb5_keyblock *replykey = NULL;
     2212    int rk_is_subkey = 0;
    20142213    time_t *csec = NULL;
    20152214    int *cusec = NULL;
     
    20392238                            from, from_addr,
    20402239                            &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    }
    20422247    if (ret) {
    20432248        kdc_log(context, config, 0,
     
    20522257                          krbtgt,
    20532258                          krbtgt_etype,
     2259                          replykey,
     2260                          rk_is_subkey,
    20542261                          ticket,
    20552262                          data,
     
    20722279
    20732280out:
    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){
    20752284        krb5_mk_error(context,
    20762285                      ret,
     
    20822291                      cusec,
    20832292                      data);
     2293        ret = 0;
    20842294    }
    20852295    free(csec);
     
    20952305    }
    20962306
    2097     return 0;
     2307    return ret;
    20982308}
Note: See TracChangeset for help on using the changeset viewer.