From a550317253966c6feded683a859f8c50f298be74 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Wed, 12 Mar 2008 23:11:48 -0500 Subject: heimdal: Add parameter to windc_plugin to allow extended return codes. These changes add a krb5_data parameter named e_data to the windc_plugin to allow the samba KDC to return extended error information in addition to the standard KRB5KDC_ERR_* codes. Windows uses the extended information to provide detailed information in user dialogs (e.g. account disabled, logon hours restriction, must change password, etc.). This particular commit modifies only heimdal code. Hopefully this can be submitted and accepted into the upstream heimdal codebase. (This used to be commit f542362be25e7182a0836de7a0163f6b9fce9408) --- source4/heimdal/kdc/kdc-private.h | 3 ++- source4/heimdal/kdc/kerberos5.c | 2 +- source4/heimdal/kdc/windc.c | 5 +++-- source4/heimdal/kdc/windc_plugin.h | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/heimdal/kdc') diff --git a/source4/heimdal/kdc/kdc-private.h b/source4/heimdal/kdc/kdc-private.h index 030be9ae58..4052e9b509 100644 --- a/source4/heimdal/kdc/kdc-private.h +++ b/source4/heimdal/kdc/kdc-private.h @@ -281,6 +281,7 @@ krb5_error_code _kdc_windc_client_access ( krb5_context /*context*/, struct hdb_entry_ex */*client*/, - KDC_REQ */*req*/); + KDC_REQ */*req*/, + krb5_data */*e_data*/); #endif /* __kdc_private_h__ */ diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index 40a9c9c972..23ca5a035e 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1043,7 +1043,7 @@ _kdc_as_rep(krb5_context context, goto out; } - ret = _kdc_windc_client_access(context, client, req); + ret = _kdc_windc_client_access(context, client, req, &e_data); if(ret) goto out; diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c index 395ab73432..85e4d7f725 100644 --- a/source4/heimdal/kdc/windc.c +++ b/source4/heimdal/kdc/windc.c @@ -101,9 +101,10 @@ _kdc_pac_verify(krb5_context context, krb5_error_code _kdc_windc_client_access(krb5_context context, struct hdb_entry_ex *client, - KDC_REQ *req) + KDC_REQ *req, + krb5_data *e_data) { if (windcft == NULL) return 0; - return (windcft->client_access)(windcctx, context, client, req); + return (windcft->client_access)(windcctx, context, client, req, e_data); } diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h index ec480cf950..3ae0c94681 100644 --- a/source4/heimdal/kdc/windc_plugin.h +++ b/source4/heimdal/kdc/windc_plugin.h @@ -64,7 +64,7 @@ typedef krb5_error_code typedef krb5_error_code (*krb5plugin_windc_client_access)( - void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *); + void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *, krb5_data *); #define KRB5_WINDC_PLUGING_MINOR 2 -- cgit From 9e6b0c28712ee77ce878809c8576826a3ba08d95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Mar 2008 10:17:42 +1100 Subject: Merge lorikeet-heimdal -r 787 into Samba4 tree. Andrew Bartlett (This used to be commit d88b530522d3cef67c24422bd5182fb875d87ee2) --- source4/heimdal/kdc/digest.c | 26 ++++++++++++++++++++++++-- source4/heimdal/kdc/kaserver.c | 2 +- source4/heimdal/kdc/kdc_locl.h | 5 ++--- source4/heimdal/kdc/kerberos5.c | 41 ++++++++++++++++++++++++++--------------- source4/heimdal/kdc/krb5tgs.c | 24 ++++++++++++++++-------- source4/heimdal/kdc/log.c | 10 +++++++--- source4/heimdal/kdc/pkinit.c | 34 +++++++++++++++++++++++----------- 7 files changed, 99 insertions(+), 43 deletions(-) (limited to 'source4/heimdal/kdc') diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c index 358ca5ad56..b845b0f9a8 100644 --- a/source4/heimdal/kdc/digest.c +++ b/source4/heimdal/kdc/digest.c @@ -34,7 +34,7 @@ #include "kdc_locl.h" #include -RCSID("$Id: digest.c 21606 2007-07-17 07:03:25Z lha $"); +RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $"); #define MS_CHAP_V2 0x20 #define CHAP_MD5 0x10 @@ -1003,7 +1003,8 @@ _kdc_do_digest(krb5_context context, } r.u.ntlmInitReply.flags |= - NTLM_NEG_TARGET_DOMAIN | + NTLM_NEG_TARGET | + NTLM_TARGET_DOMAIN | NTLM_ENC_128; #define ALL \ @@ -1331,6 +1332,27 @@ _kdc_do_digest(krb5_context context, version, ireq.u.ntlmRequest.username); break; } + case choice_DigestReqInner_supportedMechs: + + kdc_log(context, config, 0, "digest supportedMechs from %s", from); + + r.element = choice_DigestRepInner_supportedMechs; + memset(&r.u.supportedMechs, 0, sizeof(r.u.supportedMechs)); + + if (config->digests_allowed & NTLM_V1) + r.u.supportedMechs.ntlm_v1 = 1; + if (config->digests_allowed & NTLM_V1_SESSION) + r.u.supportedMechs.ntlm_v1_session = 1; + if (config->digests_allowed & NTLM_V2) + r.u.supportedMechs.ntlm_v2 = 1; + if (config->digests_allowed & DIGEST_MD5) + r.u.supportedMechs.digest_md5 = 1; + if (config->digests_allowed & CHAP_MD5) + r.u.supportedMechs.chap_md5 = 1; + if (config->digests_allowed & MS_CHAP_V2) + r.u.supportedMechs.ms_chap_v2 = 1; + break; + default: { char *s; krb5_set_error_string(context, "unknown operation to digest"); diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c index 15624e8e76..27f497ea66 100644 --- a/source4/heimdal/kdc/kaserver.c +++ b/source4/heimdal/kdc/kaserver.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kaserver.c 21661 2007-07-22 01:57:17Z lha $"); +RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $"); #include #include diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h index fdbdf271de..fe0523665a 100644 --- a/source4/heimdal/kdc/kdc_locl.h +++ b/source4/heimdal/kdc/kdc_locl.h @@ -32,7 +32,7 @@ */ /* - * $Id: kdc_locl.h 20954 2007-06-07 03:30:15Z lha $ + * $Id: kdc_locl.h 22247 2007-12-08 23:49:41Z lha $ */ #ifndef __KDC_LOCL_H__ @@ -58,8 +58,7 @@ extern int detach_from_console; extern const struct units _kdc_digestunits[]; -#define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf" -#define DEFAULT_LOG_DEST "0-1/FILE:" HDB_DB_DIR "/kdc.log" +#define KDC_LOG_FILE "kdc.log" extern struct timeval _kdc_now; #define kdc_time (_kdc_now.tv_sec) diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index 40a9c9c972..bc600a5319 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: kerberos5.c 21529 2007-07-13 12:37:14Z lha $"); +RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $"); #define MAX_TIME ((time_t)((1U << 31) - 1)) @@ -362,6 +362,13 @@ older_enctype(krb5_enctype enctype) case ETYPE_DES3_CBC_SHA1: case ETYPE_ARCFOUR_HMAC_MD5: case ETYPE_ARCFOUR_HMAC_MD5_56: + /* + * The following three is "old" windows enctypes and is needed for + * windows 2000 hosts. + */ + case ETYPE_ARCFOUR_MD4: + case ETYPE_ARCFOUR_HMAC_OLD: + case ETYPE_ARCFOUR_HMAC_OLD_EXP: return 1; default: return 0; @@ -411,8 +418,8 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key) *ent->salttype = key->salt->type; #else /* - * We shouldn't sent salttype since its incompatible with the - * specification and its break windows clients. The afs + * We shouldn't sent salttype since it is incompatible with the + * specification and it breaks windows clients. The afs * salting problem is solved by using KRB5-PADATA-AFS3-SALT * implemented in Heimdal 0.7 and later. */ @@ -472,11 +479,13 @@ get_pa_etype_info(krb5_context context, free_ETYPE_INFO(&pa); return ret; } + break; } } skip1:; } for(i = 0; i < client->keys.len; i++) { + /* already added? */ for(j = 0; j < etypes_len; j++) { if(client->keys.val[i].key.keytype == etypes[j]) goto skip2; @@ -497,7 +506,7 @@ get_pa_etype_info(krb5_context context, } if(n < pa.len) { - /* stripped out newer enctypes */ + /* stripped out dups, newer enctypes, and not valid enctypes */ pa.len = n; } @@ -621,23 +630,29 @@ get_pa_etype_info2(krb5_context context, if(client->keys.val[i].key.keytype == etypes[j]) { if (krb5_enctype_valid(context, etypes[j]) != 0) continue; + if (n >= pa.len) + krb5_abortx(context, "internal error: n >= p.len"); if((ret = make_etype_info2_entry(&pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO2(&pa); return ret; } + break; } } skip1:; } - /* send enctypes that the cliene doesn't know about too */ + /* send enctypes that the client doesn't know about too */ for(i = 0; i < client->keys.len; i++) { + /* already added? */ for(j = 0; j < etypes_len; j++) { if(client->keys.val[i].key.keytype == etypes[j]) goto skip2; } if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0) continue; + if (n >= pa.len) + krb5_abortx(context, "internal error: n >= p.len"); if((ret = make_etype_info2_entry(&pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO2(&pa); @@ -646,16 +661,8 @@ get_pa_etype_info2(krb5_context context, skip2:; } - if(n != pa.len) { - char *name; - ret = krb5_unparse_name(context, client->principal, &name); - if (ret) - name = rk_UNCONST(""); - kdc_log(context, config, 0, - "internal error in get_pa_etype_info2(%s): %d != %d", - name, n, pa.len); - if (ret == 0) - free(name); + if(n < pa.len) { + /* stripped out dups, and not valid enctypes */ pa.len = n; } @@ -1554,6 +1561,10 @@ _kdc_as_rep(krb5_context context, * otherwise just a dummy lr. */ ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val)); + if (ek.last_req.val == NULL) { + ret = ENOMEM; + goto out; + } ek.last_req.len = 0; if (client->entry.pw_end && (config->kdc_warn_pwexpire == 0 diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 4d6be60f68..32bdee9799 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 21262 2007-06-21 15:18:37Z lha $"); +RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $"); /* * return the realm of a krbtgt-ticket or NULL @@ -822,7 +822,7 @@ tgs_make_reply(krb5_context context, if(rspac->length) { /* * No not need to filter out the any PAC from the - * auth_data since its signed by the KDC. + * auth_data since it's signed by the KDC. */ ret = _kdc_tkt_add_if_relevant_ad(context, &et, KRB5_AUTHDATA_WIN2K_PAC, @@ -1099,11 +1099,14 @@ tgs_parse_request(krb5_context context, ret = hdb_enctype2key(context, &(*krbtgt)->entry, ap_req.ticket.enc_part.etype, &tkey); if(ret){ - char *str, *p; + char *str = NULL, *p = NULL; + krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str); krb5_unparse_name(context, princ, &p); - kdc_log(context, config, 0, - "No server key with enctype %s found for %s", str, p); + kdc_log(context, config, 0, + "No server key with enctype %s found for %s", + str ? str : "", + p ? p : ""); free(str); free(p); ret = KRB5KRB_AP_ERR_BADKEYVER; @@ -1163,8 +1166,10 @@ tgs_parse_request(krb5_context context, } if (b->enc_authorization_data) { + unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY; krb5_keyblock *subkey; krb5_data ad; + ret = krb5_auth_con_getremotesubkey(context, ac, &subkey); @@ -1175,6 +1180,7 @@ tgs_parse_request(krb5_context context, goto out; } if(subkey == NULL){ + usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION; ret = krb5_auth_con_getkey(context, ac, &subkey); if(ret) { krb5_auth_con_free(context, ac); @@ -1199,7 +1205,7 @@ tgs_parse_request(krb5_context context, } ret = krb5_decrypt_EncryptedData (context, crypto, - KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, + usage, b->enc_authorization_data, &ad); krb5_crypto_destroy(context, crypto); @@ -1373,6 +1379,7 @@ server_lookup: ret = krb5_unparse_name(context, sp, &spn); if (ret) goto out; + auth_data = NULL; /* ms don't handle AD in referals */ goto server_lookup; } } @@ -1390,6 +1397,7 @@ server_lookup: if (ret) goto out; krb5_free_host_realm(context, realms); + auth_data = NULL; /* ms don't handle AD in referals */ goto server_lookup; } krb5_free_host_realm(context, realms); @@ -1431,8 +1439,8 @@ server_lookup: } /* - * Check that service is in the same realm as the krbtgt. If its - * not the same, its someone that is using a uni-directional trust + * Check that service is in the same realm as the krbtgt. If it's + * not the same, it's someone that is using a uni-directional trust * backward. */ diff --git a/source4/heimdal/kdc/log.c b/source4/heimdal/kdc/log.c index 977b1c9476..8cf967fbfb 100644 --- a/source4/heimdal/kdc/log.c +++ b/source4/heimdal/kdc/log.c @@ -32,7 +32,7 @@ */ #include "kdc_locl.h" -RCSID("$Id: log.c 15532 2005-06-30 01:54:49Z lha $"); +RCSID("$Id: log.c 22254 2007-12-09 06:01:05Z lha $"); void kdc_openlog(krb5_context context, @@ -47,8 +47,12 @@ kdc_openlog(krb5_context context, for(p = s; *p; p++) krb5_addlog_dest(context, config->logf, *p); krb5_config_free_strings(s); - }else - krb5_addlog_dest(context, config->logf, DEFAULT_LOG_DEST); + }else { + char *s; + asprintf(&s, "0-1/FILE:%s/%s", hdb_db_dir(context), KDC_LOG_FILE); + krb5_addlog_dest(context, config->logf, s); + free(s); + } krb5_set_warn_dest(context, config->logf); } diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index ead961022d..bf248af588 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 21290 2007-06-25 14:13:23Z lha $"); +RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $"); #ifdef PKINIT @@ -1248,6 +1248,7 @@ out: static int match_rfc_san(krb5_context context, krb5_kdc_configuration *config, + hx509_context hx509ctx, hx509_cert client_cert, krb5_const_principal match) { @@ -1256,7 +1257,8 @@ match_rfc_san(krb5_context context, memset(&list, 0 , sizeof(list)); - ret = hx509_cert_find_subjectAltName_otherName(client_cert, + ret = hx509_cert_find_subjectAltName_otherName(hx509ctx, + client_cert, oid_id_pkinit_san(), &list); if (ret) @@ -1304,6 +1306,7 @@ out: static int match_ms_upn_san(krb5_context context, krb5_kdc_configuration *config, + hx509_context hx509ctx, hx509_cert client_cert, krb5_const_principal match) { @@ -1315,7 +1318,8 @@ match_ms_upn_san(krb5_context context, memset(&list, 0 , sizeof(list)); - ret = hx509_cert_find_subjectAltName_otherName(client_cert, + ret = hx509_cert_find_subjectAltName_otherName(hx509ctx, + client_cert, oid_id_pkinit_ms_san(), &list); if (ret) @@ -1376,7 +1380,7 @@ _kdc_pk_check_client(krb5_context context, hx509_name name; int i; - ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx, + ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx, client_params->cert, &name); if (ret) @@ -1393,6 +1397,7 @@ _kdc_pk_check_client(krb5_context context, if (config->pkinit_princ_in_cert) { ret = match_rfc_san(context, config, + kdc_identity->hx509ctx, client_params->cert, client->entry.principal); if (ret == 0) { @@ -1401,6 +1406,7 @@ _kdc_pk_check_client(krb5_context context, return 0; } ret = match_ms_upn_san(context, config, + kdc_identity->hx509ctx, client_params->cert, client->entry.principal); if (ret == 0) { @@ -1580,7 +1586,8 @@ _kdc_pk_initialize(krb5_context context, char **pool, char **revoke_list) { - const char *file; + const char *file; + char *fn = NULL; krb5_error_code ret; file = krb5_config_get_string(context, NULL, @@ -1646,14 +1653,19 @@ _kdc_pk_initialize(krb5_context context, NULL); _krb5_pk_allow_proxy_certificate(kdc_identity, ret); - file = krb5_config_get_string_default(context, - NULL, - HDB_DB_DIR "/pki-mapping", - "kdc", - "pkinit_mappings_file", - NULL); + file = krb5_config_get_string(context, + NULL, + "kdc", + "pkinit_mappings_file", + NULL); + if (file == NULL) { + asprintf(&fn, "%s/pki-mapping", hdb_db_dir(context)); + file = fn; + } load_mappings(context, file); + if (fn) + free(fn); return 0; } -- cgit