summaryrefslogtreecommitdiff
path: root/source4/heimdal/kdc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-07-03 08:00:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:58:59 -0500
commitec0035c9b8e0690f3bc21f3de089c39eae660916 (patch)
tree183dddce1bc0704f0c137df03e611d255fb68e11 /source4/heimdal/kdc
parent74b35321dc043188386d0305508b5276a5290d0d (diff)
downloadsamba-ec0035c9b8e0690f3bc21f3de089c39eae660916.tar.gz
samba-ec0035c9b8e0690f3bc21f3de089c39eae660916.tar.bz2
samba-ec0035c9b8e0690f3bc21f3de089c39eae660916.zip
r23678: Update to current lorikeet-heimdal (-r 767), which should fix the
panics on hosts without /dev/random. Andrew Bartlett (This used to be commit 14a4ddb131993fec72316f7e8e371638749e6f1f)
Diffstat (limited to 'source4/heimdal/kdc')
-rw-r--r--source4/heimdal/kdc/default_config.c19
-rw-r--r--source4/heimdal/kdc/digest.c140
-rw-r--r--source4/heimdal/kdc/kdc-protos.h7
-rw-r--r--source4/heimdal/kdc/kdc.h8
-rw-r--r--source4/heimdal/kdc/krb5tgs.c32
-rw-r--r--source4/heimdal/kdc/misc.c11
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c16
7 files changed, 142 insertions, 91 deletions
diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c
index c28bd424ea..e06366f214 100644
--- a/source4/heimdal/kdc/default_config.c
+++ b/source4/heimdal/kdc/default_config.c
@@ -36,10 +36,9 @@
#include <getarg.h>
#include <parse_bytes.h>
-RCSID("$Id: default_config.c 20532 2007-04-23 07:46:57Z lha $");
+RCSID("$Id: default_config.c 21296 2007-06-25 14:49:11Z lha $");
-
-int
+krb5_error_code
krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
{
krb5_kdc_configuration *c;
@@ -62,7 +61,8 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->enable_524 = FALSE;
c->enable_v4_cross_realm = FALSE;
c->enable_pkinit = FALSE;
- c->enable_pkinit_princ_in_cert = TRUE;
+ c->pkinit_princ_in_cert = TRUE;
+ c->pkinit_require_binding = TRUE;
c->db = NULL;
c->num_db = 0;
c->logf = NULL;
@@ -257,12 +257,19 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
krb5_config_free_strings(pool_list);
krb5_config_free_strings(revoke_list);
- c->enable_pkinit_princ_in_cert =
+ c->pkinit_princ_in_cert =
krb5_config_get_bool_default(context, NULL,
- c->enable_pkinit_princ_in_cert,
+ c->pkinit_princ_in_cert,
"kdc",
"pkinit_principal_in_certificate",
NULL);
+
+ c->pkinit_require_binding =
+ krb5_config_get_bool_default(context, NULL,
+ c->pkinit_require_binding,
+ "kdc",
+ "pkinit_win2k_require_binding",
+ NULL);
}
c->pkinit_dh_min_bits =
diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c
index 811ab639f1..801449fe5e 100644
--- a/source4/heimdal/kdc/digest.c
+++ b/source4/heimdal/kdc/digest.c
@@ -34,7 +34,7 @@
#include "kdc_locl.h"
#include <hex.h>
-RCSID("$Id: digest.c 20877 2007-06-04 04:07:26Z lha $");
+RCSID("$Id: digest.c 21241 2007-06-20 11:30:19Z lha $");
#define MS_CHAP_V2 0x20
#define CHAP_MD5 0x10
@@ -160,6 +160,44 @@ static const unsigned char ms_rfc3079_magic1[27] = {
*
*/
+static krb5_error_code
+get_password_entry(krb5_context context,
+ krb5_kdc_configuration *config,
+ const char *username,
+ char **password)
+{
+ krb5_principal clientprincipal;
+ krb5_error_code ret;
+ hdb_entry_ex *user;
+ HDB *db;
+
+ /* get username */
+ ret = krb5_parse_name(context, username, &clientprincipal);
+ if (ret)
+ return ret;
+
+ ret = _kdc_db_fetch(context, config, clientprincipal,
+ HDB_F_GET_CLIENT, &db, &user);
+ krb5_free_principal(context, clientprincipal);
+ if (ret)
+ return ret;
+
+ ret = hdb_entry_get_password(context, db, &user->entry, password);
+ if (ret || password == NULL) {
+ if (ret == 0) {
+ ret = EINVAL;
+ krb5_set_error_string(context, "password missing");
+ }
+ memset(user, 0, sizeof(*user));
+ }
+ _kdc_free_ent (context, user);
+ return ret;
+}
+
+/*
+ *
+ */
+
krb5_error_code
_kdc_do_digest(krb5_context context,
krb5_kdc_configuration *config,
@@ -461,9 +499,6 @@ _kdc_do_digest(krb5_context context,
break;
}
case choice_DigestReqInner_digestRequest: {
- krb5_principal clientprincipal;
- HDB *db;
-
sp = krb5_storage_emem();
if (sp == NULL) {
ret = ENOMEM;
@@ -571,29 +606,6 @@ _kdc_do_digest(krb5_context context,
}
}
- /* get username */
- ret = krb5_parse_name(context,
- ireq.u.digestRequest.username,
- &clientprincipal);
- if (ret)
- goto out;
-
- ret = _kdc_db_fetch(context, config, clientprincipal,
- HDB_F_GET_CLIENT, &db, &user);
-
- krb5_free_principal(context, clientprincipal);
- if (ret)
- goto out;
-
- ret = hdb_entry_get_password(context, db, &user->entry, &password);
- if (ret || password == NULL) {
- if (ret == 0) {
- ret = EINVAL;
- krb5_set_error_string(context, "password missing");
- }
- goto out;
- }
-
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
MD5_CTX ctx;
unsigned char md[MD5_DIGEST_LENGTH];
@@ -618,6 +630,12 @@ _kdc_do_digest(krb5_context context,
goto out;
}
+ ret = get_password_entry(context, config,
+ ireq.u.digestRequest.username,
+ &password);
+ if (ret)
+ goto out;
+
MD5_Init(&ctx);
MD5_Update(&ctx, &id, 1);
MD5_Update(&ctx, password, strlen(password));
@@ -664,6 +682,12 @@ _kdc_do_digest(krb5_context context,
if (ireq.u.digestRequest.realm == NULL)
goto out;
+ ret = get_password_entry(context, config,
+ ireq.u.digestRequest.username,
+ &password);
+ if (ret)
+ goto failed;
+
MD5_Init(&ctx);
MD5_Update(&ctx, ireq.u.digestRequest.username,
strlen(ireq.u.digestRequest.username));
@@ -692,7 +716,7 @@ _kdc_do_digest(krb5_context context,
if (A1 == NULL) {
krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
- goto out;
+ goto failed;
}
MD5_Init(&ctx);
@@ -712,7 +736,7 @@ _kdc_do_digest(krb5_context context,
krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
free(A1);
- goto out;
+ goto failed;
}
MD5_Init(&ctx);
@@ -758,6 +782,7 @@ _kdc_do_digest(krb5_context context,
} else if (strcasecmp(ireq.u.digestRequest.type, "MS-CHAP-V2") == 0) {
unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH];
+ krb5_principal clientprincipal = NULL;
char *mdx;
const char *username;
struct ntlm_buf answer;
@@ -766,20 +791,20 @@ _kdc_do_digest(krb5_context context,
if ((config->digests_allowed & MS_CHAP_V2) == 0) {
kdc_log(context, config, 0, "MS-CHAP-V2 not allowed");
- goto out;
+ goto failed;
}
if (ireq.u.digestRequest.clientNonce == NULL) {
krb5_set_error_string(context,
"MS-CHAP-V2 clientNonce missing");
ret = EINVAL;
- goto out;
+ goto failed;
}
if (serverNonce.length != 16) {
krb5_set_error_string(context,
"MS-CHAP-V2 serverNonce wrong length");
ret = EINVAL;
- goto out;
+ goto failed;
}
/* strip of the domain component */
@@ -821,7 +846,7 @@ _kdc_do_digest(krb5_context context,
/* NtPasswordHash */
ret = krb5_parse_name(context, username, &clientprincipal);
if (ret)
- goto out;
+ goto failed;
ret = _kdc_db_fetch(context, config, clientprincipal,
HDB_F_GET_CLIENT, NULL, &user);
@@ -830,7 +855,7 @@ _kdc_do_digest(krb5_context context,
krb5_set_error_string(context,
"MS-CHAP-V2 user %s not in database",
username);
- goto out;
+ goto failed;
}
ret = hdb_enctype2key(context, &user->entry,
@@ -839,7 +864,7 @@ _kdc_do_digest(krb5_context context,
krb5_set_error_string(context,
"MS-CHAP-V2 missing arcfour key %s",
username);
- goto out;
+ goto failed;
}
/* ChallengeResponse */
@@ -848,7 +873,7 @@ _kdc_do_digest(krb5_context context,
challange, &answer);
if (ret) {
krb5_set_error_string(context, "NTLM missing arcfour key");
- goto out;
+ goto failed;
}
hex_encode(answer.data, answer.length, &mdx);
@@ -861,15 +886,15 @@ _kdc_do_digest(krb5_context context,
r.element = choice_DigestRepInner_response;
ret = strcasecmp(mdx, ireq.u.digestRequest.responseData);
- free(mdx);
if (ret == 0) {
r.u.response.success = TRUE;
} else {
kdc_log(context, config, 0,
- "MS-CHAP-V2 reply mismatch for %s",
+ "MS-CHAP-V2 hash mismatch for %s",
ireq.u.digestRequest.username);
r.u.response.success = FALSE;
}
+ free(mdx);
if (r.u.response.success) {
unsigned char hashhash[MD4_DIGEST_LENGTH];
@@ -958,7 +983,7 @@ _kdc_do_digest(krb5_context context,
if ((config->digests_allowed & (NTLM_V1|NTLM_V1_SESSION|NTLM_V2)) == 0) {
kdc_log(context, config, 0, "NTLM not allowed");
- goto out;
+ goto failed;
}
r.element = choice_DigestRepInner_ntlmInitReply;
@@ -967,14 +992,14 @@ _kdc_do_digest(krb5_context context,
if ((ireq.u.ntlmInit.flags & NTLM_NEG_UNICODE) == 0) {
kdc_log(context, config, 0, "NTLM client have no unicode");
- goto out;
+ goto failed;
}
if (ireq.u.ntlmInit.flags & NTLM_NEG_NTLM)
r.u.ntlmInitReply.flags |= NTLM_NEG_NTLM;
else {
kdc_log(context, config, 0, "NTLM client doesn't support NTLM");
- goto out;
+ goto failed;
}
r.u.ntlmInitReply.flags |=
@@ -1095,7 +1120,7 @@ _kdc_do_digest(krb5_context context,
ireq.u.ntlmRequest.username,
&clientprincipal);
if (ret)
- goto out;
+ goto failed;
ret = _kdc_db_fetch(context, config, clientprincipal,
HDB_F_GET_CLIENT, NULL, &user);
@@ -1103,20 +1128,23 @@ _kdc_do_digest(krb5_context context,
if (ret) {
krb5_set_error_string(context, "NTLM user %s not in database",
ireq.u.ntlmRequest.username);
- goto out;
+ goto failed;
}
ret = get_digest_key(context, config, server, &crypto);
if (ret)
- goto out;
+ goto failed;
ret = krb5_decrypt(context, crypto, KRB5_KU_DIGEST_OPAQUE,
ireq.u.ntlmRequest.opaque.data,
ireq.u.ntlmRequest.opaque.length, &buf);
krb5_crypto_destroy(context, crypto);
crypto = NULL;
- if (ret)
- goto out;
+ if (ret) {
+ kdc_log(context, config, 0,
+ "Failed to decrypt nonce from %s", from);
+ goto failed;
+ }
sp = krb5_storage_from_data(&buf);
if (sp == NULL) {
@@ -1185,7 +1213,7 @@ _kdc_do_digest(krb5_context context,
free(targetname);
if (ret) {
krb5_set_error_string(context, "NTLM v2 verify failed");
- goto out;
+ goto failed;
}
/* XXX verify infotarget matches client (checksum ?) */
@@ -1205,14 +1233,14 @@ _kdc_do_digest(krb5_context context,
if ((config->digests_allowed & NTLM_V1_SESSION) == 0) {
kdc_log(context, config, 0, "NTLM v1-session not allowed");
ret = EINVAL;
- goto out;
+ goto failed;
}
if (ireq.u.ntlmRequest.lm.length != 24) {
krb5_set_error_string(context, "LM hash have wrong length "
"for NTLM session key");
ret = EINVAL;
- goto out;
+ goto failed;
}
MD5_Init(&md5ctx);
@@ -1223,7 +1251,7 @@ _kdc_do_digest(krb5_context context,
} else {
if ((config->digests_allowed & NTLM_V1) == 0) {
kdc_log(context, config, 0, "NTLM v1 not allowed");
- goto out;
+ goto failed;
}
}
@@ -1232,7 +1260,7 @@ _kdc_do_digest(krb5_context context,
challange, &answer);
if (ret) {
krb5_set_error_string(context, "NTLM missing arcfour key");
- goto out;
+ goto failed;
}
if (ireq.u.ntlmRequest.ntlm.length != answer.length ||
@@ -1241,7 +1269,7 @@ _kdc_do_digest(krb5_context context,
free(answer.data);
ret = EINVAL;
krb5_set_error_string(context, "NTLM hash mismatch");
- goto out;
+ goto failed;
}
free(answer.data);
@@ -1265,7 +1293,7 @@ _kdc_do_digest(krb5_context context,
"NTLM client failed to neg key "
"exchange but still sent key");
ret = EINVAL;
- goto out;
+ goto failed;
}
len = ireq.u.ntlmRequest.sessionkey->length;
@@ -1273,7 +1301,7 @@ _kdc_do_digest(krb5_context context,
krb5_set_error_string(context,
"NTLM master key wrong length: %lu",
(unsigned long)len);
- goto out;
+ goto failed;
}
RC4_set_key(&rc4, sizeof(sessionkey), sessionkey);
@@ -1301,12 +1329,12 @@ _kdc_do_digest(krb5_context context,
r.u.ntlmResponse.success = 1;
kdc_log(context, config, 0, "NTLM version %d successful for %s",
version, ireq.u.ntlmRequest.username);
-
break;
}
default:
+ failed:
r.element = choice_DigestRepInner_error;
- r.u.error.reason = strdup("unknown operation");
+ r.u.error.reason = strdup("unknown/failed operation");
if (r.u.error.reason == NULL) {
krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
diff --git a/source4/heimdal/kdc/kdc-protos.h b/source4/heimdal/kdc/kdc-protos.h
index f7df365eb2..15e8c29f4c 100644
--- a/source4/heimdal/kdc/kdc-protos.h
+++ b/source4/heimdal/kdc/kdc-protos.h
@@ -37,7 +37,7 @@ kdc_openlog (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/);
-int
+krb5_error_code
krb5_kdc_get_config (
krb5_context /*context*/,
krb5_kdc_configuration **/*config*/);
@@ -74,6 +74,11 @@ krb5_kdc_save_request (
const krb5_data */*reply*/,
const struct sockaddr */*sa*/);
+krb5_error_code
+krb5_kdc_set_dbinfo (
+ krb5_context /*context*/,
+ struct krb5_kdc_configuration */*c*/);
+
void
krb5_kdc_update_time (struct timeval */*tv*/);
diff --git a/source4/heimdal/kdc/kdc.h b/source4/heimdal/kdc/kdc.h
index eb24b4ee97..6c129f38f5 100644
--- a/source4/heimdal/kdc/kdc.h
+++ b/source4/heimdal/kdc/kdc.h
@@ -35,7 +35,7 @@
*/
/*
- * $Id: kdc.h 19907 2007-01-14 23:10:24Z lha $
+ * $Id: kdc.h 21287 2007-06-25 14:09:03Z lha $
*/
#ifndef __KDC_H__
@@ -73,13 +73,13 @@ typedef struct krb5_kdc_configuration {
krb5_boolean enable_524;
krb5_boolean enable_pkinit;
- krb5_boolean enable_pkinit_princ_in_cert;
+ krb5_boolean pkinit_princ_in_cert;
char *pkinit_kdc_ocsp_file;
+ int pkinit_dh_min_bits;
+ int pkinit_require_binding;
krb5_log_facility *logf;
- int pkinit_dh_min_bits;
-
int enable_digest;
int digests_allowed;
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 02cd92de2e..4d6be60f68 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: krb5tgs.c 21041 2007-06-10 06:21:12Z lha $");
+RCSID("$Id: krb5tgs.c 21262 2007-06-21 15:18:37Z lha $");
/*
* return the realm of a krbtgt-ticket or NULL
@@ -475,12 +475,14 @@ check_tgs_flags(krb5_context context,
et->endtime = min(*et->renew_till, et->endtime);
}
+#if 0
/* checks for excess flags */
if(f.request_anonymous && !config->allow_anonymous){
kdc_log(context, config, 0,
"Request for anonymous ticket");
return KRB5KDC_ERR_BADOPTION;
}
+#endif
return 0;
}
@@ -731,10 +733,12 @@ tgs_make_reply(krb5_context context,
&rep.ticket.realm);
_krb5_principal2principalname(&rep.ticket.sname, server->entry.principal);
copy_Realm(&tgt_name->realm, &rep.crealm);
+/*
if (f.request_anonymous)
_kdc_make_anonymous_principalname (&rep.cname);
- else
- copy_PrincipalName(&tgt_name->name, &rep.cname);
+ else */
+
+ copy_PrincipalName(&tgt_name->name, &rep.cname);
rep.ticket.tkt_vno = 5;
ek.caddr = et.caddr;
@@ -1707,24 +1711,20 @@ server_lookup:
goto out;
}
- /* check PAC if there is one */
- {
+ /* check PAC if not cross realm and if there is one */
+ if (!cross_realm) {
Key *tkey;
- krb5_keyblock *tgtkey = NULL;
- if (!cross_realm) {
- ret = hdb_enctype2key(context, &krbtgt->entry,
- krbtgt_etype, &tkey);
- if(ret) {
- kdc_log(context, config, 0,
- "Failed to find key for krbtgt PAC check");
- goto out;
- }
- tgtkey = &tkey->key;
+ ret = hdb_enctype2key(context, &krbtgt->entry,
+ krbtgt_etype, &tkey);
+ if(ret) {
+ kdc_log(context, config, 0,
+ "Failed to find key for krbtgt PAC check");
+ goto out;
}
ret = check_PAC(context, config, client_principal,
- client, server, ekey, tgtkey,
+ client, server, ekey, &tkey->key,
tgt, &rspac, &require_signedpath);
if (ret) {
kdc_log(context, config, 0,
diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c
index ebf2873599..072df44042 100644
--- a/source4/heimdal/kdc/misc.c
+++ b/source4/heimdal/kdc/misc.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: misc.c 17951 2006-08-28 14:41:49Z lha $");
+RCSID("$Id: misc.c 21106 2007-06-18 10:18:11Z lha $");
struct timeval _kdc_now;
@@ -46,12 +46,14 @@ _kdc_db_fetch(krb5_context context,
hdb_entry_ex **h)
{
hdb_entry_ex *ent;
- krb5_error_code ret = HDB_ERR_NOENTRY;
+ krb5_error_code ret;
int i;
ent = calloc (1, sizeof (*ent));
- if (ent == NULL)
+ if (ent == NULL) {
+ krb5_set_error_string(context, "out of memory");
return ENOMEM;
+ }
for(i = 0; i < config->num_db; i++) {
ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0);
@@ -74,7 +76,8 @@ _kdc_db_fetch(krb5_context context,
}
}
free(ent);
- return ret;
+ krb5_set_error_string(context, "no such entry found in hdb");
+ return HDB_ERR_NOENTRY;
}
void
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index bf62f879db..ead961022d 100755
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: pkinit.c 21039 2007-06-10 06:20:31Z lha $");
+RCSID("$Id: pkinit.c 21290 2007-06-25 14:13:23Z lha $");
#ifdef PKINIT
@@ -380,6 +380,7 @@ _kdc_pk_rd_padata(krb5_context context,
*ret_params = NULL;
if (!config->enable_pkinit) {
+ kdc_log(context, config, 0, "PK-INIT request but PK-INIT not enabled");
krb5_clear_error_string(context);
return 0;
}
@@ -676,6 +677,7 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
static krb5_error_code
pk_mk_pa_reply_enckey(krb5_context context,
+ krb5_kdc_configuration *config,
pk_client_params *client_params,
const KDC_REQ *req,
const krb5_data *req_buffer,
@@ -700,8 +702,11 @@ pk_mk_pa_reply_enckey(krb5_context context,
switch (client_params->type) {
case PKINIT_COMPAT_WIN2K: {
int i = 0;
- if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL)
+ if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL
+ && config->pkinit_require_binding == 0)
+ {
do_win2k = 1;
+ }
break;
}
case PKINIT_COMPAT_27:
@@ -1015,6 +1020,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
goto out;
}
ret = pk_mk_pa_reply_enckey(context,
+ config,
client_params,
req,
req_buffer,
@@ -1110,6 +1116,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
goto out;
}
ret = pk_mk_pa_reply_enckey(context,
+ config,
client_params,
req,
req_buffer,
@@ -1384,7 +1391,7 @@ _kdc_pk_check_client(krb5_context context,
"Trying to authorize PK-INIT subject DN %s",
*subject_name);
- if (config->enable_pkinit_princ_in_cert) {
+ if (config->pkinit_princ_in_cert) {
ret = match_rfc_san(context, config,
client_params->cert,
client->entry.principal);
@@ -1508,7 +1515,8 @@ _kdc_add_inital_verified_cas(krb5_context context,
krb5_abortx(context, "internal asn.1 encoder error");
ret = _kdc_tkt_add_if_relevant_ad(context, tkt,
- ad_initial_verified_cas, &data);
+ KRB5_AUTHDATA_INITIAL_VERIFIED_CAS,
+ &data);
krb5_data_free(&data);
return ret;
}