summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-04-10 20:31:20 +0000
committerStefan Metzmacher <metze@samba.org>2015-07-08 18:38:20 +0200
commitf05c0bc6397d783681fb0b4a82677493e96f3398 (patch)
tree5becc4a88aa66281651dccc7726a54698ecd9ece /source4
parentcbe9fed248a85e3ab57df63656204941925f8131 (diff)
downloadsamba-f05c0bc6397d783681fb0b4a82677493e96f3398.tar.gz
s4:kdc/db-glue: allow invalid kvno numbers in samba_kdc_trust_message2entry()
We should fallback to the current password if the trusted KDC used a wrong kvno. After commit 6f8b868a29fe47a3b589616fde97099829933ce0, we always have the previous password filled. With the trust creation we typically don't have a TRUST_AUTH_TYPE_VERSION in the current nor in the previous array. This means current_kvno is 0. And now previous_kvno is 255. A FreeIPA/MIT KDC uses kvno=1 in the referral ticket, which triggered the 'Request for unknown kvno 1 - current kvno is 0' case. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/kdc/db-glue.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index 92727175209..20c73c8b11b 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -1022,13 +1022,15 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
const struct ldb_val *password_val;
struct trustAuthInOutBlob password_blob;
struct samba_kdc_entry *p;
- bool use_previous;
+ bool use_previous = false;
uint32_t current_kvno;
+ uint32_t previous_kvno;
uint32_t num_keys = 0;
enum ndr_err_code ndr_err;
int ret, trust_direction_flags;
unsigned int i;
struct AuthenticationInformationArray *auth_array;
+ uint32_t *auth_kvno;
uint32_t supported_enctypes = ENC_RC4_HMAC_MD5;
if (dsdb_functional_level(kdc_db_ctx->samdb) >= DS_DOMAIN_FUNCTION_2008) {
@@ -1125,8 +1127,24 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
/* first work out the current kvno */
current_kvno = 0;
for (i=0; i < password_blob.count; i++) {
- if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_VERSION) {
- current_kvno = password_blob.current.array[i].AuthInfo.version.version;
+ struct AuthenticationInformation *a =
+ &password_blob.current.array[i];
+
+ if (a->AuthType == TRUST_AUTH_TYPE_VERSION) {
+ current_kvno = a->AuthInfo.version.version;
+ }
+ }
+ if (current_kvno == 0) {
+ previous_kvno = 255;
+ } else {
+ previous_kvno = current_kvno - 1;
+ }
+ for (i=0; i < password_blob.count; i++) {
+ struct AuthenticationInformation *a =
+ &password_blob.previous.array[i];
+
+ if (a->AuthType == TRUST_AUTH_TYPE_VERSION) {
+ previous_kvno = a->AuthInfo.version.version;
}
}
@@ -1135,31 +1153,41 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
if (password_blob.previous.count == 0) {
/* there is no previous password */
use_previous = false;
- } else if (!(flags & HDB_F_KVNO_SPECIFIED) ||
- kvno == current_kvno) {
+ } else if (!(flags & HDB_F_KVNO_SPECIFIED)) {
+ /*
+ * If not specified we use the current one.
+ */
+ use_previous = false;
+ } else if (kvno == current_kvno) {
+ /*
+ * Exact match ...
+ */
use_previous = false;
- } else if ((kvno+1 == current_kvno) ||
- (kvno == 255 && current_kvno == 0)) {
+ } else if (kvno == previous_kvno) {
+ /*
+ * Exact match ...
+ */
use_previous = true;
} else {
- DEBUG(1,(__location__ ": Request for unknown kvno %u - current kvno is %u\n",
- kvno, current_kvno));
- krb5_clear_error_message(context);
- ret = HDB_ERR_NOENTRY;
- goto out;
+ /*
+ * Fallback to the current one for anything else
+ */
+ use_previous = false;
}
if (use_previous) {
auth_array = &password_blob.previous;
+ auth_kvno = &previous_kvno;
} else {
auth_array = &password_blob.current;
+ auth_kvno = &current_kvno;
}
/* use the kvno the client specified, if available */
if (flags & HDB_F_KVNO_SPECIFIED) {
entry_ex->entry.kvno = kvno;
} else {
- entry_ex->entry.kvno = current_kvno;
+ entry_ex->entry.kvno = *auth_kvno;
}
for (i=0; i < auth_array->count; i++) {