summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-07-25 18:51:53 +0200
committerStefan Metzmacher <metze@samba.org>2011-07-26 02:16:08 +0200
commit5a8635bca1b6d60a5b81c602eb4f0b7fd8902d7b (patch)
treea9a73cdf05ce487a174c9ef7ab334007348e7248
parentf1a59f9d6f45987acd0304ee58e4488333faad18 (diff)
downloadsamba-5a8635bca1b6d60a5b81c602eb4f0b7fd8902d7b.tar.gz
samba-5a8635bca1b6d60a5b81c602eb4f0b7fd8902d7b.tar.bz2
samba-5a8635bca1b6d60a5b81c602eb4f0b7fd8902d7b.zip
s4:heimdal: import lorikeet-heimdal-201107241840 (commit 0fdf11fa3cdb47df9f5393ebf36d9f5742243036)
-rw-r--r--source4/heimdal/kdc/default_config.c2
-rw-r--r--source4/heimdal/kdc/kerberos5.c2
-rw-r--r--source4/heimdal/kdc/krb5tgs.c12
-rw-r--r--source4/heimdal/kdc/misc.c2
-rw-r--r--source4/heimdal/kdc/pkinit.c2
-rw-r--r--source4/heimdal/kuser/kinit.c2
-rw-r--r--source4/heimdal/lib/asn1/krb5.asn12
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h12
-rw-r--r--source4/heimdal/lib/gssapi/krb5/arcfour.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c15
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c15
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c16
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c30
-rw-r--r--source4/heimdal/lib/gssapi/version-script.map2
-rw-r--r--source4/heimdal/lib/hcrypto/pkcs12.c9
-rw-r--r--source4/heimdal/lib/hdb/db.c22
-rw-r--r--source4/heimdal/lib/hdb/ext.c64
-rw-r--r--source4/heimdal/lib/hdb/hdb.asn125
-rw-r--r--source4/heimdal/lib/hdb/hdb.c5
-rw-r--r--source4/heimdal/lib/hdb/hdb.h8
-rw-r--r--source4/heimdal/lib/hdb/hdb_err.et1
-rw-r--r--source4/heimdal/lib/hdb/hdb_locl.h3
-rw-r--r--source4/heimdal/lib/hdb/keys.c143
-rw-r--r--source4/heimdal/lib/hdb/mkey.c150
-rw-r--r--source4/heimdal/lib/hdb/version-script.map24
-rw-r--r--source4/heimdal/lib/krb5/auth_context.c2
-rw-r--r--source4/heimdal/lib/krb5/crypto-aes.c4
-rw-r--r--source4/heimdal/lib/krb5/crypto-arcfour.c2
-rw-r--r--source4/heimdal/lib/krb5/crypto-des.c4
-rw-r--r--source4/heimdal/lib/krb5/crypto-des3.c4
-rw-r--r--source4/heimdal/lib/krb5/crypto-null.c2
-rw-r--r--source4/heimdal/lib/krb5/crypto.c32
-rw-r--r--source4/heimdal/lib/krb5/crypto.h2
-rw-r--r--source4/heimdal/lib/krb5/error_string.c15
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c5
-rw-r--r--source4/heimdal/lib/krb5/get_for_creds.c2
-rw-r--r--source4/heimdal/lib/krb5/get_in_tkt.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c6
-rw-r--r--source4/heimdal/lib/krb5/keyblock.c2
-rw-r--r--source4/heimdal/lib/krb5/krb5.h11
-rw-r--r--source4/heimdal/lib/krb5/mit_glue.c2
-rw-r--r--source4/heimdal/lib/krb5/version-script.map1
42 files changed, 555 insertions, 115 deletions
diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c
index fe977ded5a..6fbf5fdae1 100644
--- a/source4/heimdal/kdc/default_config.c
+++ b/source4/heimdal/kdc/default_config.c
@@ -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;
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 4bc1619170..c13abb7ce0 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -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
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 92cce5759f..6aad65d408 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -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;
diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c
index f9b34571a3..1b2c440005 100644
--- a/source4/heimdal/kdc/misc.c
+++ b/source4/heimdal/kdc/misc.c
@@ -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)
{
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index a02cb816ab..d85b156500 100644
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -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);
diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c
index e872fef9be..0b3876dcc5 100644
--- a/source4/heimdal/kuser/kinit.c
+++ b/source4/heimdal/kuser/kinit.c
@@ -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,
diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1
index 02fab7a3a6..568fe0cd04 100644
--- a/source4/heimdal/lib/asn1/krb5.asn1
+++ b/source4/heimdal/lib/asn1/krb5.asn1
@@ -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
}
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
index fa53a29d24..bbb2fd54c9 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -61,6 +61,11 @@
#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_ */
diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c
index 0264207e4a..f5e41e4056 100644
--- a/source4/heimdal/lib/gssapi/krb5/arcfour.c
+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index 0109ca7c6e..d032d23d5f 100644
--- a/source4/heimdal/lib/gssapi/krb5/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index d6bc204777..b3da35ee9e 100644
--- a/source4/heimdal/lib/gssapi/krb5/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -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);
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index 3123787ff4..af06e0a1e3 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index efd0d82c49..4d095c8e87 100644
--- a/source4/heimdal/lib/gssapi/krb5/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -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);
diff --git a/source4/heimdal/lib/gssapi/version-script.map b/source4/heimdal/lib/gssapi/version-script.map
index ebd8ee21ac..bcb79bf8f7 100644
--- a/source4/heimdal/lib/gssapi/version-script.map
+++ b/source4/heimdal/lib/gssapi/version-script.map
@@ -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;
diff --git a/source4/heimdal/lib/hcrypto/pkcs12.c b/source4/heimdal/lib/hcrypto/pkcs12.c
index a890f01a3d..ff0f77644e 100644
--- a/source4/heimdal/lib/hcrypto/pkcs12.c
+++ b/source4/heimdal/lib/hcrypto/pkcs12.c
@@ -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)];
diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c
index 69940edf89..2ed054a631 100644
--- a/source4/heimdal/lib/hdb/db.c
+++ b/source4/heimdal/lib/hdb/db.c
@@ -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);
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
index d2a4373b9b..f4f1715240 100644
--- a/source4/heimdal/lib/hdb/ext.c
+++ b/source4/heimdal/lib/hdb/ext.c
@@ -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);
+}
diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1
index a72851c9f2..0594b313b7 100644
--- a/source4/heimdal/lib/hdb/hdb.asn1
+++ b/source4/heimdal/lib/hdb/hdb.asn1
@@ -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,
diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c
index ca05cc4a17..5dc5a0957e 100644
--- a/source4/heimdal/lib/hdb/hdb.c
+++ b/source4/heimdal/lib/hdb/hdb.c
@@ -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);
}
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 469ec82ec0..75d18770f0 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -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.
*
diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et
index 2cad4daba4..0bdcb385f6 100644
--- a/source4/heimdal/lib/hdb/hdb_err.et
+++ b/source4/heimdal/lib/hdb/hdb_err.et
@@ -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
diff --git a/source4/heimdal/lib/hdb/hdb_locl.h b/source4/heimdal/lib/hdb/hdb_locl.h
index e896b58025..c210b98b84 100644
--- a/source4/heimdal/lib/hdb/hdb_locl.h
+++ b/source4/heimdal/lib/hdb/hdb_locl.h
@@ -36,6 +36,9 @@
#ifndef __HDB_LOCL_H__
#define __HDB_LOCL_H__
+#include <assert.h>
+#include <heimbase.h>
+
#include <config.h>
#include <stdio.h>
diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c
index 3d0b9d7c1b..0bc3392fb6 100644
--- a/source4/heimdal/lib/hdb/keys.c
+++ b/source4/heimdal/lib/hdb/keys.c
@@ -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;
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
index 9a13d55a51..6dcfc02942 100644
--- a/source4/heimdal/lib/hdb/mkey.c
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -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);
@@ -480,6 +480,131 @@ hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
}
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)
{
if (db->hdb_master_key_set == 0)
@@ -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;
}
diff --git a/source4/heimdal/lib/hdb/version-script.map b/source4/heimdal/lib/hdb/version-script.map
index 50a36cec0a..f80fb78a65 100644
--- a/source4/heimdal/lib/hdb/version-script.map
+++ b/source4/heimdal/lib/hdb/version-script.map
@@ -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:
*;
diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c
index 518e19359c..33f4ed283d 100644
--- a/source4/heimdal/lib/krb5/auth_context.c
+++ b/source4/heimdal/lib/krb5/auth_context.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/crypto-aes.c b/source4/heimdal/lib/krb5/crypto-aes.c
index e8facd85dd..783372b399 100644
--- a/source4/heimdal/lib/krb5/crypto-aes.c
+++ b/source4/heimdal/lib/krb5/crypto-aes.c
@@ -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,
diff --git a/source4/heimdal/lib/krb5/crypto-arcfour.c b/source4/heimdal/lib/krb5/crypto-arcfour.c
index 82769aea62..1d4f94672a 100644
--- a/source4/heimdal/lib/krb5/crypto-arcfour.c
+++ b/source4/heimdal/lib/krb5/crypto-arcfour.c
@@ -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,
diff --git a/source4/heimdal/lib/krb5/crypto-des.c b/source4/heimdal/lib/krb5/crypto-des.c
index 63ce901d92..f6f1c6881c 100644
--- a/source4/heimdal/lib/krb5/crypto-des.c
+++ b/source4/heimdal/lib/krb5/crypto-des.c
@@ -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,
diff --git a/source4/heimdal/lib/krb5/crypto-des3.c b/source4/heimdal/lib/krb5/crypto-des3.c
index d50c5cebe2..43806038b7 100644
--- a/source4/heimdal/lib/krb5/crypto-des3.c
+++ b/source4/heimdal/lib/krb5/crypto-des3.c
@@ -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,
diff --git a/source4/heimdal/lib/krb5/crypto-null.c b/source4/heimdal/lib/krb5/crypto-null.c
index 69d0e7c34e..b647a6d109 100644
--- a/source4/heimdal/lib/krb5/crypto-null.c
+++ b/source4/heimdal/lib/krb5/crypto-null.c
@@ -38,7 +38,7 @@
#endif
static struct _krb5_key_type keytype_null = {
- KEYTYPE_NULL,
+ KRB5_ENCTYPE_NULL,
"null",
0,
0,
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 63aedc4568..732311bec9 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -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:
diff --git a/source4/heimdal/lib/krb5/crypto.h b/source4/heimdal/lib/krb5/crypto.h
index bf945875b9..9b95b8f0cb 100644
--- a/source4/heimdal/lib/krb5/crypto.h
+++ b/source4/heimdal/lib/krb5/crypto.h
@@ -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;
diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c
index 7a7b989b69..bebd4c490e 100644
--- a/source4/heimdal/lib/krb5/error_string.c
+++ b/source4/heimdal/lib/krb5/error_string.c
@@ -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);
diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c
index e3bb23a2e9..51550daa4c 100644
--- a/source4/heimdal/lib/krb5/get_cred.c
+++ b/source4/heimdal/lib/krb5/get_cred.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c
index 979fc9b0ae..2ec1c5e41b 100644
--- a/source4/heimdal/lib/krb5/get_for_creds.c
+++ b/source4/heimdal/lib/krb5/get_for_creds.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c
index 27f4964e61..41618b9616 100644
--- a/source4/heimdal/lib/krb5/get_in_tkt.c
+++ b/source4/heimdal/lib/krb5/get_in_tkt.c
@@ -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);
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index f2185628e5..6c874126ab 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -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)
diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c
index 9ba9c4b290..6e781aca78 100644
--- a/source4/heimdal/lib/krb5/keyblock.c
+++ b/source4/heimdal/lib/krb5/keyblock.c
@@ -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;
}
}
diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h
index 2224b92e95..9c0f566946 100644
--- a/source4/heimdal/lib/krb5/krb5.h
+++ b/source4/heimdal/lib/krb5/krb5.h
@@ -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;
+
/*
*
*/
diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c
index 803a5bf289..16c230a11f 100644
--- a/source4/heimdal/lib/krb5/mit_glue.c
+++ b/source4/heimdal/lib/krb5/mit_glue.c
@@ -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
diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map
index fad84ebb5b..818e6e071c 100644
--- a/source4/heimdal/lib/krb5/version-script.map
+++ b/source4/heimdal/lib/krb5/version-script.map
@@ -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;