s4:heimdal: import lorikeet-heimdal-201107241840 (commit 0fdf11fa3cdb47df9f5393ebf36d...
authorStefan Metzmacher <metze@samba.org>
Mon, 25 Jul 2011 16:51:53 +0000 (18:51 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 Jul 2011 00:16:08 +0000 (02:16 +0200)
42 files changed:
source4/heimdal/kdc/default_config.c
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c
source4/heimdal/kdc/misc.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/kuser/kinit.c
source4/heimdal/lib/asn1/krb5.asn1
source4/heimdal/lib/gssapi/gssapi/gssapi.h
source4/heimdal/lib/gssapi/krb5/arcfour.c
source4/heimdal/lib/gssapi/krb5/get_mic.c
source4/heimdal/lib/gssapi/krb5/unwrap.c
source4/heimdal/lib/gssapi/krb5/verify_mic.c
source4/heimdal/lib/gssapi/krb5/wrap.c
source4/heimdal/lib/gssapi/version-script.map
source4/heimdal/lib/hcrypto/pkcs12.c
source4/heimdal/lib/hdb/db.c
source4/heimdal/lib/hdb/ext.c
source4/heimdal/lib/hdb/hdb.asn1
source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hdb/hdb_err.et
source4/heimdal/lib/hdb/hdb_locl.h
source4/heimdal/lib/hdb/keys.c
source4/heimdal/lib/hdb/mkey.c
source4/heimdal/lib/hdb/version-script.map
source4/heimdal/lib/krb5/auth_context.c
source4/heimdal/lib/krb5/crypto-aes.c
source4/heimdal/lib/krb5/crypto-arcfour.c
source4/heimdal/lib/krb5/crypto-des.c
source4/heimdal/lib/krb5/crypto-des3.c
source4/heimdal/lib/krb5/crypto-null.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/crypto.h
source4/heimdal/lib/krb5/error_string.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/get_for_creds.c
source4/heimdal/lib/krb5/get_in_tkt.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/keyblock.c
source4/heimdal/lib/krb5/krb5.h
source4/heimdal/lib/krb5/mit_glue.c
source4/heimdal/lib/krb5/version-script.map

index fe977ded5a24a102cccbdbb52bc42d2c2d17121d..6fbf5fdae156a1d2a16b33720410284070db0eb3 100644 (file)
@@ -54,7 +54,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
     c->as_use_strongest_session_key = FALSE;
     c->preauth_use_strongest_session_key = FALSE;
     c->tgs_use_strongest_session_key = FALSE;
-    c->use_strongest_server_key = FALSE;
+    c->use_strongest_server_key = TRUE;
     c->check_ticket_addresses = TRUE;
     c->allow_null_ticket_addresses = TRUE;
     c->allow_anonymous = FALSE;
index 4bc1619170b04aa6cde039cd6759f3350365ba14..c13abb7ce0bbfbecf7037e08515b46b52eba9273 100644 (file)
@@ -978,7 +978,7 @@ _kdc_as_rep(krb5_context context,
     krb5_crypto crypto;
     Key *ckey, *skey;
     EncryptionKey *reply_key = NULL, session_key;
-    int flags = 0;
+    int flags = HDB_F_FOR_AS_REQ;
 #ifdef PKINIT
     pk_client_params *pkp = NULL;
 #endif
index 92cce5759f49ed2d6d0922dce51080748f9c0c46..6aad65d4087ed0c5c03e7830f11d286c063c2541 100644 (file)
@@ -1216,7 +1216,7 @@ tgs_parse_request(krb5_context context,
     }
 
     if(ap_req.ticket.enc_part.kvno &&
-       (unsigned int)*ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
+       *ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
        char *p;
 
        ret = krb5_unparse_name (context, princ, &p);
@@ -1508,6 +1508,7 @@ tgs_build_reply(krb5_context context,
 
     Key *tkey_check;
     Key *tkey_sign;
+    int flags = HDB_F_FOR_TGS_REQ;
 
     memset(&sessionkey, 0, sizeof(sessionkey));
     memset(&adtkt, 0, sizeof(adtkt));
@@ -1517,6 +1518,9 @@ tgs_build_reply(krb5_context context,
     s = b->sname;
     r = b->realm;
 
+    if (b->kdc_options.canonicalize)
+       flags |= HDB_F_CANON;
+
     if(b->kdc_options.enc_tkt_in_skey){
        Ticket *t;
        hdb_entry_ex *uu;
@@ -1591,7 +1595,7 @@ tgs_build_reply(krb5_context context,
      */
 
 server_lookup:
-    ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | HDB_F_CANON,
+    ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags,
                        NULL, NULL, &server);
 
     if(ret == HDB_ERR_NOT_FOUND_HERE) {
@@ -1777,7 +1781,7 @@ server_lookup:
        goto out;
     }
 
-    ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
+    ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags,
                        NULL, &clientdb, &client);
     if(ret == HDB_ERR_NOT_FOUND_HERE) {
        /* This is OK, we are just trying to find out if they have
@@ -1912,7 +1916,7 @@ server_lookup:
            if(rspac.data) {
                krb5_pac p = NULL;
                krb5_data_free(&rspac);
-               ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | HDB_F_CANON,
+               ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
                                    NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
                if (ret) {
                    const char *msg;
index f9b34571a32a13930a9793111f1a8571de8dc77a..1b2c440005984731f1dae57c2e068516932c5dd1 100644 (file)
@@ -40,7 +40,7 @@ _kdc_db_fetch(krb5_context context,
              krb5_kdc_configuration *config,
              krb5_const_principal principal,
              unsigned flags,
-             krb5int32 *kvno_ptr,
+             krb5uint32 *kvno_ptr,
              HDB **db,
              hdb_entry_ex **h)
 {
index a02cb816ab7e1bdc3765badaf5823111bf4b5945..d85b15650073d2b282fb7ce65e63c13867c710dc 100644 (file)
@@ -1420,7 +1420,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        memset(&rep, 0, sizeof(rep));
 
        pa_type = KRB5_PADATA_PK_AS_REP_19;
-       rep.element = choice_PA_PK_AS_REP_encKeyPack;
+       rep.element = choice_PA_PK_AS_REP_Win2k_encKeyPack;
 
        ret = krb5_generate_random_keyblock(context, enctype,
                                            &cp->reply_key);
index e872fef9bee035ab82da930cd93c5dcab690e1fc..0b3876dcc5ede13205066fe7e15446749e73d3e0 100644 (file)
@@ -434,7 +434,7 @@ get_new_tickets(krb5_context context,
                                                pac_flag ? TRUE : FALSE);
     if (canonicalize_flag)
        krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
-    if ((pk_enterprise_flag || enterprise_flag || canonicalize_flag) && windows_flag)
+    if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
        krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
     if (pk_user_id || ent_user_id || anonymous_flag) {
        ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
index 02fab7a3a69a919668e8c92cc7e4bb4642988ef5..568fe0cd04b41efdfdab87b904b4874c7b6bcec0 100644 (file)
@@ -361,7 +361,7 @@ LastReq ::= SEQUENCE OF SEQUENCE {
 
 EncryptedData ::= SEQUENCE {
        etype[0]                ENCTYPE, -- EncryptionType
-       kvno[1]                 krb5int32 OPTIONAL,
+       kvno[1]                 krb5uint32 OPTIONAL,
        cipher[2]               OCTET STRING -- ciphertext
 }
 
index fa53a29d240966e919900068c4baf7073993ddaf..bbb2fd54c9bd702437b051b2acaa3825e12d5ff4 100644 (file)
 #endif
 #endif
 
+/* Compatiblity with MIT Kerberos on the Mac */
+#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
+#pragma pack(push,2)
+#endif
+
 #ifdef __cplusplus
 #define GSSAPI_CPP_START       extern "C" {
 #define GSSAPI_CPP_END         }
@@ -1041,7 +1046,8 @@ GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
 gss_userok(const gss_name_t name,
            const char *user);
 
-extern GSSAPI_LIB_VARIABLE gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER;
+extern GSSAPI_LIB_VARIABLE gss_buffer_desc __gss_c_attr_local_login_user;
+#define GSS_C_ATTR_LOCAL_LOGIN_USER (&__gss_c_attr_local_login_user)
 
 /*
  * Naming extensions
@@ -1105,6 +1111,10 @@ gss_name_to_oid(const char *name);
 
 GSSAPI_CPP_END
 
+#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
+#pragma pack(pop)
+#endif
+
 #undef GSSAPI_DEPRECATED_FUNCTION
 
 #endif /* GSSAPI_GSSAPI_H_ */
index 0264207e4a8ceb467fdaf80c9079c3c88e74e7cb..f5e41e4056f369b888466611b0d456a64bc90ea0 100644 (file)
@@ -86,7 +86,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
     cksum_k5.checksum.data = k5_data;
     cksum_k5.checksum.length = sizeof(k5_data);
 
-    if (key->keytype == KEYTYPE_ARCFOUR_56) {
+    if (key->keytype == KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56) {
        char L40[14] = "fortybits";
 
        memcpy(L40 + 10, T, sizeof(T));
@@ -100,7 +100,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
     if (ret)
        return ret;
 
-    key5.keytype = KEYTYPE_ARCFOUR;
+    key5.keytype = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5;
     key5.keyvalue = cksum_k5.checksum;
 
     cksum_k6.checksum.data = key6_data;
index 0109ca7c6e76d90e8d229d2069228bc9fe978db4..d032d23d5f8d49431b7b3db30cc32c8e4b035aa1 100644 (file)
@@ -285,7 +285,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
   krb5_keyblock *key;
   OM_uint32 ret;
-  krb5_keytype keytype;
 
   GSSAPI_KRB5_INIT (&context);
 
@@ -300,10 +299,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
       *minor_status = ret;
       return GSS_S_FAILURE;
   }
-  krb5_enctype_to_keytype (context, key->keytype, &keytype);
 
-  switch (keytype) {
-  case KEYTYPE_DES :
+  switch (key->keytype) {
+  case KRB5_ENCTYPE_DES_CBC_CRC :
+  case KRB5_ENCTYPE_DES_CBC_MD4 :
+  case KRB5_ENCTYPE_DES_CBC_MD5 :
 #ifdef HEIM_WEAK_CRYPTO
       ret = mic_des (minor_status, ctx, context, qop_req,
                     message_buffer, message_token, key);
@@ -311,12 +311,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
       ret = GSS_S_FAILURE;
 #endif
       break;
-  case KEYTYPE_DES3 :
+  case KRB5_ENCTYPE_DES3_CBC_MD5 :
+  case KRB5_ENCTYPE_DES3_CBC_SHA1 :
       ret = mic_des3 (minor_status, ctx, context, qop_req,
                      message_buffer, message_token, key);
       break;
-  case KEYTYPE_ARCFOUR:
-  case KEYTYPE_ARCFOUR_56:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
       ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req,
                                     message_buffer, message_token, key);
       break;
index d6bc20477787c744b6eda069c4226cb985e59e3c..b3da35ee9e28f4b374569d2acd0b8f50500ce6c2 100644 (file)
@@ -392,7 +392,6 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
   krb5_keyblock *key;
   krb5_context context;
   OM_uint32 ret;
-  krb5_keytype keytype;
   gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
 
   output_message_buffer->value = NULL;
@@ -414,12 +413,13 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
       *minor_status = ret;
       return GSS_S_FAILURE;
   }
-  krb5_enctype_to_keytype (context, key->keytype, &keytype);
 
   *minor_status = 0;
 
-  switch (keytype) {
-  case KEYTYPE_DES :
+  switch (key->keytype) {
+  case KRB5_ENCTYPE_DES_CBC_CRC :
+  case KRB5_ENCTYPE_DES_CBC_MD4 :
+  case KRB5_ENCTYPE_DES_CBC_MD5 :
 #ifdef HEIM_WEAK_CRYPTO
       ret = unwrap_des (minor_status, ctx,
                        input_message_buffer, output_message_buffer,
@@ -428,13 +428,14 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
       ret = GSS_S_FAILURE;
 #endif
       break;
-  case KEYTYPE_DES3 :
+  case KRB5_ENCTYPE_DES3_CBC_MD5 :
+  case KRB5_ENCTYPE_DES3_CBC_SHA1 :
       ret = unwrap_des3 (minor_status, ctx, context,
                         input_message_buffer, output_message_buffer,
                         conf_state, qop_state, key);
       break;
-  case KEYTYPE_ARCFOUR:
-  case KEYTYPE_ARCFOUR_56:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
       ret = _gssapi_unwrap_arcfour (minor_status, ctx, context,
                                    input_message_buffer, output_message_buffer,
                                    conf_state, qop_state, key);
index 3123787ff474cbc5d4f23b212e9afbdf3cce6ab6..af06e0a1e3d55b29b18de9a64e8a277832242974 100644 (file)
@@ -281,7 +281,6 @@ _gsskrb5_verify_mic_internal
 {
     krb5_keyblock *key;
     OM_uint32 ret;
-    krb5_keytype keytype;
 
     if (ctx->more_flags & IS_CFX)
         return _gssapi_verify_mic_cfx (minor_status, ctx,
@@ -296,9 +295,11 @@ _gsskrb5_verify_mic_internal
        return GSS_S_FAILURE;
     }
     *minor_status = 0;
-    krb5_enctype_to_keytype (context, key->keytype, &keytype);
-    switch (keytype) {
-    case KEYTYPE_DES :
+
+    switch (key->keytype) {
+    case KRB5_ENCTYPE_DES_CBC_CRC :
+    case KRB5_ENCTYPE_DES_CBC_MD4 :
+    case KRB5_ENCTYPE_DES_CBC_MD5 :
 #ifdef HEIM_WEAK_CRYPTO
        ret = verify_mic_des (minor_status, ctx, context,
                              message_buffer, token_buffer, qop_state, key,
@@ -307,13 +308,14 @@ _gsskrb5_verify_mic_internal
       ret = GSS_S_FAILURE;
 #endif
        break;
-    case KEYTYPE_DES3 :
+    case KRB5_ENCTYPE_DES3_CBC_MD5 :
+    case KRB5_ENCTYPE_DES3_CBC_SHA1 :
        ret = verify_mic_des3 (minor_status, ctx, context,
                               message_buffer, token_buffer, qop_state, key,
                               type);
        break;
-    case KEYTYPE_ARCFOUR :
-    case KEYTYPE_ARCFOUR_56 :
+    case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+    case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
        ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
                                          context,
                                          message_buffer, token_buffer,
index efd0d82c49545a0a9255a1ffb8e416f4b899bdf1..4d095c8e87737c74ed9499a5d679ca3505740948 100644 (file)
@@ -147,7 +147,6 @@ _gsskrb5_wrap_size_limit (
   krb5_context context;
   krb5_keyblock *key;
   OM_uint32 ret;
-  krb5_keytype keytype;
   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
 
   GSSAPI_KRB5_INIT (&context);
@@ -164,23 +163,25 @@ _gsskrb5_wrap_size_limit (
       *minor_status = ret;
       return GSS_S_FAILURE;
   }
-  krb5_enctype_to_keytype (context, key->keytype, &keytype);
 
-  switch (keytype) {
-  case KEYTYPE_DES :
+  switch (key->keytype) {
+  case KRB5_ENCTYPE_DES_CBC_CRC :
+  case KRB5_ENCTYPE_DES_CBC_MD4 :
+  case KRB5_ENCTYPE_DES_CBC_MD5 :
 #ifdef HEIM_WEAK_CRYPTO
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
 #else
       ret = GSS_S_FAILURE;
 #endif
       break;
-  case KEYTYPE_ARCFOUR:
-  case KEYTYPE_ARCFOUR_56:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
       ret = _gssapi_wrap_size_arcfour(minor_status, ctx, context,
                                      conf_req_flag, qop_req,
                                      req_output_size, max_input_size, key);
       break;
-  case KEYTYPE_DES3 :
+  case KRB5_ENCTYPE_DES3_CBC_MD5 :
+  case KRB5_ENCTYPE_DES3_CBC_SHA1 :
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
       break;
   default :
@@ -538,7 +539,6 @@ _gsskrb5_wrap
   krb5_context context;
   krb5_keyblock *key;
   OM_uint32 ret;
-  krb5_keytype keytype;
   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
 
   output_message_buffer->value = NULL;
@@ -558,10 +558,11 @@ _gsskrb5_wrap
       *minor_status = ret;
       return GSS_S_FAILURE;
   }
-  krb5_enctype_to_keytype (context, key->keytype, &keytype);
 
-  switch (keytype) {
-  case KEYTYPE_DES :
+  switch (key->keytype) {
+  case KRB5_ENCTYPE_DES_CBC_CRC :
+  case KRB5_ENCTYPE_DES_CBC_MD4 :
+  case KRB5_ENCTYPE_DES_CBC_MD5 :
 #ifdef HEIM_WEAK_CRYPTO
       ret = wrap_des (minor_status, ctx, context, conf_req_flag,
                      qop_req, input_message_buffer, conf_state,
@@ -570,13 +571,14 @@ _gsskrb5_wrap
       ret = GSS_S_FAILURE;
 #endif
       break;
-  case KEYTYPE_DES3 :
+  case KRB5_ENCTYPE_DES3_CBC_MD5 :
+  case KRB5_ENCTYPE_DES3_CBC_SHA1 :
       ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,
                       qop_req, input_message_buffer, conf_state,
                       output_message_buffer, key);
       break;
-  case KEYTYPE_ARCFOUR:
-  case KEYTYPE_ARCFOUR_56:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
+  case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
       ret = _gssapi_wrap_arcfour (minor_status, ctx, context, conf_req_flag,
                                  qop_req, input_message_buffer, conf_state,
                                  output_message_buffer, key);
index ebd8ee21acfaa4f6c338a7f67df2b9e14771fed6..bcb79bf8f76e4040c1f8ab93e0e097123f82720d 100644 (file)
@@ -14,7 +14,7 @@ HEIMDAL_GSS_2.0 {
                __gss_c_attr_stream_sizes_oid_desc;
                __gss_c_cred_password_oid_desc;
                __gss_c_cred_certificate_oid_desc;
-               GSS_C_ATTR_LOCAL_LOGIN_USER;
+               __gss_c_attr_local_login_user;
                gss_accept_sec_context;
                gss_acquire_cred;
                gss_acquire_cred_with_password;
index a890f01a3dd8bf19ba2c0ea17d41c8fd72effdb0..ff0f77644ea855741452df8a0f7513f77ed300fd 100644 (file)
@@ -55,6 +55,13 @@ PKCS12_key_gen(const void *key, size_t keylen,
     unsigned char *outp = out;
     int i, vlen;
 
+    /**
+     * The argument key is pointing to an utf16 string, and thus
+     * keylen that is no a multiple of 2 is invalid.
+     */
+    if (keylen & 1)
+       return 0;
+
     ctx = EVP_MD_CTX_create();
     if (ctx == NULL)
        return 0;
@@ -83,7 +90,7 @@ PKCS12_key_gen(const void *key, size_t keylen,
      * empty string, in the empty string the UTF16 NUL terminator is
      * included into the string.
      */
-    if (key && keylen >= 0) {
+    if (key) {
        for (i = 0; i < vlen / 2; i++) {
            I[(i * 2) + size_I] = 0;
            I[(i * 2) + size_I + 1] = ((unsigned char*)key)[i % (keylen + 1)];
index 69940edf89dc7e5e054e8e38bf2f194731a2bb8f..2ed054a6315cbb810b36a6da7953331188cbb72c 100644 (file)
@@ -65,12 +65,24 @@ DB_lock(krb5_context context, HDB *db, int operation)
 {
     DB *d = (DB*)db->hdb_db;
     int fd = (*d->fd)(d);
+    krb5_error_code ret;
+
+    if (db->lock_count > 0) {
+       db->lock_count++;
+       if (db->lock_type == HDB_WLOCK || db->lock_type == operation)
+           return 0;
+    }
+
     if(fd < 0) {
        krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB,
                               "Can't lock database: %s", db->hdb_name);
        return HDB_ERR_CANT_LOCK_DB;
     }
-    return hdb_lock(fd, operation);
+    ret = hdb_lock(fd, operation);
+    if (ret)
+       return ret;
+    db->lock_count++;
+    return 0;
 }
 
 static krb5_error_code
@@ -78,6 +90,14 @@ DB_unlock(krb5_context context, HDB *db)
 {
     DB *d = (DB*)db->hdb_db;
     int fd = (*d->fd)(d);
+
+    if (db->lock_count > 1) {
+       db->lock_count--;
+       return 0;
+    }
+    heim_assert(db->lock_count == 1, "HDB lock/unlock sequence does not match");
+    db->lock_count--;
+
     if(fd < 0) {
        krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB,
                               "Can't unlock database: %s", db->hdb_name);
index d2a4373b9b3889093967b3e49ae61147d73f2cd8..f4f17152400753c1f3fb9ca074d9433690aa07b9 100644 (file)
@@ -432,3 +432,67 @@ hdb_entry_get_aliases(const hdb_entry *entry, const HDB_Ext_Aliases **a)
 
     return 0;
 }
+
+unsigned int
+hdb_entry_get_kvno_diff_clnt(const hdb_entry *entry)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry,
+                            choice_HDB_extension_data_hist_kvno_diff_clnt);
+    if (ext)
+       return ext->data.u.hist_kvno_diff_clnt;
+    return 1;
+}
+
+krb5_error_code
+hdb_entry_set_kvno_diff_clnt(krb5_context context, hdb_entry *entry,
+                            unsigned int diff)
+{
+    HDB_extension ext;
+
+    if (diff > 16384)
+       return EINVAL;
+    ext.data.element = choice_HDB_extension_data_hist_kvno_diff_clnt;
+    ext.data.u.hist_kvno_diff_clnt = diff;
+    return hdb_replace_extension(context, entry, &ext);
+}
+
+krb5_error_code
+hdb_entry_clear_kvno_diff_clnt(krb5_context context, hdb_entry *entry)
+{
+    return hdb_clear_extension(context, entry,
+                              choice_HDB_extension_data_hist_kvno_diff_clnt);
+}
+
+unsigned int
+hdb_entry_get_kvno_diff_svc(const hdb_entry *entry)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry,
+                            choice_HDB_extension_data_hist_kvno_diff_svc);
+    if (ext)
+       return ext->data.u.hist_kvno_diff_svc;
+    return 1024; /* max_life effectively provides a better default */
+}
+
+krb5_error_code
+hdb_entry_set_kvno_diff_svc(krb5_context context, hdb_entry *entry,
+                           unsigned int diff)
+{
+    HDB_extension ext;
+
+    if (diff > 16384)
+       return EINVAL;
+    ext.data.element = choice_HDB_extension_data_hist_kvno_diff_svc;
+    ext.data.u.hist_kvno_diff_svc = diff;
+    return hdb_replace_extension(context, entry, &ext);
+}
+
+krb5_error_code
+hdb_entry_clear_kvno_diff_svc(krb5_context context, hdb_entry *entry)
+{
+    return hdb_clear_extension(context, entry,
+                              choice_HDB_extension_data_hist_kvno_diff_svc);
+}
index a72851c9f2011b65895aa46ba2c33aabbc2da192..0594b313b763b0d77532377a5e540f47b871262c 100644 (file)
@@ -46,8 +46,9 @@ HDBFlags ::= BIT STRING {
        trusted-for-delegation(14),     -- Trusted to print forwardabled tickets
        allow-kerberos4(15),            -- Allow Kerberos 4 requests
        allow-digest(16),               -- Allow digest requests
-       locked-out(17)                  -- Account is locked out,
+       locked-out(17),                 -- Account is locked out,
                                        -- authentication will be denied
+       do-not-store(31)                -- Not to be modified and stored in HDB
 }
 
 GENERATION ::= SEQUENCE {
@@ -87,6 +88,17 @@ HDB-Ext-Aliases ::= SEQUENCE {
        aliases[1]              SEQUENCE OF Principal -- all names, inc primary
 }
 
+Keys ::= SEQUENCE OF Key
+
+hdb_keyset ::= SEQUENCE {
+       kvno[0]         INTEGER (0..4294967295),
+       keys[1]         Keys,
+       set-time[2]     KerberosTime OPTIONAL,  -- time this keyset was created/set
+       ...
+}
+
+HDB-Ext-KeySet ::= SEQUENCE OF hdb_keyset
+
 
 HDB-extension ::= SEQUENCE {
         mandatory[0]    BOOLEAN,        -- kdc MUST understand this extension,
@@ -102,6 +114,10 @@ HDB-extension ::= SEQUENCE {
                aliases[6]                      HDB-Ext-Aliases,
                last-pw-change[7]               KerberosTime,
                pkinit-cert[8]                  HDB-Ext-PKINIT-cert,
+               hist-keys[9]                    HDB-Ext-KeySet,
+               hist-kvno-diff-clnt[10]         INTEGER (0..4294967295),
+               hist-kvno-diff-svc[11]          INTEGER (0..4294967295),
+               policy[12]                      UTF8String,
                ...
        },
        ...
@@ -109,16 +125,11 @@ HDB-extension ::= SEQUENCE {
 
 HDB-extensions ::= SEQUENCE OF HDB-extension
 
-hdb_keyset ::= SEQUENCE {
-       kvno[1]         INTEGER (0..4294967295),
-       keys[0]         SEQUENCE OF Key
-}
-
 hdb_entry ::= SEQUENCE {
        principal[0]    Principal  OPTIONAL, -- this is optional only 
                                             -- for compatibility with libkrb5
        kvno[1]         INTEGER (0..4294967295),
-       keys[2]         SEQUENCE OF Key,
+       keys[2]         Keys,
        created-by[3]   Event,
        modified-by[4]  Event OPTIONAL,
        valid-start[5]  KerberosTime OPTIONAL,
index ca05cc4a1785c2a2896a788afbb89ab6a8588228..5dc5a0957e080abf00ebd741339e6dae6aa2a886 100644 (file)
@@ -168,13 +168,14 @@ hdb_unlock(int fd)
 void
 hdb_free_entry(krb5_context context, hdb_entry_ex *ent)
 {
+    Key *k;
     size_t i;
 
     if (ent->free_entry)
        (*ent->free_entry)(context, ent);
 
-    for(i = 0; i < ent->entry.keys.len; ++i) {
-       Key *k = &ent->entry.keys.val[i];
+    for(i = 0; i < ent->entry.keys.len; i++) {
+       k = &ent->entry.keys.val[i];
 
        memset (k->key.keyvalue.data, 0, k->key.keyvalue.length);
     }
index 469ec82ec0bd27ad726a5ba895e3d1710ea73bc2..75d18770f01c20d9791ee35d3f033f19979adc18 100644 (file)
@@ -57,6 +57,12 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 #define HDB_F_CANON            32      /* want canonicalition */
 #define HDB_F_ADMIN_DATA       64      /* want data that kdc don't use  */
 #define HDB_F_KVNO_SPECIFIED   128     /* we want a particular KVNO */
+#define HDB_F_CURRENT_KVNO     256     /* we want the current KVNO */
+#define HDB_F_LIVE_CLNT_KVNOS  512     /* we want all live keys for pre-auth */
+#define HDB_F_LIVE_SVC_KVNOS   1024    /* we want all live keys for tix */
+#define HDB_F_ALL_KVNOS                2048    /* we want all the keys, live or not */
+#define HDB_F_FOR_AS_REQ       4096    /* fetch is for a AS REQ */
+#define HDB_F_FOR_TGS_REQ      8192    /* fetch is for a TGS REQ */
 
 /* hdb_capability_flags */
 #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
@@ -102,6 +108,8 @@ typedef struct HDB{
     hdb_master_key hdb_master_key;
     int hdb_openp;
     int hdb_capability_flags;
+    int lock_count;
+    int lock_type;
     /**
      * Open (or create) the a Kerberos database.
      *
index 2cad4daba41478c57e511f503e5859bb3e75ae74..0bdcb385f6bc1b84f69985e696b7761931d5ec7a 100644 (file)
@@ -26,5 +26,6 @@ error_code NO_MKEY,           "No correct master key"
 error_code MANDATORY_OPTION,   "Entry contains unknown mandatory extension"
 error_code NO_WRITE_SUPPORT,   "HDB backend doesn't contain write support"
 error_code NOT_FOUND_HERE,     "The secret for this entry is not replicated to this database"
+error_code MISUSE,             "Incorrect use of the API"
 
 end
index e896b5802575918d5d8d3762c8a73d1fbdaeedc4..c210b98b84a89d7cfae605232b58aaae097eb018 100644 (file)
@@ -36,6 +36,9 @@
 #ifndef __HDB_LOCL_H__
 #define __HDB_LOCL_H__
 
+#include <assert.h>
+#include <heimbase.h>
+
 #include <config.h>
 
 #include <stdio.h>
index 3d0b9d7c1b3168cd53e5a2c43e1aa7901f5ba255..0bc3392fb62b9e9b4d3365edb753f8830fd2e8b1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2011 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -39,9 +39,9 @@
  */
 
 void
-hdb_free_keys (krb5_context context, int len, Key *keys)
+hdb_free_keys(krb5_context context, int len, Key *keys)
 {
-    int i;
+    size_t i;
 
     for (i = 0; i < len; i++) {
        free(keys[i].mkvno);
@@ -68,15 +68,15 @@ hdb_free_keys (krb5_context context, int len, Key *keys)
  */
 
 static const krb5_enctype des_etypes[] = {
-    ETYPE_DES_CBC_MD5,
-    ETYPE_DES_CBC_MD4,
-    ETYPE_DES_CBC_CRC
+    KRB5_ENCTYPE_DES_CBC_MD5,
+    KRB5_ENCTYPE_DES_CBC_MD4,
+    KRB5_ENCTYPE_DES_CBC_CRC
 };
 
 static const krb5_enctype all_etypes[] = {
-    ETYPE_AES256_CTS_HMAC_SHA1_96,
-    ETYPE_ARCFOUR_HMAC_MD5,
-    ETYPE_DES3_CBC_SHA1
+    KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+    KRB5_ENCTYPE_ARCFOUR_HMAC_MD5,
+    KRB5_ENCTYPE_DES3_CBC_SHA1
 };
 
 static krb5_error_code
@@ -114,7 +114,7 @@ parse_key_set(krb5_context context, const char *key,
                enctypes = des_etypes;
                num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]);
            } else if(strcmp(buf[i], "des3") == 0) {
-               e = ETYPE_DES3_CBC_SHA1;
+               e = KRB5_ENCTYPE_DES3_CBC_SHA1;
                enctypes = &e;
                num_enctypes = 1;
            } else {
@@ -196,6 +196,68 @@ parse_key_set(krb5_context context, const char *key,
     return 0;
 }
 
+
+/**
+ * This function adds an HDB entry's current keyset to the entry's key
+ * history.  The current keyset is left alone; the caller is responsible
+ * for freeing it.
+ *
+ * @param context   Context
+ * @param entry            HDB entry
+ */
+krb5_error_code
+hdb_add_current_keys_to_history(krb5_context context, hdb_entry *entry)
+{
+    krb5_boolean replace = FALSE;
+    krb5_error_code ret;
+    HDB_extension *ext;
+    hdb_keyset newkey;
+    time_t newtime;
+
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_hist_keys);
+    if (ext == NULL) {
+       replace = TRUE;
+       ext = calloc(1, sizeof (*ext));
+       if (ext == NULL)
+           return krb5_enomem(context);
+
+       ext->data.element = choice_HDB_extension_data_hist_keys;
+    }
+
+    /*
+     * Copy in newest old keyset
+     */
+
+    ret = hdb_entry_get_pw_change_time(entry, &newtime);
+    if (ret)
+       goto out;
+
+    memset(&newkey, 0, sizeof(newkey));
+    newkey.keys = entry->keys;
+    newkey.kvno = entry->kvno;
+    newkey.set_time = &newtime;
+
+    ret = add_HDB_Ext_KeySet(&ext->data.u.hist_keys, &newkey);
+    if (ret)
+       goto out;
+
+    if (replace) {
+       /* hdb_replace_extension() deep-copies ext; what a waste */
+       ret = hdb_replace_extension(context, entry, ext);
+       if (ret)
+           goto out;
+    }
+
+ out:
+    if (replace && ext) {
+       free_HDB_extension(ext);
+       free(ext);
+    }
+    return ret;
+}
+
+
 static krb5_error_code
 add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
                       krb5_enctype enctype, krb5_salt *salt)
@@ -243,6 +305,50 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
 }
 
 
+static
+krb5_error_code
+ks_tuple2str(krb5_context context, int n_ks_tuple,
+            krb5_key_salt_tuple *ks_tuple, char ***ks_tuple_strs)
+{
+       size_t i;
+       char **ksnames;
+       char *ename, *sname;
+       krb5_error_code rc = KRB5_PROG_ETYPE_NOSUPP;
+
+       *ks_tuple_strs = NULL;
+       if (n_ks_tuple < 1)
+               return 0;
+
+       if ((ksnames = calloc(n_ks_tuple, sizeof (*ksnames))) == NULL)
+               return (errno);
+
+       for (i = 0; i < n_ks_tuple; i++) {
+           if (krb5_enctype_to_string(context, ks_tuple[i].ks_enctype, &ename))
+               goto out;
+           if (krb5_salttype_to_string(context, ks_tuple[i].ks_enctype,
+                                       ks_tuple[i].ks_salttype, &sname))
+               goto out;
+
+           if (asprintf(&ksnames[i], "%s:%s", ename, sname) == -1) {
+                   rc = errno;
+                   free(ename);
+                   free(sname);
+                   goto out;
+           }
+           free(ename);
+           free(sname);
+       }
+
+       *ks_tuple_strs = ksnames;
+       rc = 0;
+
+out:
+       for (i = 0; i < n_ks_tuple; i++)
+               free(ksnames[i]);
+       free(ksnames);
+       return (rc);
+}
+
 /*
  * Generate the `key_set' from the [kadmin]default_keys statement. If
  * `no_salt' is set, salt is not important (and will not be set) since
@@ -251,12 +357,15 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
 
 krb5_error_code
 hdb_generate_key_set(krb5_context context, krb5_principal principal,
+                    int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
                     Key **ret_key_set, size_t *nkeyset, int no_salt)
 {
-    char **ktypes, **kp;
+    char **ktypes = NULL;
+    char **kp;
     krb5_error_code ret;
     Key *k, *key_set;
     size_t i, j;
+    char **ks_tuple_strs;
     static const char *default_keytypes[] = {
        "aes256-cts-hmac-sha1-96:pw-salt",
        "des3-cbc-sha1:pw-salt",
@@ -264,16 +373,18 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
        NULL
     };
 
-    ktypes = krb5_config_get_strings(context, NULL, "kadmin",
-                                    "default_keys", NULL);
+    if ((ret = ks_tuple2str(context, n_ks_tuple, ks_tuple, &ks_tuple_strs)))
+           return ret;
+
+    if (ks_tuple_strs == NULL)
+       ktypes = krb5_config_get_strings(context, NULL, "kadmin",
+                                        "default_keys", NULL);
     if (ktypes == NULL)
        ktypes = (char **)(intptr_t)default_keytypes;
 
     *ret_key_set = key_set = NULL;
     *nkeyset = 0;
 
-    ret = 0;
-
     for(kp = ktypes; kp && *kp; kp++) {
        const char *p;
        krb5_salt salt;
@@ -366,7 +477,7 @@ hdb_generate_key_set_password(krb5_context context,
     krb5_error_code ret;
     size_t i;
 
-    ret = hdb_generate_key_set(context, principal,
+    ret = hdb_generate_key_set(context, principal, 0, NULL,
                                keys, num_keys, 0);
     if (ret)
        return ret;
index 9a13d55a517b1c6384827f9e647d2a7415b6b107..6dcfc0294205d8f79a61d88564ee1d22fd8e0369 100644 (file)
@@ -228,7 +228,7 @@ read_master_encryptionkey(krb5_context context, const char *filename,
        should cover all cases, but will break if someone has hacked
        this code to really use des-cbc-md5 -- but then that's not my
        problem. */
-    if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5)
+    if(key.keytype == ETYPE_DES_CBC_CRC || key.keytype == ETYPE_DES_CBC_MD5)
        key.keytype = ETYPE_DES_CFB64_NONE;
 
     ret = hdb_process_master_key(context, 0, &key, 0, mkey);
@@ -479,6 +479,131 @@ hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
     return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key);
 }
 
+krb5_error_code
+hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno,
+                    unsigned flags, hdb_entry *ent)
+{
+    krb5_error_code ret = HDB_ERR_NOENTRY;
+    HDB_extension *ext;
+    HDB_Ext_KeySet *hist_keys;
+    Key *tmp_val;
+    time_t tmp_set_time;
+    unsigned int tmp_len;
+    unsigned int kvno_diff = 0;
+    krb5_kvno tmp_kvno;
+    size_t i, k;
+    int exclude_dead = 0;
+    KerberosTime now = 0;
+    time_t *set_time;
+
+    if (kvno == 0)
+       ret = 0;
+
+    if ((flags & HDB_F_LIVE_CLNT_KVNOS) || (flags & HDB_F_LIVE_SVC_KVNOS)) {
+       exclude_dead = 1;
+       now = time(NULL);
+       if (HDB_F_LIVE_CLNT_KVNOS)
+           kvno_diff = hdb_entry_get_kvno_diff_clnt(ent);
+       else
+           kvno_diff = hdb_entry_get_kvno_diff_svc(ent);
+    }
+
+    ext = hdb_find_extension(ent, choice_HDB_extension_data_hist_keys);
+    if (ext == NULL)
+       return ret;
+
+    /* For swapping; see below */
+    tmp_len = ent->keys.len;
+    tmp_val = ent->keys.val;
+    tmp_kvno = ent->kvno;
+    (void) hdb_entry_get_pw_change_time(ent, &tmp_set_time);
+
+    hist_keys = &ext->data.u.hist_keys;
+
+    for (i = 0; i < hist_keys->len; i++) {
+       if (kvno != 0 && hist_keys->val[i].kvno != kvno)
+           continue;
+
+       if (exclude_dead &&
+           ((ent->max_life != NULL &&
+             hist_keys->val[i].set_time != NULL &&
+             (*hist_keys->val[i].set_time) < (now - (*ent->max_life))) ||
+           (hist_keys->val[i].kvno < kvno &&
+            (kvno - hist_keys->val[i].kvno) > kvno_diff)))
+           /*
+            * The KDC may want to to check for this keyset's set_time
+            * is within the TGS principal's max_life, say.  But we stop
+            * here.
+            */
+           continue;
+
+       /* Either the keys we want, or all the keys */
+       for (k = 0; k < hist_keys->val[i].keys.len; k++) {
+           ret = hdb_unseal_key_mkey(context,
+                                     &hist_keys->val[i].keys.val[k],
+                                     db->hdb_master_key);
+           /*
+            * If kvno == 0 we might not want to bail here!  E.g., if we
+            * no longer have the right master key, so just ignore this.
+            *
+            * We could filter out keys that we can't decrypt here
+            * because of HDB_ERR_NO_MKEY.  However, it seems safest to
+            * filter them out only where necessary, say, in kadm5.
+            */
+           if (ret && kvno != 0)
+               return ret;
+           if (ret && ret != HDB_ERR_NO_MKEY)
+               return (ret);
+       }
+
+       if (kvno == 0)
+           continue;
+
+       /*
+        * What follows is a bit of a hack.
+        *
+        * This is the keyset we're being asked for, but it's not the
+        * current keyset.  So we add the current keyset to the history,
+        * leave the one we were asked for in the history, and pretend
+        * the one we were asked for is also the current keyset.
+        *
+        * This is a bit of a defensive hack in case an entry fetched
+        * this way ever gets modified then stored: if the keyset is not
+        * changed we can detect this and put things back, else we won't
+        * drop any keysets from history by accident.
+        *
+        * Note too that we only ever get called with a non-zero kvno
+        * either in the KDC or in cases where we aren't changing the
+        * HDB entry anyways, which is why this is just a defensive
+        * hack.  We also don't fetch specific kvnos in the dump case,
+        * so there's no danger that we'll dump this entry and load it
+        * again, repeatedly causing the history to grow boundelessly.
+        */
+       set_time = malloc(sizeof (*set_time));
+       if (set_time == NULL)
+           return ENOMEM;
+
+       /* Swap key sets */
+       ent->kvno = hist_keys->val[i].kvno;
+       ent->keys.val = hist_keys->val[i].keys.val;
+       ent->keys.len = hist_keys->val[i].keys.len;
+       if (hist_keys->val[i].set_time != NULL)
+           /* Sloppy, but the callers we expect won't care */
+           (void) hdb_entry_set_pw_change_time(context, ent,
+                                               *hist_keys->val[i].set_time);
+       hist_keys->val[i].kvno = tmp_kvno;
+       hist_keys->val[i].keys.val = tmp_val;
+       hist_keys->val[i].keys.len = tmp_len;
+       if (hist_keys->val[i].set_time != NULL)
+           /* Sloppy, but the callers we expect won't care */
+           *hist_keys->val[i].set_time = tmp_set_time;
+
+       return 0;
+    }
+
+    return (ret);
+}
+
 krb5_error_code
 hdb_unseal_key(krb5_context context, HDB *db, Key *k)
 {
@@ -526,14 +651,31 @@ hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey)
 krb5_error_code
 hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
 {
-    size_t i;
-    for(i = 0; i < ent->keys.len; i++){
-       krb5_error_code ret;
+    HDB_extension *ext;
+    HDB_Ext_KeySet *hist_keys;
+    size_t i, k;
+    krb5_error_code ret;
 
+    for(i = 0; i < ent->keys.len; i++){
        ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey);
        if (ret)
            return ret;
     }
+
+    ext = hdb_find_extension(ent, choice_HDB_extension_data_hist_keys);
+    if (ext == NULL)
+       return 0;
+    hist_keys = &ext->data.u.hist_keys;
+
+    for (i = 0; i < hist_keys->len; i++) {
+       for (k = 0; k < hist_keys->val[i].keys.len; k++) {
+           ret = hdb_seal_key_mkey(context, &hist_keys->val[i].keys.val[k],
+                                   mkey);
+           if (ret)
+               return ret;
+       }
+    }
+
     return 0;
 }
 
index 50a36cec0aa9310c667093eb229d03bffe5782da..f80fb78a654c6b25e76576f10a91e4805e4723d2 100644 (file)
@@ -4,6 +4,7 @@ HEIMDAL_HDB_1.0 {
        global:
                encode_hdb_keyset;
                hdb_add_master_key;
+               hdb_add_current_keys_to_history;
                hdb_check_db_format;
                hdb_clear_extension;
                hdb_clear_master_key;
@@ -74,33 +75,44 @@ HEIMDAL_HDB_1.0 {
                hdb_kt_ops;
 
                # some random bits needed for libkadm
-               HDBFlags2int;
+               add_HDB_Ext_KeySet;
+               add_Keys;
                asn1_HDBFlags_units;
                copy_Event;
                copy_HDB_extensions;
                copy_Key;
+               copy_Keys;
                copy_Salt;
                decode_HDB_Ext_Aliases;
-               decode_HDB_Ext_PKINIT_acl;
                decode_HDB_extension;
+               decode_HDB_Ext_PKINIT_acl;
                decode_Key;
+               decode_Keys;
                encode_HDB_Ext_Aliases;
-               encode_HDB_Ext_PKINIT_acl;
                encode_HDB_extension;
+               encode_HDB_Ext_PKINIT_acl;
                encode_Key;
+               encode_Keys;
                free_Event;
+               free_hdb_entry;
                free_HDB_Ext_Aliases;
-               free_HDB_Ext_PKINIT_acl;
                free_HDB_extension;
                free_HDB_extensions;
+               free_HDB_Ext_PKINIT_acl;
+               free_hdb_keyset;
                free_Key;
+               free_Keys;
                free_Salt;
-               free_hdb_entry;
+               HDBFlags2int;
                int2HDBFlags;
                length_HDB_Ext_Aliases;
-               length_HDB_Ext_PKINIT_acl;
                length_HDB_extension;
+               length_HDB_Ext_PKINIT_acl;
                length_Key;
+               length_Keys;
+               remove_Keys;
+               add_Keys;
+               add_HDB_Ext_Keyset;
 
        local:
                *;
index 518e19359c1577537e94c5a8df022fb824dd3b2c..33f4ed283d47b86ae9da30e1466acd9ac215a611 100644 (file)
@@ -58,7 +58,7 @@ krb5_auth_con_init(krb5_context context,
     p->remote_address = NULL;
     p->local_port     = 0;
     p->remote_port    = 0;
-    p->keytype        = KEYTYPE_NULL;
+    p->keytype        = KRB5_ENCTYPE_NULL;
     p->cksumtype      = CKSUMTYPE_NONE;
     *auth_context     = p;
     return 0;
index e8facd85dd412bf5b74ff31930e2339c70cd8489..783372b39988b9697f83af986dfec22189c49fce 100644 (file)
@@ -38,7 +38,7 @@
  */
 
 static struct _krb5_key_type keytype_aes128 = {
-    KEYTYPE_AES128,
+    KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96,
     "aes-128",
     128,
     16,
@@ -52,7 +52,7 @@ static struct _krb5_key_type keytype_aes128 = {
 };
 
 static struct _krb5_key_type keytype_aes256 = {
-    KEYTYPE_AES256,
+    KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96,
     "aes-256",
     256,
     32,
index 82769aea621cf4275d5780298c17a1d704dd75f6..1d4f94672abab6678afd03c241832a22fccc2ee6 100644 (file)
@@ -38,7 +38,7 @@
 #include "krb5_locl.h"
 
 static struct _krb5_key_type keytype_arcfour = {
-    KEYTYPE_ARCFOUR,
+    KRB5_ENCTYPE_ARCFOUR_HMAC_MD5,
     "arcfour",
     128,
     16,
index 63ce901d92582ff5442841d1f6a37b1022172f4b..f6f1c6881c915dc7accc344b02fdb96ae0c495d5 100644 (file)
@@ -69,7 +69,7 @@ krb5_DES_random_to_key(krb5_context context,
 }
 
 static struct _krb5_key_type keytype_des_old = {
-    KEYTYPE_DES,
+    ETYPE_DES_CBC_CRC,
     "des-old",
     56,
     8,
@@ -83,7 +83,7 @@ static struct _krb5_key_type keytype_des_old = {
 };
 
 static struct _krb5_key_type keytype_des = {
-    KEYTYPE_DES,
+    ETYPE_DES_CBC_CRC,
     "des",
     56,
     8,
index d50c5cebe2e33d0de84d8c528dba9844a704de56..43806038b7145c0639fd8005cf4fd730fe4c094e 100644 (file)
@@ -55,7 +55,7 @@ DES3_random_key(krb5_context context,
 
 #ifdef DES3_OLD_ENCTYPE
 static struct _krb5_key_type keytype_des3 = {
-    KEYTYPE_DES3,
+    ETYPE_OLD_DES3_CBC_SHA1,
     "des3",
     168,
     24,
@@ -70,7 +70,7 @@ static struct _krb5_key_type keytype_des3 = {
 #endif
 
 static struct _krb5_key_type keytype_des3_derived = {
-    KEYTYPE_DES3,
+    ETYPE_OLD_DES3_CBC_SHA1,
     "des3",
     168,
     24,
index 69d0e7c34e37d010215eed69c4b22e4501abfb33..b647a6d109237a5f455ebbfe444ad1b2cc3096e9 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 
 static struct _krb5_key_type keytype_null = {
-    KEYTYPE_NULL,
+    KRB5_ENCTYPE_NULL,
     "null",
     0,
     0,
index 63aedc45684e243d0e24def7a7a9f7cfaea6c659..732311bec9f49825189b41d0713aeefa0e91a301 100644 (file)
@@ -693,24 +693,36 @@ krb5_enctype_to_keytype(krb5_context context,
     return 0;
 }
 
+/**
+ * Check if a enctype is valid, return 0 if it is.
+ *
+ * @param context Kerberos context
+ * @param etype enctype to check if its valid or not
+ *
+ * @return Return an error code for an failure or 0 on success (enctype valid).
+ * @ingroup krb5_crypto
+ */
+
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_enctype_valid(krb5_context context,
                   krb5_enctype etype)
 {
     struct _krb5_encryption_type *e = _krb5_find_enctype(etype);
+    if(e && (e->flags & F_DISABLED) == 0)
+       return 0;
+    if (context == NULL)
+       return KRB5_PROG_ETYPE_NOSUPP;
     if(e == NULL) {
        krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
                                N_("encryption type %d not supported", ""),
                                etype);
        return KRB5_PROG_ETYPE_NOSUPP;
     }
-    if (e->flags & F_DISABLED) {
-       krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
-                               N_("encryption type %s is disabled", ""),
-                               e->name);
-       return KRB5_PROG_ETYPE_NOSUPP;
-    }
-    return 0;
+    /* Must be (e->flags & F_DISABLED) */
+    krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+                           N_("encryption type %s is disabled", ""),
+                           e->name);
+    return KRB5_PROG_ETYPE_NOSUPP;
 }
 
 /**
@@ -1886,11 +1898,11 @@ _krb5_derive_key(krb5_context context,
 
     /* XXX keytype dependent post-processing */
     switch(kt->type) {
-    case KEYTYPE_DES3:
+    case KRB5_ENCTYPE_OLD_DES3_CBC_SHA1:
        _krb5_DES3_random_to_key(context, key->key, k, nblocks * et->blocksize);
        break;
-    case KEYTYPE_AES128:
-    case KEYTYPE_AES256:
+    case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+    case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96:
        memcpy(key->key->keyvalue.data, k, key->key->keyvalue.length);
        break;
     default:
index bf945875b900841262ea4a8d4211fb642f38fa73..9b95b8f0cbcc5db2c793c2c7a762038712098350 100644 (file)
@@ -69,7 +69,7 @@ struct salt_type {
 };
 
 struct _krb5_key_type {
-    krb5_keytype type; /* XXX */
+    krb5_enctype type;
     const char *name;
     size_t bits;
     size_t size;
index 7a7b989b69e863e647550d6434239a9ca36e92c9..bebd4c490ee1855d52d718fcb87ac16fce54a14a 100644 (file)
@@ -59,6 +59,8 @@ krb5_clear_error_message(krb5_context context)
  * Set the context full error string for a specific error code.
  * The error that is stored should be internationalized.
  *
+ * The if context is NULL, no error string is stored.
+ *
  * @param context Kerberos 5 context
  * @param ret The error code
  * @param fmt Error string for the error code
@@ -82,6 +84,8 @@ krb5_set_error_message(krb5_context context, krb5_error_code ret,
 /**
  * Set the context full error string for a specific error code.
  *
+ * The if context is NULL, no error string is stored.
+ *
  * @param context Kerberos 5 context
  * @param ret The error code
  * @param fmt Error string for the error code
@@ -98,6 +102,9 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret,
 {
     int r;
 
+    if (context == NULL)
+       return;
+
     HEIMDAL_MUTEX_lock(context->mutex);
     if (context->error_string) {
        free(context->error_string);
@@ -114,6 +121,8 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret,
  * Prepend the context full error string for a specific error code.
  * The error that is stored should be internationalized.
  *
+ * The if context is NULL, no error string is stored.
+ *
  * @param context Kerberos 5 context
  * @param ret The error code
  * @param fmt Error string for the error code
@@ -137,6 +146,8 @@ krb5_prepend_error_message(krb5_context context, krb5_error_code ret,
 /**
  * Prepend the contexts's full error string for a specific error code.
  *
+ * The if context is NULL, no error string is stored.
+ *
  * @param context Kerberos 5 context
  * @param ret The error code
  * @param fmt Error string for the error code
@@ -151,6 +162,10 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret,
     __attribute__ ((format (printf, 3, 0)))
 {
     char *str = NULL, *str2 = NULL;
+
+    if (context == NULL)
+       return;
+
     HEIMDAL_MUTEX_lock(context->mutex);
     if (context->error_code != ret) {
        HEIMDAL_MUTEX_unlock(context->mutex);
index e3bb23a2e9d72b9ef9bdea46f5ecd4cc05f4bfec..51550daa4ceabd6ba4cd9371ac141020193eef1c 100644 (file)
@@ -543,6 +543,11 @@ get_cred_kdc(krb5_context context,
        /* this should go someplace else */
        out_creds->times.endtime = in_creds->times.endtime;
 
+       /*
+        * Windows KDCs always canonicalize the server name
+        */
+       eflags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
+
        /* XXX should do better testing */
        if (flags.b.constrained_delegation || impersonate_principal)
            eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
index 979fc9b0ae99368f54e9a92e5d840ca092b64f0e..2ec1c5e41b6f86bf004870bbc1ac5bb8eab75f2d 100644 (file)
@@ -407,7 +407,7 @@ krb5_get_forwarded_creds (krb5_context          context,
      */
 
     if (auth_context->flags & KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED) {
-       cred.enc_part.etype = ENCTYPE_NULL;
+       cred.enc_part.etype = KRB5_ENCTYPE_NULL;
        cred.enc_part.kvno = NULL;
        cred.enc_part.cipher.data = buf;
        cred.enc_part.cipher.length = buf_size;
index 27f4964e61e77bb6f85708deb3d0c9aaf51503d4..41618b9616a40df7d4700926f7df23a758fa7088 100644 (file)
@@ -480,7 +480,7 @@ krb5_get_in_cred(krb5_context context,
        }
     }
     if(pa) {
-       salt.salttype = pa->padata_type;
+       salt.salttype = (krb5_salttype)pa->padata_type;
        salt.saltvalue = pa->padata_value;
 
        ret = (*key_proc)(context, etype, salt, keyseed, &key);
index f2185628e5c4bfea7f2d2aa2a57cee901d75e7b5..6c874126ab5a47e6f5efef0662095bd2256dc2ae 100644 (file)
@@ -859,7 +859,7 @@ pa_pw_or_afs3_salt(krb5_context context,
                   heim_octet_string *data)
 {
     krb5_error_code ret;
-    if (paid->etype == ENCTYPE_NULL)
+    if (paid->etype == KRB5_ENCTYPE_NULL)
        return NULL;
     ret = set_paid(paid, context,
                   paid->etype,
@@ -915,7 +915,7 @@ process_pa_info(krb5_context context,
        PA_DATA *pa = find_pa_data(md, pa_prefs[i].type);
        if (pa == NULL)
            continue;
-       paid->salt.salttype = pa_prefs[i].type;
+       paid->salt.salttype = (krb5_salttype)pa_prefs[i].type;
        p = (*pa_prefs[i].salt_info)(context, client, asreq,
                                     paid, &pa->padata_value);
     }
@@ -1204,7 +1204,7 @@ process_pa_data_to_md(krb5_context context,
 
        paid = calloc(1, sizeof(*paid));
 
-       paid->etype = ENCTYPE_NULL;
+       paid->etype = KRB5_ENCTYPE_NULL;
        ppaid = process_pa_info(context, creds->client, a, paid, in_md);
 
        if (ppaid)
index 9ba9c4b290daa54e230428ce98c4f464c399b594..6e781aca782e56adba1f74d36419a67ec1da7684 100644 (file)
@@ -65,7 +65,7 @@ krb5_free_keyblock_contents(krb5_context context,
        if (keyblock->keyvalue.data != NULL)
            memset(keyblock->keyvalue.data, 0, keyblock->keyvalue.length);
        krb5_data_free (&keyblock->keyvalue);
-       keyblock->keytype = ENCTYPE_NULL;
+       keyblock->keytype = KRB5_ENCTYPE_NULL;
     }
 }
 
index 2224b92e95b57def6947c8b9f605dec29bdf342f..9c0f5669466c43bdd8e69fd5d4bdabc2fe39284a 100644 (file)
@@ -326,7 +326,9 @@ typedef HostAddress krb5_address;
 
 typedef HostAddresses krb5_addresses;
 
-typedef enum krb5_keytype {
+typedef krb5_enctype krb5_keytype;
+
+enum krb5_keytype_old {
     KEYTYPE_NULL       = ETYPE_NULL,
     KEYTYPE_DES                = ETYPE_DES_CBC_CRC,
     KEYTYPE_DES3       = ETYPE_OLD_DES3_CBC_SHA1,
@@ -334,7 +336,7 @@ typedef enum krb5_keytype {
     KEYTYPE_AES256     = ETYPE_AES256_CTS_HMAC_SHA1_96,
     KEYTYPE_ARCFOUR    = ETYPE_ARCFOUR_HMAC_MD5,
     KEYTYPE_ARCFOUR_56 = ETYPE_ARCFOUR_HMAC_MD5_56
-} krb5_keytype;
+};
 
 typedef EncryptionKey krb5_keyblock;
 
@@ -876,6 +878,11 @@ typedef struct {
 typedef krb5_error_code
 (KRB5_CALLCONV * krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *);
 
+typedef struct {
+    krb5_enctype       ks_enctype;
+    krb5int32          ks_salttype;
+}krb5_key_salt_tuple;
+
 /*
  *
  */
index 803a5bf289484629af8fe1c405f2f899ef44edb3..16c230a11f96fa136111f617cd6baca513869bd6 100644 (file)
@@ -139,7 +139,7 @@ krb5_checksum_free(krb5_context context, krb5_checksum *cksum)
 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
 krb5_c_valid_enctype (krb5_enctype etype)
 {
-    return krb5_enctype_valid(NULL, etype);
+    return !krb5_enctype_valid(NULL, etype);
 }
 
 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
index fad84ebb5ba6b8432b74ec4bdea0b4b50c7bcf9d..818e6e071cbd405d9127d2dbaa8b51e005faae85 100644 (file)
@@ -285,6 +285,7 @@ HEIMDAL_KRB5_2.0 {
                krb5_free_creds_contents;
                krb5_free_data;
                krb5_free_data_contents;
+               krb5_free_default_realm;
                krb5_free_error;
                krb5_free_error_contents;
                krb5_free_error_string;