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/kerberos5.c

    r414 r745  
    3434#include "kdc_locl.h"
    3535
    36 RCSID("$Id$");
    37 
    3836#define MAX_TIME ((time_t)((1U << 31) - 1))
    3937
     
    6159
    6260static void
    63 set_salt_padata (METHOD_DATA *md, Salt *salt)
     61set_salt_padata(METHOD_DATA *md, Salt *salt)
    6462{
    6563    if (salt) {
    66         realloc_method_data(md);
    67         md->val[md->len - 1].padata_type = salt->type;
    68         der_copy_octet_string(&salt->salt,
    69                               &md->val[md->len - 1].padata_value);
     64       realloc_method_data(md);
     65       md->val[md->len - 1].padata_type = salt->type;
     66       der_copy_octet_string(&salt->salt,
     67                             &md->val[md->len - 1].padata_value);
    7068    }
    7169}
     
    128126_kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
    129127                krb5_enctype *etypes, unsigned len,
    130                 Key **ret_key, krb5_enctype *ret_etype)
     128                Key **ret_key)
    131129{
    132130    int i;
     
    149147            }
    150148            *ret_key   = key;
    151             *ret_etype = etypes[i];
    152149            ret = 0;
    153150            if (is_default_salt_p(&def_salt, key)) {
     
    262259                  int skvno, const EncryptionKey *skey,
    263260                  int ckvno, const EncryptionKey *reply_key,
     261                  int rk_is_subkey,
    264262                  const char **e_text,
    265263                  krb5_data *reply)
     
    273271    ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
    274272    if(ret) {
    275         kdc_log(context, config, 0, "Failed to encode ticket: %s",
    276                 krb5_get_err_text(context, ret));
     273        const char *msg = krb5_get_error_message(context, ret);
     274        kdc_log(context, config, 0, "Failed to encode ticket: %s", msg);
     275        krb5_free_error_message(context, msg);
    277276        return ret;
    278277    }
     
    286285    ret = krb5_crypto_init(context, skey, etype, &crypto);
    287286    if (ret) {
     287        const char *msg;
    288288        free(buf);
    289         kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
    290                 krb5_get_err_text(context, ret));
     289        msg = krb5_get_error_message(context, ret);
     290        kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
     291        krb5_free_error_message(context, msg);
    291292        return ret;
    292293    }
     
    302303    krb5_crypto_destroy(context, crypto);
    303304    if(ret) {
    304         kdc_log(context, config, 0, "Failed to encrypt data: %s",
    305                 krb5_get_err_text(context, ret));
     305        const char *msg = krb5_get_error_message(context, ret);
     306        kdc_log(context, config, 0, "Failed to encrypt data: %s", msg);
     307        krb5_free_error_message(context, msg);
    306308        return ret;
    307309    }
     
    312314        ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
    313315    if(ret) {
    314         kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
    315                 krb5_get_err_text(context, ret));
     316        const char *msg = krb5_get_error_message(context, ret);
     317        kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
     318        krb5_free_error_message(context, msg);
    316319        return ret;
    317320    }
     
    324327    ret = krb5_crypto_init(context, reply_key, 0, &crypto);
    325328    if (ret) {
     329        const char *msg = krb5_get_error_message(context, ret);
    326330        free(buf);
    327         kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
    328                 krb5_get_err_text(context, ret));
     331        kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
     332        krb5_free_error_message(context, msg);
    329333        return ret;
    330334    }
     
    342346        krb5_encrypt_EncryptedData(context,
    343347                                   crypto,
    344                                    KRB5_KU_TGS_REP_ENC_PART_SESSION,
     348                                   rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
    345349                                   buf,
    346350                                   len,
     
    352356    krb5_crypto_destroy(context, crypto);
    353357    if(ret) {
    354         kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
    355                 krb5_get_err_text(context, ret));
     358        const char *msg = krb5_get_error_message(context, ret);
     359        kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
     360        krb5_free_error_message(context, msg);
    356361        return ret;
    357362    }
     
    896901    hdb_entry_ex *client = NULL, *server = NULL;
    897902    HDB *clientdb;
    898     krb5_enctype cetype, setype, sessionetype;
     903    krb5_enctype setype, sessionetype;
    899904    krb5_data e_data;
    900905    EncTicketPart et;
     
    906911    krb5_crypto crypto;
    907912    Key *ckey, *skey;
    908     EncryptionKey *reply_key;
     913    EncryptionKey *reply_key = NULL, session_key;
    909914    int flags = 0;
    910915#ifdef PKINIT
     
    913918
    914919    memset(&rep, 0, sizeof(rep));
     920    memset(&session_key, 0, sizeof(session_key));
    915921    krb5_data_zero(&e_data);
     922
     923    ALLOC(rep.padata);
     924    rep.padata->len = 0;
     925    rep.padata->val = NULL;
    916926
    917927    if (f.canonicalize)
     
    979989
    980990    ret = _kdc_db_fetch(context, config, client_princ,
    981                         HDB_F_GET_CLIENT | flags, &clientdb, &client);
    982     if(ret){
    983         kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
    984                 krb5_get_err_text(context, ret));
     991                        HDB_F_GET_CLIENT | flags, NULL,
     992                        &clientdb, &client);
     993    if(ret == HDB_ERR_NOT_FOUND_HERE) {
     994        kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy", client_name);
     995        goto out;
     996    } else if(ret){
     997        const char *msg = krb5_get_error_message(context, ret);
     998        kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg);
     999        krb5_free_error_message(context, msg);
    9851000        ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
    9861001        goto out;
    9871002    }
    988 
    9891003    ret = _kdc_db_fetch(context, config, server_princ,
    990                         HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
    991                         NULL, &server);
    992     if(ret){
    993         kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name,
    994                 krb5_get_err_text(context, ret));
     1004                        HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags,
     1005                        NULL, NULL, &server);
     1006    if(ret == HDB_ERR_NOT_FOUND_HERE) {
     1007        kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", server_name);
     1008        goto out;
     1009    } else if(ret){
     1010        const char *msg = krb5_get_error_message(context, ret);
     1011        kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, msg);
     1012        krb5_free_error_message(context, msg);
    9951013        ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
    9961014        goto out;
     
    10011019
    10021020    /*
    1003      * Find the client key for reply encryption and pa-type salt, Pick
    1004      * the client key upfront before the other keys because that is
    1005      * going to affect what enctypes we are going to use in
    1006      * ETYPE-INFO{,2}.
     1021     * Select a session enctype from the list of the crypto systems
     1022     * supported enctype, is supported by the client and is one of the
     1023     * enctype of the enctype of the krbtgt.
     1024     *
     1025     * The later is used as a hint what enctype all KDC are supporting
     1026     * to make sure a newer version of KDC wont generate a session
     1027     * enctype that and older version of a KDC in the same realm can't
     1028     * decrypt.
     1029     *
     1030     * But if the KDC admin is paranoid and doesn't want to have "no
     1031     * the best" enctypes on the krbtgt, lets save the best pick from
     1032     * the client list and hope that that will work for any other
     1033     * KDCs.
    10071034     */
    1008 
    1009     ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
    1010                           &ckey, &cetype);
    1011     if (ret) {
    1012         kdc_log(context, config, 0,
    1013                 "Client (%s) has no support for etypes", client_name);
    1014         goto out;
     1035    {
     1036        const krb5_enctype *p;
     1037        krb5_enctype clientbest = ETYPE_NULL;
     1038        int i, j;
     1039
     1040        p = krb5_kerberos_enctypes(context);
     1041
     1042        sessionetype = ETYPE_NULL;
     1043
     1044        for (i = 0; p[i] != ETYPE_NULL && sessionetype == ETYPE_NULL; i++) {
     1045            if (krb5_enctype_valid(context, p[i]) != 0)
     1046                continue;
     1047
     1048            for (j = 0; j < b->etype.len && sessionetype == ETYPE_NULL; j++) {
     1049                Key *dummy;
     1050                /* check with client */
     1051                if (p[i] != b->etype.val[j])
     1052                    continue;
     1053                /* save best of union of { client, crypto system } */
     1054                if (clientbest == ETYPE_NULL)
     1055                    clientbest = p[i];
     1056                /* check with krbtgt */
     1057                ret = hdb_enctype2key(context, &server->entry, p[i], &dummy);
     1058                if (ret)
     1059                    continue;
     1060                sessionetype = p[i];
     1061            }
     1062        }
     1063        /* if krbtgt had no shared keys with client, pick clients best */
     1064        if (clientbest != ETYPE_NULL && sessionetype == ETYPE_NULL) {
     1065            sessionetype = clientbest;
     1066        } else if (sessionetype == ETYPE_NULL) {
     1067            kdc_log(context, config, 0,
     1068                    "Client (%s) from %s has no common enctypes with KDC"
     1069                    "to use for the session key",
     1070                    client_name, from);
     1071            goto out;
     1072        }
    10151073    }
    10161074
     
    11361194            ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
    11371195            if (ret) {
    1138                 kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
    1139                         krb5_get_err_text(context, ret));
     1196                const char *msg = krb5_get_error_message(context, ret);
     1197                kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
     1198                krb5_free_error_message(context, msg);
    11401199                free_EncryptedData(&enc_data);
    11411200                continue;
     
    11551214            if(ret){
    11561215                krb5_error_code ret2;
     1216                const char *msg = krb5_get_error_message(context, ret);
     1217
    11571218                ret2 = krb5_enctype_to_string(context,
    11581219                                              pa_key->key.keytype, &str);
     
    11621223                        "Failed to decrypt PA-DATA -- %s "
    11631224                        "(enctype %s) error %s",
    1164                         client_name,
    1165                         str ? str : "unknown enctype",
    1166                         krb5_get_err_text(context, ret));
     1225                        client_name, str ? str : "unknown enctype", msg);
     1226                krb5_free_error_message(context, msg);
    11671227                free(str);
    11681228
     
    12201280            et.flags.pre_authent = 1;
    12211281
    1222             ret = krb5_enctype_to_string(context,pa_key->key.keytype, &str);
     1282            set_salt_padata(rep.padata, pa_key->salt);
     1283
     1284            reply_key = &pa_key->key;
     1285
     1286            ret = krb5_enctype_to_string(context, pa_key->key.keytype, &str);
    12231287            if (ret)
    12241288                str = NULL;
     
    12901354         * If there is a client key, send ETYPE_INFO{,2}
    12911355         */
    1292         if (ckey) {
     1356        ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
     1357                              &ckey);
     1358        if (ret == 0) {
    12931359
    12941360            /*
     
    13611427        goto out;
    13621428
    1363     /*
    1364      * Select a session enctype from the list of the crypto systems
    1365      * supported enctype, is supported by the client and is one of the
    1366      * enctype of the enctype of the krbtgt.
    1367      *
    1368      * The later is used as a hint what enctype all KDC are supporting
    1369      * to make sure a newer version of KDC wont generate a session
    1370      * enctype that and older version of a KDC in the same realm can't
    1371      * decrypt.
    1372      *
    1373      * But if the KDC admin is paranoid and doesn't want to have "no
    1374      * the best" enctypes on the krbtgt, lets save the best pick from
    1375      * the client list and hope that that will work for any other
    1376      * KDCs.
    1377      */
    1378     {
    1379         const krb5_enctype *p;
    1380         krb5_enctype clientbest = ETYPE_NULL;
    1381         int i, j;
    1382 
    1383         p = krb5_kerberos_enctypes(context);
    1384 
    1385         sessionetype = ETYPE_NULL;
    1386 
    1387         for (i = 0; p[i] != ETYPE_NULL && sessionetype == ETYPE_NULL; i++) {
    1388             if (krb5_enctype_valid(context, p[i]) != 0)
    1389                 continue;
    1390 
    1391             for (j = 0; j < b->etype.len && sessionetype == ETYPE_NULL; j++) {
    1392                 Key *dummy;
    1393                 /* check with client */
    1394                 if (p[i] != b->etype.val[j])
    1395                     continue;
    1396                 /* save best of union of { client, crypto system } */
    1397                 if (clientbest == ETYPE_NULL)
    1398                     clientbest = p[i];
    1399                 /* check with krbtgt */
    1400                 ret = hdb_enctype2key(context, &server->entry, p[i], &dummy);
    1401                 if (ret)
    1402                     continue;
    1403                 sessionetype = p[i];
    1404             }
    1405         }
    1406         /* if krbtgt had no shared keys with client, pick clients best */
    1407         if (clientbest != ETYPE_NULL && sessionetype == ETYPE_NULL) {
    1408             sessionetype = clientbest;
    1409         } else if (sessionetype == ETYPE_NULL) {
    1410             kdc_log(context, config, 0,
    1411                     "Client (%s) from %s has no common enctypes with KDC"
    1412                     "to use for the session key",
    1413                     client_name, from);
    1414             goto out;
    1415         }
    1416     }
    1417 
    1418     log_as_req(context, config, cetype, setype, b);
    1419 
    14201429    if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
    14211430       || (f.request_anonymous && !config->allow_anonymous)) {
    14221431        ret = KRB5KDC_ERR_BADOPTION;
     1432        e_text = "Bad KDC options";
    14231433        kdc_log(context, config, 0, "Bad KDC options -- %s", client_name);
    14241434        goto out;
     
    14501460        et.flags.forwardable = f.forwardable;
    14511461    else if (f.forwardable) {
     1462        e_text = "Ticket may not be forwardable";
    14521463        ret = KRB5KDC_ERR_POLICY;
    14531464        kdc_log(context, config, 0,
     
    14581469        et.flags.proxiable = f.proxiable;
    14591470    else if (f.proxiable) {
     1471        e_text = "Ticket may not be proxiable";
    14601472        ret = KRB5KDC_ERR_POLICY;
    14611473        kdc_log(context, config, 0,
     
    14661478        et.flags.may_postdate = f.allow_postdate;
    14671479    else if (f.allow_postdate){
     1480        e_text = "Ticket may not be postdate";
    14681481        ret = KRB5KDC_ERR_POLICY;
    14691482        kdc_log(context, config, 0,
     
    14741487    /* check for valid set of addresses */
    14751488    if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) {
     1489        e_text = "Bad address list in requested";
    14761490        ret = KRB5KRB_AP_ERR_BADADDR;
    14771491        kdc_log(context, config, 0,
     
    16121626    }
    16131627
    1614     ALLOC(rep.padata);
    1615     rep.padata->len = 0;
    1616     rep.padata->val = NULL;
    1617 
    16181628#if PKINIT
    16191629    if (pkp) {
     
    16301640        if (ret)
    16311641            goto out;
     1642
    16321643    } else
    16331644#endif
    1634     if (ckey) {
    1635         reply_key = &ckey->key;
     1645    {
    16361646        ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
    16371647        if (ret)
    16381648            goto out;
    1639     } else {
     1649    }
     1650
     1651    if (reply_key == NULL) {
    16401652        e_text = "Client have no reply key";
    16411653        ret = KRB5KDC_ERR_CLIENT_NOTYET;
     
    16461658    if (ret)
    16471659        goto out;
    1648 
    1649     if (ckey)
    1650         set_salt_padata (rep.padata, ckey->salt);
    16511660
    16521661    /* Add signing of alias referral */
     
    17481757                                  server,
    17491758                                  setype,
     1759                                  client->entry.principal,
    17501760                                  NULL,
    17511761                                  NULL,
     
    17541764        goto out;
    17551765
     1766    log_as_req(context, config, reply_key->keytype, setype, b);
     1767
    17561768    ret = _kdc_encode_reply(context, config,
    17571769                            &rep, &et, &ek, setype, server->entry.kvno,
    17581770                            &skey->key, client->entry.kvno,
    1759                             reply_key, &e_text, reply);
     1771                            reply_key, 0, &e_text, reply);
    17601772    free_EncTicketPart(&et);
    17611773    free_EncKDCRepPart(&ek);
     
    17721784out:
    17731785    free_AS_REP(&rep);
    1774     if(ret){
     1786    if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE){
    17751787        krb5_mk_error(context,
    17761788                      ret,
Note: See TracChangeset for help on using the changeset viewer.