From 88cc567f5303d168f77aba94fffdc8668fa8363a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Aug 2019 14:51:14 +0000 Subject: [PATCH 01/25] s4:auth: require a PAC for kerberos authentication As AD-DC there's really no reason why we want to accept a kerberos ticket without a PAC. We don't support MIT trusts. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source4/auth/ntlm/auth.c | 47 +++------------------------------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index ead5326705e6..759b5d624d33 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -86,48 +86,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t cha return NT_STATUS_OK; } -/**************************************************************************** -Used in the gensec_gssapi and gensec_krb5 server-side code, where the -PAC isn't available, and for tokenGroups in the DSDB stack. - - Supply either a principal or a DN -****************************************************************************/ -static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx, - TALLOC_CTX *mem_ctx, - const char *principal, - struct ldb_dn *user_dn, - uint32_t session_info_flags, - struct auth_session_info **session_info) -{ - NTSTATUS nt_status; - struct auth_method_context *method; - struct auth_user_info_dc *user_info_dc; - - for (method = auth_ctx->methods; method; method = method->next) { - if (!method->ops->get_user_info_dc_principal) { - continue; - } - - nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { - continue; - } - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, - user_info_dc, - user_info_dc->info->account_name, - session_info_flags, session_info); - talloc_free(user_info_dc); - - return nt_status; - } - - return NT_STATUS_NOT_IMPLEMENTED; -} - /** * Check a user's Plaintext, LM or NTLM password. * (sync version) @@ -657,8 +615,9 @@ static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx, TALLOC_CTX *tmp_ctx; if (!pac_blob) { - return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name, - NULL, session_info_flags, session_info); + DBG_WARNING("No PAC available for principal_name[%s]\n", + principal_name); + return NT_STATUS_NO_IMPERSONATION_TOKEN; } tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); -- 2.17.1 From 40021bd07d28db9a6cb0c19351acf357fe121301 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Aug 2019 14:52:12 +0000 Subject: [PATCH 02/25] s4:auth: remove unused get_user_info_dc_principal() backend hook BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source4/auth/auth.h | 6 ------ source4/auth/ntlm/auth_sam.c | 12 ------------ 2 files changed, 18 deletions(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 51895c9259f3..2977b752426e 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -74,12 +74,6 @@ struct auth_operations { struct auth_user_info_dc **interim_info, bool *authoritative); - /* Lookup a 'session info interim' return based only on the principal or DN */ - NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth4_context *auth_context, - const char *principal, - struct ldb_dn *user_dn, - struct auth_user_info_dc **interim_info); uint32_t flags; }; diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index fb88cb87f668..a8c7d8b4b857 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -854,28 +854,16 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, return NT_STATUS_OK; } -/* Wrapper for the auth subsystem pointer */ -static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, - struct auth4_context *auth_context, - const char *principal, - struct ldb_dn *user_dn, - struct auth_user_info_dc **user_info_dc) -{ - return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx, - principal, user_dn, user_info_dc); -} static const struct auth_operations sam_ignoredomain_ops = { .name = "sam_ignoredomain", .want_check = authsam_ignoredomain_want_check, .check_password = authsam_check_password_internals, - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; static const struct auth_operations sam_ops = { .name = "sam", .want_check = authsam_want_check, .check_password = authsam_check_password_internals, - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *); -- 2.17.1 From 24e6372ee2eaad36dd67bae89daedee26bf55c65 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Aug 2019 14:52:54 +0000 Subject: [PATCH 03/25] s4:auth: remove unused prototype of auth_generate_session_info_wrapper() BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source4/auth/ntlm/auth.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 759b5d624d33..122a40e4edef 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -37,13 +37,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context, - TALLOC_CTX *mem_ctx, - void *server_returned_info, - const char *original_user_name, - uint32_t session_info_flags, - struct auth_session_info **session_info); - /*************************************************************************** Set a fixed challenge ***************************************************************************/ -- 2.17.1 From 83055b426abed1ef1d6f32bad6138637b2c36189 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Sep 2019 16:13:01 +0200 Subject: [PATCH 04/25] docs-xml: add "kerberos acceptor require pac" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- .../security/kerberosacceptorrequirepac.xml | 27 +++++++++++++++++++ lib/param/loadparm.c | 1 + source3/param/loadparm.c | 1 + 3 files changed, 29 insertions(+) create mode 100644 docs-xml/smbdotconf/security/kerberosacceptorrequirepac.xml diff --git a/docs-xml/smbdotconf/security/kerberosacceptorrequirepac.xml b/docs-xml/smbdotconf/security/kerberosacceptorrequirepac.xml new file mode 100644 index 000000000000..6b221f5fdcfd --- /dev/null +++ b/docs-xml/smbdotconf/security/kerberosacceptorrequirepac.xml @@ -0,0 +1,27 @@ + + + The typicall use case for kerberos is being part of + an active directory domain. Which means we'll always + get an PAC (Privilege Attribute Certificate Data Structure) + as part of the service ticket we accept. + + + If the server is configured as domain member it + will require a valid PAC to be present by default. + + + For all configurations except on an active directory + domain controller it is possible to deactivate this requirement + and fallback to rely on a local unix user to be present. + + +auto +no +yes + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 9a577aa188c5..36c3db967620 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3021,6 +3021,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes"); lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all"); + lpcfg_do_global_parameter(lp_ctx, "kerberos acceptor require pac", "auto"); lpcfg_do_global_parameter(lp_ctx, "rpc server dynamic port range", diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index b1a52055ade7..6cd09236bbb2 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -677,6 +677,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */ Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */ Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */ + Globals._require_pac = Auto; Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */ Globals.lm_interval = 60; #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) -- 2.17.1 From 6654b95b13b2516c686fb72302dd81bf5a2fa3b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:52:42 +0000 Subject: [PATCH 05/25] s3:param: add lp_require_pac() This handles the autodetection for the "kerberos acceptor require pac" option. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source3/include/proto.h | 1 + source3/param/loadparm.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 0d02f38fc8be..7e10f50fca8d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -745,6 +745,7 @@ bool lp_idmap_default_range(uint32_t *low, uint32_t *high); const char *lp_idmap_backend(const char *domain_name); const char *lp_idmap_default_backend (void); int lp_security(void); +bool lp_require_pac(void); int lp_client_max_protocol(void); int lp_client_ipc_min_protocol(void); int lp_client_ipc_max_protocol(void); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6cd09236bbb2..1109eca384a6 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4593,6 +4593,34 @@ int lp_security(void) lp__security()); } +bool lp_require_pac(void) +{ + enum server_role role = lp_server_role(); + int val = lp__require_pac(); + + if (role == ROLE_ACTIVE_DIRECTORY_DC) { + return true; + } + + if (val != Auto) { + return val != 0; + } + + switch (role) { + case ROLE_DOMAIN_MEMBER: + /* + * if we're part of a domain we + * want to rely on a valid PAC + * in kerberos tickets + */ + return true; + default: + break; + } + + return false; +} + int lp_client_max_protocol(void) { int client_max_protocol = lp__client_max_protocol(); -- 2.17.1 From dd52a931c49093d5eb6456f52bb2ed439b642619 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Aug 2019 15:36:32 +0000 Subject: [PATCH 06/25] s3:auth: require PAC on ad domain members/servers As part of an active directory domain we'll get a service ticket including a PAC. We should enforce that and don't do any strange fallbacks by default. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source3/auth/auth_generic.c | 21 +++++++++++++++++++++ source3/auth/user_krb5.c | 15 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 167d4e00367f..88c6248e8b9d 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -58,6 +58,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, struct passwd *pw; NTSTATUS status; int rc; + bool require_pac = lp_require_pac(); tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { @@ -100,6 +101,15 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, switch (wbc_err) { case WBC_ERR_WINBIND_NOT_AVAILABLE: + if (require_pac) { + status = NT_STATUS_NO_LOGON_SERVERS; + DBG_ERR("winbindd not running - " + "but required as domain member: " + "princ_name[%s] %s\n", + princ_name, nt_errstr(status)); + goto done; + } + //FALL_THROUGH; case WBC_ERR_SUCCESS: break; case WBC_ERR_AUTH_ERROR: @@ -119,6 +129,11 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, if (!NT_STATUS_IS_OK(status)) { goto done; } + } else if (require_pac) { + status = NT_STATUS_NO_IMPERSONATION_TOKEN; + DBG_WARNING("No PAC available for princ_name[%s] %s\n", + princ_name, nt_errstr(status)); + goto done; } rc = get_remote_hostname(remote_address, @@ -157,6 +172,12 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, if (!NT_STATUS_IS_OK(status)) { goto done; } + } else if (require_pac) { + status = NT_STATUS_NO_IMPERSONATION_TOKEN; + DBG_WARNING("No PAC LOGON_INFO available for " + "princ_name[%s] %s\n", + princ_name, nt_errstr(status)); + goto done; } /* setup the string used by %U */ diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c index 8998f9c8f8ae..ca3d3714e624 100644 --- a/source3/auth/user_krb5.c +++ b/source3/auth/user_krb5.c @@ -193,8 +193,17 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, { NTSTATUS status; struct auth_serversupplied_info *server_info; + bool require_pac = lp_require_pac(); if (mapped_to_guest) { + if (require_pac) { + status = NT_STATUS_BAD_TOKEN_TYPE; + DBG_WARNING("Mapped to guest for PAC required " + "[%s\\%s] %s\n", + ntdomain, ntuser, nt_errstr(status)); + return status; + } + status = make_server_info_guest(mem_ctx, &server_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("make_server_info_guest failed: %s!\n", @@ -216,6 +225,12 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, return status; } + } else if (require_pac) { + status = NT_STATUS_NO_IMPERSONATION_TOKEN; + DBG_WARNING("No INFO3 available for " + "[%s\\%s] %s\n", + ntdomain, ntuser, nt_errstr(status)); + return status; } else { /* * We didn't get a PAC, we have to make up the user -- 2.17.1 From 3a4953ee1e7be48edb59882b3b95a5f079ada6a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2019 06:58:16 +0200 Subject: [PATCH 07/25] auth3_generate_session_info_pac WBC_ERR_WINBIND_NOT_AVAILABLE: --- source3/auth/auth_generic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 88c6248e8b9d..6fddad54cdcb 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -101,14 +101,14 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, switch (wbc_err) { case WBC_ERR_WINBIND_NOT_AVAILABLE: - if (require_pac) { - status = NT_STATUS_NO_LOGON_SERVERS; - DBG_ERR("winbindd not running - " - "but required as domain member: " - "princ_name[%s] %s\n", - princ_name, nt_errstr(status)); - goto done; - } + //if (require_pac) { + // status = NT_STATUS_NO_LOGON_SERVERS; + // DBG_ERR("winbindd not running - " + // "but required as domain member: " + // "princ_name[%s] %s\n", + // princ_name, nt_errstr(status)); + // goto done; + //} //FALL_THROUGH; case WBC_ERR_SUCCESS: break; -- 2.17.1 From b0dd91b1180a65b48765c7b70371628bc9731570 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 08/25] UPSTREAM-FIRST!!! HEIMDAL:lib/krb5: add krb5_rd_req_in_set_verify_ap_req_flags() In the next commits we want to be able to pass down things like KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source4/heimdal/lib/krb5/rd_req.c | 18 ++++++++++++++++-- source4/heimdal/lib/krb5/version-script.map | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 21daeb596b55..76d5caadb318 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -519,6 +519,7 @@ struct krb5_rd_req_in_ctx_data { krb5_keytab keytab; krb5_keyblock *keyblock; krb5_boolean check_pac; + krb5_flags verify_ap_req_flags; }; struct krb5_rd_req_out_ctx_data { @@ -577,6 +578,15 @@ krb5_rd_req_in_set_keytab(krb5_context context, return 0; } +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_rd_req_in_set_verify_ap_req_flags(krb5_context context, + krb5_rd_req_in_ctx in, + krb5_flags flags) +{ + in->verify_ap_req_flags = flags; + return 0; +} + /** * Set if krb5_rq_red() is going to check the Windows PAC or not * @@ -850,6 +860,7 @@ krb5_rd_req_ctx(krb5_context context, krb5_rd_req_out_ctx o = NULL; krb5_keytab id = NULL, keytab = NULL; krb5_principal service = NULL; + krb5_flags verify_ap_req_flags = 0; *outctx = NULL; @@ -890,6 +901,9 @@ krb5_rd_req_ctx(krb5_context context, if (inctx && inctx->keytab) id = inctx->keytab; + if (inctx) + verify_ap_req_flags = inctx->verify_ap_req_flags; + if((*auth_context)->keyblock){ ret = krb5_copy_keyblock(context, (*auth_context)->keyblock, @@ -947,7 +961,7 @@ krb5_rd_req_ctx(krb5_context context, &ap_req, server, o->keyblock, - 0, + verify_ap_req_flags, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); @@ -995,7 +1009,7 @@ krb5_rd_req_ctx(krb5_context context, &ap_req, server, &entry.keyblock, - 0, + verify_ap_req_flags, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map index ddae2a067645..7b49c15dfc0e 100644 --- a/source4/heimdal/lib/krb5/version-script.map +++ b/source4/heimdal/lib/krb5/version-script.map @@ -529,6 +529,7 @@ HEIMDAL_KRB5_2.0 { krb5_rd_req_in_set_keyblock; krb5_rd_req_in_set_keytab; krb5_rd_req_in_set_pac_check; + krb5_rd_req_in_set_verify_ap_req_flags; krb5_rd_req_out_ctx_free; krb5_rd_req_out_get_ap_req_options; krb5_rd_req_out_get_keyblock; -- 2.17.1 From 853f3737800f5a84c1a617075522fbd61759c6d5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 09/25] UPSTREAM-FIRST!!! HEIMDAL:lib/krb5: add KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK In active directory a domain member replies on (trusts) the [K]DCs of the domain. It's the job of the [K]DCs to only generate useful tickets as they know about the trust topology. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source4/heimdal/lib/krb5/krb5.h | 1 + source4/heimdal/lib/krb5/rd_req.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 9c0f5669466c..03119fa78321 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -422,6 +422,7 @@ typedef union { /* flags for krb5_verify_ap_req */ #define KRB5_VERIFY_AP_REQ_IGNORE_INVALID (1 << 0) +#define KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK (1 << 1) #define KRB5_GC_CACHED (1U << 0) #define KRB5_GC_USER_USER (1U << 1) diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 76d5caadb318..1a1c31d8d8ba 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -253,7 +253,8 @@ krb5_decrypt_ticket(krb5_context context, return KRB5KRB_AP_ERR_TKT_EXPIRED; } - if(!t.flags.transited_policy_checked) { + if(!t.flags.transited_policy_checked + && !(flags & KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK)) { ret = check_transited(context, ticket, &t); if(ret) { free_EncTicketPart(&t); -- 2.17.1 From 75f03351e6f289a81d570c3c6989166073af218f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 10/25] UPSTREAM-FIRST!!! HEIMDAL:lib/gssapi/krb5: add GSS_KRB5_CRED_NO_TRANSIT_CHECK_X This allows KRB5_GC_NO_TRANSIT_CHECK (on the initiator) and KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK (on the acceptor) to be controlled via the gssapi layer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- .../heimdal/lib/gssapi/gssapi/gssapi_oid.h | 3 +++ .../lib/gssapi/krb5/accept_sec_context.c | 11 ++++++++- .../heimdal/lib/gssapi/krb5/gsskrb5_locl.h | 1 + .../lib/gssapi/krb5/init_sec_context.c | 16 ++++++++----- .../heimdal/lib/gssapi/krb5/set_cred_option.c | 24 +++++++++++++++++++ source4/heimdal/lib/gssapi/mech/gss_oid.c | 3 +++ source4/heimdal/lib/gssapi/version-script.map | 1 + 7 files changed, 52 insertions(+), 7 deletions(-) diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h index 3d00c060d10d..0eed639d53e1 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h @@ -96,6 +96,9 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_force_v1_oid_desc; extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc; #define GSS_KRB5_CRED_NO_CI_FLAGS_X (&__gss_krb5_cred_no_ci_flags_x_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_transit_check_x_oid_desc; +#define GSS_KRB5_CRED_NO_TRANSIT_CHECK_X (&__gss_krb5_cred_no_transit_check_x_oid_desc) + extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc; #define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc) diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index cfe27ace875e..2e4ed53ba08e 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -398,13 +398,22 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; krb5_principal server = NULL; + krb5_flags verify_ap_req_flags = 0; - if (acceptor_cred) + if (acceptor_cred) { server = acceptor_cred->principal; + if (acceptor_cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { + verify_ap_req_flags |= KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK; + } + } + kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) kret = krb5_rd_req_in_set_keytab(context, in, keytab); + if (kret == 0) + kret = krb5_rd_req_in_set_verify_ap_req_flags(context, in, + verify_ap_req_flags); if (kret) { if (in) krb5_rd_req_in_ctx_free(context, in); diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 6b9b03f34908..6a1e977452cf 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -94,6 +94,7 @@ typedef struct { int cred_flags; #define GSS_CF_DESTROY_CRED_ON_RELEASE 1 #define GSS_CF_NO_CI_FLAGS 2 +#define GSS_CF_NO_TRANSIT_CHECK 4 struct krb5_keytab_data *keytab; OM_uint32 lifetime; gss_cred_usage_t usage; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 0a89ae1f36cf..2f55f27000c2 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -205,6 +205,7 @@ gsskrb5_get_creds( OM_uint32 * minor_status, krb5_context context, krb5_ccache ccache, + krb5_flags options, gsskrb5_ctx ctx, const gss_name_t target_name, int use_dns, @@ -246,7 +247,7 @@ gsskrb5_get_creds( this_cred.session.keytype = KEYTYPE_NULL; kret = krb5_get_credentials(context, - 0, + options, ccache, &this_cred, &ctx->kcred); @@ -397,6 +398,7 @@ init_auth krb5_data fwd_data; OM_uint32 lifetime_rec; int allow_dns = 1; + krb5_flags options = 0; krb5_data_zero(&outbuf); krb5_data_zero(&fwd_data); @@ -414,8 +416,12 @@ init_auth goto failure; } ctx->more_flags |= CLOSE_CCACHE; - } else + } else { ctx->ccache = cred->ccache; + if (cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { + options |= KRB5_GC_NO_TRANSIT_CHECK; + } + } kret = krb5_cc_get_principal (context, ctx->ccache, &ctx->source); if (kret) { @@ -455,12 +461,10 @@ init_auth * DNS canonicalizion. */ ret = gsskrb5_get_creds(minor_status, context, ctx->ccache, - ctx, name, 0, time_req, - time_rec); + options, ctx, name, 0, time_req, time_rec); if (ret && allow_dns) ret = gsskrb5_get_creds(minor_status, context, ctx->ccache, - ctx, name, 1, time_req, - time_rec); + options, ctx, name, 1, time_req, time_rec); if (ret) goto failure; diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index bd3871675109..8d9f49884884 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -216,6 +216,26 @@ no_ci_flags(OM_uint32 *minor_status, } +static OM_uint32 +no_transit_check(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + cred->cred_flags |= GSS_CF_NO_TRANSIT_CHECK; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + OM_uint32 GSSAPI_CALLCONV _gsskrb5_set_cred_option (OM_uint32 *minor_status, @@ -243,6 +263,10 @@ _gsskrb5_set_cred_option } + if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_TRANSIT_CHECK_X)) { + return no_transit_check(minor_status, context, cred_handle, value); + } + *minor_status = EINVAL; return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid.c b/source4/heimdal/lib/gssapi/mech/gss_oid.c index 916d1e4dda5e..6f86eec65c39 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid.c @@ -94,6 +94,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_ci_flags_x_oid_desc = { 6, r /* GSS_KRB5_IMPORT_CRED_X - 1.2.752.43.13.30 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1e") }; +/* GSS_KRB5_CRED_NO_TRANSIT_CHECK_X - 1.2.752.43.13.31 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_transit_check_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") }; + /* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") }; diff --git a/source4/heimdal/lib/gssapi/version-script.map b/source4/heimdal/lib/gssapi/version-script.map index bcb79bf8f76e..776fe19dbf3c 100644 --- a/source4/heimdal/lib/gssapi/version-script.map +++ b/source4/heimdal/lib/gssapi/version-script.map @@ -154,6 +154,7 @@ HEIMDAL_GSS_2.0 { __gss_c_ntlm_session_key_oid_desc; __gss_c_ntlm_force_v1_oid_desc; __gss_krb5_cred_no_ci_flags_x_oid_desc; + __gss_krb5_cred_no_transit_check_x_oid_desc; __gss_krb5_import_cred_x_oid_desc; __gss_c_ma_sasl_mech_name_oid_desc; __gss_c_ma_mech_name_oid_desc; -- 2.17.1 From f2275c528ef5f4a5482356f55244cc84e5ad24b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Jul 2019 10:15:04 +0000 Subject: [PATCH 11/25] UPSTREAM-FIRST!!! HEIMDAL:lib/krb5: let krb5_rd_req_ctx() fallback only on KRB5KRB_AP_ERR_BAD_INTEGRITY This avoids hidding a real error like KRB5KRB_AP_ERR_ILL_CR_TKT. We only want to retry with the next key if the decryption failed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source4/heimdal/lib/krb5/rd_req.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 1a1c31d8d8ba..aef42d8b4ffc 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -1014,10 +1014,15 @@ krb5_rd_req_ctx(krb5_context context, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); - if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { + /* failed to decrypt, try the next key */ krb5_kt_free_entry (context, &entry); continue; } + if (ret) { + krb5_kt_free_entry (context, &entry); + goto out; + } /* * Found a match, save the keyblock for PAC processing, -- 2.17.1 From 2e8a62b2975fdd6fc6d3aee5ad9f0a0379d0efb2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Jul 2019 10:15:04 +0000 Subject: [PATCH 12/25] UPSTREAM-FIRST!!! HEIMDAL:lib/krb5: add krb5_rd_req_in_set_iterate_keytab() A caller might not know the kvno maintained by the KDC. And most often there's need to know it. So this function makes it possible to force the keytab iteration in order to get a consistent behavior. Otherwise it's possible to get a different behavior if the guessed kvno in the keytab accidentally matches the kvno of the ticket and we'll give up if the key is not able to decrypt the ticket. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source4/heimdal/lib/krb5/rd_req.c | 27 +++++++++++++++++++++ source4/heimdal/lib/krb5/version-script.map | 1 + 2 files changed, 28 insertions(+) diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index aef42d8b4ffc..4ea3cee959dc 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -518,6 +518,7 @@ krb5_verify_ap_req2(krb5_context context, struct krb5_rd_req_in_ctx_data { krb5_keytab keytab; + krb5_boolean iterate_keytab; krb5_keyblock *keyblock; krb5_boolean check_pac; krb5_flags verify_ap_req_flags; @@ -588,6 +589,27 @@ krb5_rd_req_in_set_verify_ap_req_flags(krb5_context context, return 0; } +/** + * Set if krb5_rq_red() is going to iterate the keytab to find a key + * + * @param context Keberos 5 context. + * @param in krb5_rd_req_in_ctx to check the option on. + * @param flag flag to select if the keytab should be iterated (TRUE) or not (FALSE). + * + * @return Kerberos 5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_auth + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_rd_req_in_set_iterate_keytab(krb5_context context, + krb5_rd_req_in_ctx in, + krb5_boolean flag) +{ + in->iterate_keytab = flag; + return 0; +} + /** * Set if krb5_rq_red() is going to check the Windows PAC or not * @@ -917,6 +939,11 @@ krb5_rd_req_ctx(krb5_context context, &o->keyblock); if (ret) goto out; + } else if (id && inctx && inctx->iterate_keytab) { + /* + * Force iterating over the keytab. + */ + o->keyblock = NULL; } else { if(id == NULL) { diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map index 7b49c15dfc0e..b18a1c5d7375 100644 --- a/source4/heimdal/lib/krb5/version-script.map +++ b/source4/heimdal/lib/krb5/version-script.map @@ -526,6 +526,7 @@ HEIMDAL_KRB5_2.0 { krb5_rd_req_ctx; krb5_rd_req_in_ctx_alloc; krb5_rd_req_in_ctx_free; + krb5_rd_req_in_set_iterate_keytab; krb5_rd_req_in_set_keyblock; krb5_rd_req_in_set_keytab; krb5_rd_req_in_set_pac_check; -- 2.17.1 From d6a9a47c72cbee78c3b97c36d7db9977655e4bcd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 10:30:01 +0200 Subject: [PATCH 13/25] UPSTREAM-FIRST!!! HEIMDAL:lib/gssapi/krb5: add GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X This allows krb5_rd_req_in_set_iterate_keytab() to be used via the gssapi layer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- .../heimdal/lib/gssapi/gssapi/gssapi_oid.h | 3 +++ .../lib/gssapi/krb5/accept_sec_context.c | 7 ++++++ .../heimdal/lib/gssapi/krb5/gsskrb5_locl.h | 1 + .../heimdal/lib/gssapi/krb5/set_cred_option.c | 22 +++++++++++++++++++ source4/heimdal/lib/gssapi/mech/gss_oid.c | 3 +++ source4/heimdal/lib/gssapi/version-script.map | 1 + 6 files changed, 37 insertions(+) diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h index 0eed639d53e1..48ff4035d854 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_oid.h @@ -99,6 +99,9 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc; extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_transit_check_x_oid_desc; #define GSS_KRB5_CRED_NO_TRANSIT_CHECK_X (&__gss_krb5_cred_no_transit_check_x_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc; +#define GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X (&__gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc) + extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc; #define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc) diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 2e4ed53ba08e..d5865e5bdd71 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -398,11 +398,16 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; krb5_principal server = NULL; + krb5_boolean iterate_keytab = FALSE; krb5_flags verify_ap_req_flags = 0; if (acceptor_cred) { server = acceptor_cred->principal; + if (acceptor_cred->cred_flags & GSS_CF_ITERATE_ACCEPTOR_KEYTAB) { + iterate_keytab = TRUE; + } + if (acceptor_cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { verify_ap_req_flags |= KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK; } @@ -411,6 +416,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) kret = krb5_rd_req_in_set_keytab(context, in, keytab); + if (kret == 0 && iterate_keytab) + kret = krb5_rd_req_in_set_iterate_keytab(context, in, TRUE); if (kret == 0) kret = krb5_rd_req_in_set_verify_ap_req_flags(context, in, verify_ap_req_flags); diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 6a1e977452cf..00b6f3405e29 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -95,6 +95,7 @@ typedef struct { #define GSS_CF_DESTROY_CRED_ON_RELEASE 1 #define GSS_CF_NO_CI_FLAGS 2 #define GSS_CF_NO_TRANSIT_CHECK 4 +#define GSS_CF_ITERATE_ACCEPTOR_KEYTAB 8 struct krb5_keytab_data *keytab; OM_uint32 lifetime; gss_cred_usage_t usage; diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 8d9f49884884..9ad17bfc322c 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -215,6 +215,25 @@ no_ci_flags(OM_uint32 *minor_status, } +static OM_uint32 +iterate_acceptor_keytab(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + cred->cred_flags |= GSS_CF_ITERATE_ACCEPTOR_KEYTAB; + + *minor_status = 0; + return GSS_S_COMPLETE; +} static OM_uint32 no_transit_check(OM_uint32 *minor_status, @@ -262,6 +281,9 @@ _gsskrb5_set_cred_option return no_ci_flags(minor_status, context, cred_handle, value); } + if (gss_oid_equal(desired_object, GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X)) { + return iterate_acceptor_keytab(minor_status, context, cred_handle, value); + } if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_TRANSIT_CHECK_X)) { return no_transit_check(minor_status, context, cred_handle, value); diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid.c b/source4/heimdal/lib/gssapi/mech/gss_oid.c index 6f86eec65c39..de4ed2e571f3 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_oid.c +++ b/source4/heimdal/lib/gssapi/mech/gss_oid.c @@ -97,6 +97,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNC /* GSS_KRB5_CRED_NO_TRANSIT_CHECK_X - 1.2.752.43.13.31 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_transit_check_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") }; +/* GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X - 1.2.752.43.13.31 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x20") }; + /* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") }; diff --git a/source4/heimdal/lib/gssapi/version-script.map b/source4/heimdal/lib/gssapi/version-script.map index 776fe19dbf3c..6fcfce3ec5ea 100644 --- a/source4/heimdal/lib/gssapi/version-script.map +++ b/source4/heimdal/lib/gssapi/version-script.map @@ -153,6 +153,7 @@ HEIMDAL_GSS_2.0 { __gss_c_ntlm_v2_oid_desc; __gss_c_ntlm_session_key_oid_desc; __gss_c_ntlm_force_v1_oid_desc; + __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc; __gss_krb5_cred_no_ci_flags_x_oid_desc; __gss_krb5_cred_no_transit_check_x_oid_desc; __gss_krb5_import_cred_x_oid_desc; -- 2.17.1 From 19f92c6fcf287e991e43969681c730805c6e69b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:09:47 +0000 Subject: [PATCH 14/25] s4:heimdal_build: define HAVE_GSS_KRB5_CRED_{NO_TRANSIT_CHECK,ITERATE_ACCEPTOR_KEYTAB}_X BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source4/heimdal_build/wscript_configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/heimdal_build/wscript_configure b/source4/heimdal_build/wscript_configure index 903fb5139db8..57658b577a1a 100644 --- a/source4/heimdal_build/wscript_configure +++ b/source4/heimdal_build/wscript_configure @@ -87,6 +87,8 @@ conf.define('HAVE_GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT', 1) conf.define('HAVE_GSS_IMPORT_CRED', 1) conf.define('HAVE_GSS_EXPORT_CRED', 1) conf.define('HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X', 1) +conf.define('HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X', 1) +conf.define('HAVE_GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X', 1) conf.define('HAVE_GSSAPI', 1) conf.define('HAVE_ADDR_TYPE_IN_KRB5_ADDRESS', 1) conf.define('HAVE_CHECKSUM_IN_KRB5_CHECKSUM', 1) -- 2.17.1 From c58950ecc242656c77b66ec8865d0f3e4dc4f293 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:09:47 +0000 Subject: [PATCH 15/25] configure_mitkrb5: check for GSS_KRB5_CRED_NO_TRANSIT_CHECK_X BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- wscript_configure_system_mitkrb5 | 1 + 1 file changed, 1 insertion(+) diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5 index b05ac3f3e50c..bad6ce9a95d6 100644 --- a/wscript_configure_system_mitkrb5 +++ b/wscript_configure_system_mitkrb5 @@ -115,6 +115,7 @@ conf.CHECK_FUNCS_IN(''' gss_acquire_cred_from ''', 'gssapi gssapi_krb5') conf.CHECK_VARIABLE('GSS_KRB5_CRED_NO_CI_FLAGS_X', headers=possible_gssapi_headers) +conf.CHECK_VARIABLE('GSS_KRB5_CRED_NO_TRANSIT_CHECK_X', headers=possible_gssapi_headers) conf.CHECK_FUNCS_IN('krb5_mk_req_extended krb5_kt_compare', 'krb5') conf.CHECK_FUNCS(''' krb5_auth_con_getrecvsubkey -- 2.17.1 From a5d0cdb8a6187005ecf85b50452b61feb7e130a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:51:49 +0000 Subject: [PATCH 16/25] s3:gse: add helper define __TMP_NEED_EMPTY_BUFFFER This will simplify the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source3/librpc/crypto/gse.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 9a9f4261222f..343e0f581735 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -256,9 +256,12 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx; OM_uint32 gss_maj, gss_min; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); -#endif +#define __TMP_NEED_EMPTY_BUFFFER 1 +#endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ +#ifdef __TMP_NEED_EMPTY_BUFFFER + gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; +#endif /* __TMP_NEED_EMPTY_BUFFFER */ NTSTATUS status; if (!server || !service) { -- 2.17.1 From fad297a2696f54b4ad581fbeb4a73bde9b84100d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:51:49 +0000 Subject: [PATCH 17/25] s3:gse: rename oid to no_ci_flags_oid This will simplify the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source3/librpc/crypto/gse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 343e0f581735..25aac7e0448f 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -256,7 +256,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx; OM_uint32 gss_maj, gss_min; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); + gss_OID no_ci_flags_oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #define __TMP_NEED_EMPTY_BUFFFER 1 #endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ #ifdef __TMP_NEED_EMPTY_BUFFFER @@ -314,7 +314,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 */ gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, - oid, + no_ci_flags_oid, &empty_buffer); if (gss_maj) { DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), " -- 2.17.1 From 548f527f3fa0dcc718288decc6a81f1d609d0168 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:51:49 +0000 Subject: [PATCH 18/25] s3:gse: let gse_init_client() use GSS_KRB5_CRED_NO_TRANSIT_CHECK_X There no need to do any possible transit checking on the client side. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- source3/librpc/crypto/gse.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 25aac7e0448f..dc074d1ae1ae 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -259,6 +259,12 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, gss_OID no_ci_flags_oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #define __TMP_NEED_EMPTY_BUFFFER 1 #endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ +#ifdef HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X + gss_OID no_transit_oid = discard_const(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X); +#ifndef __TMP_NEED_EMPTY_BUFFFER +#define __TMP_NEED_EMPTY_BUFFFER 1 +#endif /* __TMP_NEED_EMPTY_BUFFFER */ +#endif /* HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X */ #ifdef __TMP_NEED_EMPTY_BUFFFER gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; #endif /* __TMP_NEED_EMPTY_BUFFFER */ @@ -325,6 +331,19 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, } #endif +#ifdef HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X + gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, + no_transit_oid, + &empty_buffer); + if (gss_maj) { + DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X), " + "failed with [%s]\n", + gse_errstr(gse_ctx, gss_maj, gss_min))); + status = NT_STATUS_INTERNAL_ERROR; + goto err_out; + } +#endif + *_gse_ctx = gse_ctx; return NT_STATUS_OK; -- 2.17.1 From dc7ae1a365d0a176a13b147ed6c117a9dd142a63 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 16:52:15 +0000 Subject: [PATCH 19/25] krb5_wrap: add smb_gss_krb5_prepare_acceptor_cred() BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- lib/krb5_wrap/gss_samba.c | 45 +++++++++++++++++++++++++++++++++++++++ lib/krb5_wrap/gss_samba.h | 4 ++++ 2 files changed, 49 insertions(+) diff --git a/lib/krb5_wrap/gss_samba.c b/lib/krb5_wrap/gss_samba.c index 2a99661ddee2..2d3016088ed8 100644 --- a/lib/krb5_wrap/gss_samba.c +++ b/lib/krb5_wrap/gss_samba.c @@ -210,5 +210,50 @@ uint32_t smb_gss_krb5_import_cred(uint32_t *minor_status, krb5_context ctx, return major_status; } +uint32_t smb_gss_krb5_prepare_acceptor_cred(uint32_t *minor_status, + bool require_pac, + gss_cred_id_t *cred) +{ +#ifdef HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X + OM_uint32 gss_maj, gss_min; + gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; + gss_OID no_transit_oid = discard_const(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X); +#ifdef HAVE_GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X /* only heimdal */ + gss_OID iterate_keytab_oid = + discard_const(GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X); + + gss_maj = gss_set_cred_option(&gss_min, cred, + iterate_keytab_oid, + &empty_buffer); + if (gss_maj) { + DBG_ERR("gss_set_cred_option(ITERATE_ACCEPTOR_KEYTAB_X)\n"); + *minor_status = gss_min; + return gss_maj; + } +#endif /* HAVE_GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X */ + + if (!require_pac) { + goto done; + } + + /* + * If we require a valid PAC we can + * skip the transit checks in the krb5 + * code. + */ + gss_maj = gss_set_cred_option(&gss_min, cred, + no_transit_oid, + &empty_buffer); + if (gss_maj) { + DBG_ERR("gss_set_cred_option(NO_TRANSIT_CHECK_X)\n"); + *minor_status = gss_min; + return gss_maj; + } + +done: +#endif /* HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X */ + *minor_status = 0; + return 0; +} #endif /* HAVE_GSSAPI */ diff --git a/lib/krb5_wrap/gss_samba.h b/lib/krb5_wrap/gss_samba.h index 89aee3479c55..77c8758ed3d8 100644 --- a/lib/krb5_wrap/gss_samba.h +++ b/lib/krb5_wrap/gss_samba.h @@ -45,5 +45,9 @@ uint32_t smb_gss_krb5_import_cred(OM_uint32 *minor_status, krb5_context ctx, krb5_ccache id, krb5_principal keytab_principal, krb5_keytab keytab, gss_cred_id_t *cred); +uint32_t smb_gss_krb5_prepare_acceptor_cred(uint32_t *minor_status, + bool require_pac, + gss_cred_id_t *cred); + #endif /* HAVE_GSSAPI */ #endif /* _GSS_SAMBA_H */ -- 2.17.1 From 57ca0acf6dfc40341d3b060738dd068ab60359b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:13:41 +0000 Subject: [PATCH 20/25] s3:gse: let gse_init_server() use smb_gss_krb5_prepare_acceptor_cred() We should check all keys in our in memory keytab and don't need any transited checks if we require a PAC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- source3/librpc/crypto/gse.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index dc074d1ae1ae..cd225b6373d1 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -598,6 +598,7 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, OM_uint32 gss_maj, gss_min; krb5_error_code ret; NTSTATUS status; + bool require_pac = lp_require_pac(); status = gse_context_init(mem_ctx, do_sign, do_seal, NULL, add_gss_c_flags, &gse_ctx); @@ -624,6 +625,17 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx, goto done; } + gss_maj = smb_gss_krb5_prepare_acceptor_cred(&gss_min, + require_pac, + &gse_ctx->creds); + + if (gss_maj != 0) { + DEBUG(0, ("smb_gss_krb5_prepare_acceptor_cred failed with [%s]\n", + gse_errstr(gse_ctx, gss_maj, gss_min))); + status = NT_STATUS_INTERNAL_ERROR; + goto done; + } + status = NT_STATUS_OK; done: -- 2.17.1 From 2e772f301b50cc4ab4a6cabe0858213faead8d47 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:24:24 +0000 Subject: [PATCH 21/25] auth/credentials_krb5: add helper define __TMP_NEED_EMPTY_BUFFFER This simplifies the following commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 20e677e521a8..c7247cfe9790 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -835,9 +835,12 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct gssapi_creds_container *gcc; struct ccache_container *ccache; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); -#endif +#define __TMP_NEED_EMPTY_BUFFFER 1 +#endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ +#ifdef __TMP_NEED_EMPTY_BUFFFER + gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; +#endif /* __TMP_NEED_EMPTY_BUFFFER */ krb5_enctype *etypes = NULL; if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && -- 2.17.1 From 9b0a70b3e879d5c1fe2359eb6f2563f7ab4a4a3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:24:24 +0000 Subject: [PATCH 22/25] auth/credentials_krb5: rename oid to no_ci_flags_oid This will simplify the following commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index c7247cfe9790..03c1e8a9a115 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -835,7 +835,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct gssapi_creds_container *gcc; struct ccache_container *ccache; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); + gss_OID no_ci_flags_oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #define __TMP_NEED_EMPTY_BUFFFER 1 #endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ #ifdef __TMP_NEED_EMPTY_BUFFFER @@ -971,7 +971,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 */ maj_stat = gss_set_cred_option(&min_stat, &gcc->creds, - oid, + no_ci_flags_oid, &empty_buffer); if (maj_stat) { talloc_free(gcc); -- 2.17.1 From 44d978fa86c15ab4a5d31bd0e41a60ba79f6661d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:24:24 +0000 Subject: [PATCH 23/25] auth/credentials_krb5: let cli_credentials_get_client_gss_creds() use NO_TRANSIT_CHECK_X There no need to do any possible transit checking on the client side. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 03c1e8a9a115..b4cb438f09d3 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -838,6 +838,12 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, gss_OID no_ci_flags_oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #define __TMP_NEED_EMPTY_BUFFFER 1 #endif /* HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X */ +#ifdef HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X + gss_OID no_transit_oid = discard_const(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X); +#ifndef __TMP_NEED_EMPTY_BUFFFER +#define __TMP_NEED_EMPTY_BUFFFER 1 +#endif /* __TMP_NEED_EMPTY_BUFFFER */ +#endif /* HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X */ #ifdef __TMP_NEED_EMPTY_BUFFFER gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; #endif /* __TMP_NEED_EMPTY_BUFFFER */ @@ -983,6 +989,21 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret)); return ret; } +#endif +#ifdef HAVE_GSS_KRB5_CRED_NO_TRANSIT_CHECK_X + maj_stat = gss_set_cred_option(&min_stat, &gcc->creds, + no_transit_oid, + &empty_buffer); + if (maj_stat) { + talloc_free(gcc); + if (min_stat) { + ret = min_stat; + } else { + ret = EINVAL; + } + (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret)); + return ret; + } #endif cred->client_gss_creds_obtained = cred->ccache_obtained; talloc_set_destructor(gcc, free_gssapi_creds); -- 2.17.1 From c0cefd0a0c717f40a3a69b2f09cd883f3740c1ca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:25:09 +0000 Subject: [PATCH 24/25] auth/credentials_krb5: let cli_credentials_get_server_gss_creds() use an early return This will simplify the next commits. Check with: git show -w BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index b4cb438f09d3..8de18c440a16 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -1383,14 +1383,16 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, ret = EINVAL; } } - if (ret == 0) { - cred->server_gss_creds_obtained = cred->keytab_obtained; - talloc_set_destructor(gcc, free_gssapi_creds); - cred->server_gss_creds = gcc; - *_gcc = gcc; + if (ret != 0) { + talloc_free(mem_ctx); + return ret; } + cred->server_gss_creds_obtained = cred->keytab_obtained; + talloc_set_destructor(gcc, free_gssapi_creds); + cred->server_gss_creds = gcc; + *_gcc = gcc; talloc_free(mem_ctx); - return ret; + return 0; } /** -- 2.17.1 From f656f81667a454d06af72ac8ce6c12227a26f131 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 17:25:30 +0000 Subject: [PATCH 25/25] auth/credentials_krb5: make use of smb_gss_krb5_prepare_acceptor_cred() We should check all keys in our in memory keytab and don't need any transited checks if we require a PAC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 8de18c440a16..31d29d3fd90e 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -1387,6 +1387,20 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, talloc_free(mem_ctx); return ret; } + maj_stat = smb_gss_krb5_prepare_acceptor_cred(&min_stat, + true, /* require_pac */ + &gcc->creds); + if (maj_stat) { + if (min_stat) { + ret = min_stat; + } else { + ret = EINVAL; + } + } + if (ret != 0) { + talloc_free(mem_ctx); + return ret; + } cred->server_gss_creds_obtained = cred->keytab_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->server_gss_creds = gcc; -- 2.17.1