From 815da6970c8b973c514cc148b2caeca84f604f5c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 8 Aug 2019 15:06:28 +0100 Subject: [PATCH 01/22] s3/libads: clang: Fix Value stored to 'canon_princ' is never read Fixes: source3/libads/kerberos.c:192:2: warning: Value stored to 'canon_princ' is never read <--[clang] canon_princ = me; ^ ~~ 1 warning generated. Signed-off-by: Noel Power Reviewed-by: Gary Lockyer (cherry picked from commit 52d20087f620704549f5a5cdcbec79cb08a36290) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 721c3c2a929..9fbe7dd0f07 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -189,9 +189,10 @@ int kerberos_kinit_password_ext(const char *principal, goto out; } - canon_princ = me; #ifndef SAMBA4_USES_HEIMDAL /* MIT */ canon_princ = my_creds.client; +#else + canon_princ = me; #endif /* MIT */ if ((code = krb5_cc_initialize(ctx, cc, canon_princ))) { -- 2.24.1 From 9db218df645bd15232b5bda98f51f0ecc05425c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2019 08:05:09 +0200 Subject: [PATCH 02/22] s4:auth: use the correct client realm in gensec_gssapi_update_internal() The function gensec_gssapi_client_creds() may call kinit and gets a TGT for the user. The principal provided by the user may not be canonicalized. The user may use 'given.last@example.com' but that may be mapped to glast@AD.EXAMPLE.PRIVATE in the background. It means we should use client_realm = AD.EXAMPLE.PRIVATE instead of client_realm = EXAMPLE.COM BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit db8fd3d6a315b140ebd6ccd0dcdfdcf27cd1bb38) --- source4/auth/gensec/gensec_gssapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4577c91c93a..045a0225741 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -437,8 +437,6 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec const char *target_principal = gensec_get_target_principal(gensec_security); const char *hostname = gensec_get_target_hostname(gensec_security); const char *service = gensec_get_target_service(gensec_security); - const char *client_realm = cli_credentials_get_realm(cli_creds); - const char *server_realm = NULL; gss_OID gss_oid_p = NULL; OM_uint32 time_req = 0; OM_uint32 time_rec = 0; @@ -457,6 +455,7 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec switch (gensec_security->gensec_role) { case GENSEC_CLIENT: { + const char *client_realm = NULL; #ifdef SAMBA4_USES_HEIMDAL struct gsskrb5_send_to_kdc send_to_kdc; krb5_error_code ret; @@ -532,6 +531,7 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec * transitive forest trusts, would have to do the * fallback ourself. */ + client_realm = cli_credentials_get_realm(cli_creds); #ifndef SAMBA4_USES_HEIMDAL if (gensec_gssapi_state->server_name == NULL) { nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state, @@ -575,6 +575,8 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec } #endif /* !SAMBA4_USES_HEIMDAL */ if (gensec_gssapi_state->server_name == NULL) { + const char *server_realm = NULL; + server_realm = smb_krb5_get_realm_from_hostname(gensec_gssapi_state, hostname, client_realm); -- 2.24.1 From 7e70ce1c6a6bb4041dbad54628d4f93caff771d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2019 17:14:11 +0200 Subject: [PATCH 03/22] s3:libads: let kerberos_kinit_password_ext() return the canonicalized principal/realm BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit bc473e5cf088a137395842540ed8eb748373a236) --- source3/libads/authdata.c | 1 + source3/libads/kerberos.c | 46 ++++++++++++++++++++++---- source3/libads/kerberos_proto.h | 5 ++- source3/libads/kerberos_util.c | 3 +- source3/utils/net_ads.c | 3 ++ source3/winbindd/winbindd_cred_cache.c | 6 ++++ 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 86a1be71bf9..6e6d5b397ff 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -170,6 +170,7 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, request_pac, add_netbios_addr, renewable_time, + NULL, NULL, NULL, &status); if (ret) { DEBUG(1,("kinit failed for '%s' with: %s (%d)\n", diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9fbe7dd0f07..3e09d70268f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -106,7 +106,7 @@ kerb_prompter(krb5_context ctx, void *data, place in default cache location. remus@snapserver.com */ -int kerberos_kinit_password_ext(const char *principal, +int kerberos_kinit_password_ext(const char *given_principal, const char *password, int time_offset, time_t *expire_time, @@ -115,8 +115,12 @@ int kerberos_kinit_password_ext(const char *principal, bool request_pac, bool add_netbios_addr, time_t renewable_time, + TALLOC_CTX *mem_ctx, + char **_canon_principal, + char **_canon_realm, NTSTATUS *ntstatus) { + TALLOC_CTX *frame = talloc_stackframe(); krb5_context ctx = NULL; krb5_error_code code = 0; krb5_ccache cc = NULL; @@ -125,6 +129,8 @@ int kerberos_kinit_password_ext(const char *principal, krb5_creds my_creds; krb5_get_init_creds_opt *opt = NULL; smb_krb5_addresses *addr = NULL; + char *canon_principal = NULL; + char *canon_realm = NULL; ZERO_STRUCT(my_creds); @@ -132,6 +138,7 @@ int kerberos_kinit_password_ext(const char *principal, if (code != 0) { DBG_ERR("kerberos init context failed (%s)\n", error_message(code)); + TALLOC_FREE(frame); return code; } @@ -139,16 +146,16 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n", - principal, - cache_name ? cache_name: krb5_cc_default_name(ctx), - getenv("KRB5_CONFIG"))); + DBG_DEBUG("as %s using [%s] as ccache and config [%s]\n", + given_principal, + cache_name ? cache_name: krb5_cc_default_name(ctx), + getenv("KRB5_CONFIG")); if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { goto out; } - if ((code = smb_krb5_parse_name(ctx, principal, &me))) { + if ((code = smb_krb5_parse_name(ctx, given_principal, &me))) { goto out; } @@ -195,6 +202,22 @@ int kerberos_kinit_password_ext(const char *principal, canon_princ = me; #endif /* MIT */ + code = smb_krb5_unparse_name(frame, + ctx, + canon_princ, + &canon_principal); + if (code != 0) { + goto out; + } + + DBG_DEBUG("%s mapped to %s\n", given_principal, canon_principal); + + canon_realm = smb_krb5_principal_get_realm(frame, ctx, canon_princ); + if (canon_realm == NULL) { + code = ENOMEM; + goto out; + } + if ((code = krb5_cc_initialize(ctx, cc, canon_princ))) { goto out; } @@ -210,6 +233,13 @@ int kerberos_kinit_password_ext(const char *principal, if (renew_till_time) { *renew_till_time = (time_t) my_creds.times.renew_till; } + + if (_canon_principal != NULL) { + *_canon_principal = talloc_move(mem_ctx, &canon_principal); + } + if (_canon_realm != NULL) { + *_canon_realm = talloc_move(mem_ctx, &canon_realm); + } out: if (ntstatus) { /* fast path */ @@ -239,6 +269,7 @@ int kerberos_kinit_password_ext(const char *principal, if (ctx) { krb5_free_context(ctx); } + TALLOC_FREE(frame); return code; } @@ -328,6 +359,9 @@ int kerberos_kinit_password(const char *principal, False, False, 0, + NULL, + NULL, + NULL, NULL); } diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h index f92cabd757e..433bce9e0ec 100644 --- a/source3/libads/kerberos_proto.h +++ b/source3/libads/kerberos_proto.h @@ -45,7 +45,7 @@ struct PAC_DATA_CTR { /* The following definitions come from libads/kerberos.c */ -int kerberos_kinit_password_ext(const char *principal, +int kerberos_kinit_password_ext(const char *given_principal, const char *password, int time_offset, time_t *expire_time, @@ -54,6 +54,9 @@ int kerberos_kinit_password_ext(const char *principal, bool request_pac, bool add_netbios_addr, time_t renewable_time, + TALLOC_CTX *mem_ctx, + char **_canon_principal, + char **_canon_realm, NTSTATUS *ntstatus); int ads_kdestroy(const char *cc_name); diff --git a/source3/libads/kerberos_util.c b/source3/libads/kerberos_util.c index 68c0f302239..bfe53820aff 100644 --- a/source3/libads/kerberos_util.c +++ b/source3/libads/kerberos_util.c @@ -66,7 +66,8 @@ int ads_kinit_password(ADS_STRUCT *ads) ads->auth.time_offset, &ads->auth.tgt_expire, NULL, ads->auth.ccache_name, false, false, - ads->auth.renewable, NULL); + ads->auth.renewable, + NULL, NULL, NULL, NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 1f055507ad7..d33031a0dbd 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -3352,6 +3352,9 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** true, true, 2592000, /* one month */ + NULL, + NULL, + NULL, &status); if (ret) { d_printf(_("failed to kinit password: %s\n"), diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c index 85ad426446a..5baecf906b9 100644 --- a/source3/winbindd/winbindd_cred_cache.c +++ b/source3/winbindd/winbindd_cred_cache.c @@ -146,6 +146,9 @@ rekinit: False, /* no PAC required anymore */ True, WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, + NULL, + NULL, + NULL, NULL); gain_root_privilege(); @@ -343,6 +346,9 @@ static void krb5_ticket_gain_handler(struct tevent_context *event_ctx, False, /* no PAC required anymore */ True, WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, + NULL, + NULL, + NULL, NULL); gain_root_privilege(); -- 2.24.1 From 0455607124f93b72c1233d451efefbc0c445017e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2019 10:08:10 +0200 Subject: [PATCH 04/22] s3:libsmb: avoid wrong debug message in cli_session_creds_prepare_krb5() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 361fb0efabfb189526c851107eee49161da2293c) --- source3/libsmb/cliconnect.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c416d10fa24..28f5fde0757 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -375,6 +375,8 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, /* * Ignore the error and hope that NTLM will work */ + TALLOC_FREE(frame); + return NT_STATUS_OK; } DBG_DEBUG("Successfully authenticated as %s to access %s using " -- 2.24.1 From 68c4e372ef66fda975c4db7eb4fd283bfe4218a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2019 08:49:13 +0200 Subject: [PATCH 05/22] s3:libsmb: let cli_session_creds_prepare_krb5() update the canonicalized principal to cli_credentials BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 6ed18c12c57efb2a010e0ce5196c51b48e57a4b9) --- source3/libsmb/cliconnect.c | 39 ++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 28f5fde0757..ca6882c225e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -229,6 +229,8 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, const char *user_account = NULL; const char *user_domain = NULL; const char *pass = NULL; + char *canon_principal = NULL; + char *canon_realm = NULL; const char *target_hostname = NULL; const DATA_BLOB *server_blob = NULL; bool got_kerberos_mechanism = false; @@ -237,6 +239,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, bool need_kinit = false; bool auth_requested = true; int ret; + bool ok; target_hostname = smbXcli_conn_remote_name(cli->conn); server_blob = smbXcli_conn_server_gss_blob(cli->conn); @@ -245,7 +248,6 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, if (server_blob != NULL && server_blob->length != 0) { char *OIDs[ASN1_MAX_OIDS] = { NULL, }; size_t i; - bool ok; /* * The server sent us the first part of the SPNEGO exchange in the @@ -354,9 +356,19 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, * only if required! */ setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); - ret = kerberos_kinit_password(user_principal, pass, - 0 /* no time correction for now */, - NULL); + ret = kerberos_kinit_password_ext(user_principal, + pass, + 0, + 0, + 0, + NULL, + false, + false, + 0, + frame, + &canon_principal, + &canon_realm, + NULL); if (ret != 0) { int dbglvl = DBGLVL_NOTICE; @@ -379,9 +391,26 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, return NT_STATUS_OK; } - DBG_DEBUG("Successfully authenticated as %s to access %s using " + ok = cli_credentials_set_principal(creds, + canon_principal, + CRED_SPECIFIED); + if (!ok) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + ok = cli_credentials_set_realm(creds, + canon_realm, + CRED_SPECIFIED); + if (!ok) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using " "Kerberos\n", user_principal, + canon_principal, target_hostname); TALLOC_FREE(frame); -- 2.24.1 From 38fd2f1fe94b63242296b2b1ce0a49065969a820 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Sep 2019 16:04:30 +0200 Subject: [PATCH 06/22] s3:libads/kerberos: always use the canonicalized principal after kinit We should always use krb5_get_init_creds_opt_set_canonicalize() and krb5_get_init_creds_opt_set_win2k() for heimdal and expect the client principal to be changed. There's no reason to have a different logic between MIT and Heimdal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 0bced73bed481a8846a6b3e68be85941914390ba) --- source3/libads/kerberos.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 3e09d70268f..559ec3b7f53 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -167,7 +167,10 @@ int kerberos_kinit_password_ext(const char *given_principal, krb5_get_init_creds_opt_set_forwardable(opt, True); /* Turn on canonicalization for lower case realm support */ -#ifndef SAMBA4_USES_HEIMDAL /* MIT */ +#ifdef SAMBA4_USES_HEIMDAL + krb5_get_init_creds_opt_set_win2k(ctx, opt, true); + krb5_get_init_creds_opt_set_canonicalize(ctx, opt, true); +#else /* MIT */ krb5_get_init_creds_opt_set_canonicalize(opt, true); #endif /* MIT */ #if 0 @@ -196,11 +199,7 @@ int kerberos_kinit_password_ext(const char *given_principal, goto out; } -#ifndef SAMBA4_USES_HEIMDAL /* MIT */ canon_princ = my_creds.client; -#else - canon_princ = me; -#endif /* MIT */ code = smb_krb5_unparse_name(frame, ctx, -- 2.24.1 From 6e1a52f6f48ca6624c8988a03ecfe5a3327c537e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Sep 2019 16:04:30 +0200 Subject: [PATCH 07/22] krb5_wrap: smb_krb5_kinit_password_ccache() should always use the canonicalized principal We should always use krb5_get_init_creds_opt_set_canonicalize() and krb5_get_init_creds_opt_set_win2k() for heimdal and expect the client principal to be changed. There's no reason to have a different logic between MIT and Heimdal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 5d0bf32ec0ad21d49587e3a1520ffdc8b5ae7614) --- lib/krb5_wrap/krb5_samba.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c index f0dc86b1859..a63159812e1 100644 --- a/lib/krb5_wrap/krb5_samba.c +++ b/lib/krb5_wrap/krb5_samba.c @@ -2111,14 +2111,12 @@ krb5_error_code smb_krb5_kinit_password_ccache(krb5_context ctx, return code; } -#ifndef SAMBA4_USES_HEIMDAL /* MIT */ /* * We need to store the principal as returned from the KDC to the * credentials cache. If we don't do that the KRB5 library is not * able to find the tickets it is looking for */ principal = my_creds.client; -#endif code = krb5_cc_initialize(ctx, cc, principal); if (code) { goto done; -- 2.24.1 From b19c14b730b470f969ccb2e2a64f57dc3ece46de Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Sep 2019 16:04:30 +0200 Subject: [PATCH 08/22] s4:auth: kinit_to_ccache() should always use the canonicalized principal We should always use krb5_get_init_creds_opt_set_canonicalize() and krb5_get_init_creds_opt_set_win2k() for heimdal and expect the client principal to be changed. There's no reason to have a different logic between MIT and Heimdal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 162b4199493c1f179e775a325a19ae7a136c418b) --- source4/auth/kerberos/kerberos_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 50bf8feec96..950d91f1737 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -313,6 +313,8 @@ done: */ krb5_get_init_creds_opt_set_win2k(smb_krb5_context->krb5_context, krb_options, true); + krb5_get_init_creds_opt_set_canonicalize(smb_krb5_context->krb5_context, + krb_options, true); #else /* MIT */ krb5_get_init_creds_opt_set_canonicalize(krb_options, true); #endif -- 2.24.1 From 1cf9d944d7dd15d8c3c796f071f82d8ffff7095e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Sep 2019 16:04:30 +0200 Subject: [PATCH 09/22] s3:libads: ads_krb5_chg_password() should always use the canonicalized principal We should always use krb5_get_init_creds_opt_set_canonicalize() and krb5_get_init_creds_opt_set_win2k() for heimdal and expect the client principal to be changed. There's no reason to have a different logic between MIT and Heimdal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 303b7e59a286896888ee2473995fc50bb2b5ce5e) --- source3/libads/krb5_setpw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c3c9477c4cf..67bc2f4640d 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -203,6 +203,12 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, krb5_get_init_creds_opt_set_renew_life(opts, 0); krb5_get_init_creds_opt_set_forwardable(opts, 0); krb5_get_init_creds_opt_set_proxiable(opts, 0); +#ifdef SAMBA4_USES_HEIMDAL + krb5_get_init_creds_opt_set_win2k(context, opts, true); + krb5_get_init_creds_opt_set_canonicalize(context, opts, true); +#else /* MIT */ + krb5_get_init_creds_opt_set_canonicalize(opts, true); +#endif /* MIT */ /* note that heimdal will fill in the local addresses if the addresses * in the creds_init_opt are all empty and then later fail with invalid -- 2.24.1 From dc23b10c5c82f4587062fea5d68eb5d373d37bcb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Sep 2019 15:52:25 +0200 Subject: [PATCH 10/22] krb5_wrap: let smb_krb5_parse_name() accept enterprise principals BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 3bdf023956e861485be70430112ed38d0a5424f7) --- lib/krb5_wrap/krb5_samba.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c index a63159812e1..abdcb308728 100644 --- a/lib/krb5_wrap/krb5_samba.c +++ b/lib/krb5_wrap/krb5_samba.c @@ -701,6 +701,11 @@ krb5_error_code smb_krb5_parse_name(krb5_context context, } ret = krb5_parse_name(context, utf8_name, principal); + if (ret == KRB5_PARSE_MALFORMED) { + ret = krb5_parse_name_flags(context, utf8_name, + KRB5_PRINCIPAL_PARSE_ENTERPRISE, + principal); + } TALLOC_FREE(frame); return ret; } -- 2.24.1 From 056fe4807255578204e56d247cd6ba003213e558 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Sep 2019 16:44:43 +0200 Subject: [PATCH 11/22] docs-xml: add "winbind use krb5 enterprise principals" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 9520652399696010c333a3ce7247809ce5337a91) --- .../winbindusekrb5enterpriseprincipals.xml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml diff --git a/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml b/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml new file mode 100644 index 00000000000..bfc11c8636c --- /dev/null +++ b/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml @@ -0,0 +1,34 @@ + + + winbindd is able to get kerberos tickets for + pam_winbind with krb5_auth or wbinfo -K/--krb5auth=. + + + winbindd (at least on a domain member) is never be able + to have a complete picture of the trust topology (which is managed by the DCs). + There might be uPNSuffixes and msDS-SPNSuffixes values, + which don't belong to any AD domain at all. + + + With no + winbindd don't even get an incomplete picture of the topology. + + + It is not really required to know about the trust topology. + We can just rely on the [K]DCs of our primary domain (e.g. PRIMARY.A.EXAMPLE.COM) + and use enterprise principals e.g. upnfromB@B.EXAMPLE.COM@PRIMARY.A.EXAMPLE.COM + and follow the WRONG_REALM referrals in order to find the correct DC. + The final principal might be userfromB@INTERNALB.EXAMPLE.PRIVATE. + + + With yes + winbindd enterprise principals will be used. + + + +no +yes + -- 2.24.1 From f2c43932e14173574177c9e36894a25e7d8a6609 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jul 2019 15:10:09 +0000 Subject: [PATCH 12/22] s3:winbindd: implement the "winbind use krb5 enterprise principals" logic We can use enterprise principals (e.g. upnfromB@B.EXAMPLE.COM@PRIMARY.A.EXAMPLE.COM) and delegate the routing decisions to the KDCs. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit a77be15d28390c5d12202278adbe6b50200a2c1b) --- source3/winbindd/winbindd_pam.c | 57 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index b81f2722c42..35018fbe284 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -418,6 +418,15 @@ struct winbindd_domain *find_auth_domain(uint8_t flags, return find_domain_from_name_noinit(domain_name); } + if (lp_winbind_use_krb5_enterprise_principals()) { + /* + * If we use enterprise principals + * we always go trough our primary domain + * and follow the WRONG_REALM replies. + */ + flags &= ~WBFLAG_PAM_CONTACT_TRUSTDOM; + } + /* we can auth against trusted domains */ if (flags & WBFLAG_PAM_CONTACT_TRUSTDOM) { domain = find_domain_from_name_noinit(domain_name); @@ -717,7 +726,20 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm); + if (lp_winbind_use_krb5_enterprise_principals() && + name_namespace[0] != '\0') + { + principal_s = talloc_asprintf(mem_ctx, + "%s@%s@%s", + name_user, + name_namespace, + realm); + } else { + principal_s = talloc_asprintf(mem_ctx, + "%s@%s", + name_user, + realm); + } if (principal_s == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1284,30 +1306,16 @@ static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, /* what domain should we contact? */ - if ( IS_DC ) { - contact_domain = find_domain_from_name(name_namespace); - if (contact_domain == NULL) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request->data.auth.user, name_domain, name_user, name_domain)); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - + if (lp_winbind_use_krb5_enterprise_principals()) { + contact_domain = find_auth_domain(0, name_namespace); } else { - if (is_myname(name_domain)) { - DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - contact_domain = find_domain_from_name(name_namespace); - if (contact_domain == NULL) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request->data.auth.user, name_domain, name_user, name_domain)); - - result = NT_STATUS_NO_SUCH_USER; - goto done; - } + } + if (contact_domain == NULL) { + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request->data.auth.user, name_domain, name_user, name_namespace)); + result = NT_STATUS_NO_SUCH_USER; + goto done; } if (contact_domain->initialized && @@ -1320,7 +1328,8 @@ static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, } if (!contact_domain->active_directory) { - DEBUG(3,("krb5 auth requested but domain is not Active Directory\n")); + DEBUG(3,("krb5 auth requested but domain (%s) is not Active Directory\n", + contact_domain->name)); return NT_STATUS_INVALID_LOGON_TYPE; } try_login: -- 2.24.1 From eb1bdb032fe5f63cd53cb5a40702b8bcfac673ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 08:04:42 +0200 Subject: [PATCH 13/22] tests/pam_winbind.py: turn pypamtest.PamTestError into a failure A failure generated by the AssertionError() checks can be added to selftest/knownfail.d/*. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit cd3ffaabb568db26e0de5e83178487e5947c4f09) --- python/samba/tests/pam_winbind.py | 15 ++++++++++++--- python/samba/tests/pam_winbind_chauthtok.py | 5 ++++- python/samba/tests/pam_winbind_warn_pwd_expire.py | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/python/samba/tests/pam_winbind.py b/python/samba/tests/pam_winbind.py index 68b05b30d7d..b05e8af6ffb 100644 --- a/python/samba/tests/pam_winbind.py +++ b/python/samba/tests/pam_winbind.py @@ -30,7 +30,10 @@ class SimplePamTests(samba.tests.TestCase): expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + try: + res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + except pypamtest.PamTestError as e: + raise AssertionError(str(e)) self.assertTrue(res is not None) @@ -42,7 +45,10 @@ class SimplePamTests(samba.tests.TestCase): expected_rc = 7 # PAM_AUTH_ERR tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + try: + res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + except pypamtest.PamTestError as e: + raise AssertionError(str(e)) self.assertTrue(res is not None) @@ -52,6 +58,9 @@ class SimplePamTests(samba.tests.TestCase): expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + try: + res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + except pypamtest.PamTestError as e: + raise AssertionError(str(e)) self.assertTrue(res is not None) diff --git a/python/samba/tests/pam_winbind_chauthtok.py b/python/samba/tests/pam_winbind_chauthtok.py index e5be3a83ce7..18c2705127a 100644 --- a/python/samba/tests/pam_winbind_chauthtok.py +++ b/python/samba/tests/pam_winbind_chauthtok.py @@ -31,6 +31,9 @@ class PamChauthtokTests(samba.tests.TestCase): expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_CHAUTHTOK, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password, newpassword, newpassword]) + try: + res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password, newpassword, newpassword]) + except pypamtest.PamTestError as e: + raise AssertionError(str(e)) self.assertTrue(res is not None) diff --git a/python/samba/tests/pam_winbind_warn_pwd_expire.py b/python/samba/tests/pam_winbind_warn_pwd_expire.py index df60bc5ace6..1af2f9befe1 100644 --- a/python/samba/tests/pam_winbind_warn_pwd_expire.py +++ b/python/samba/tests/pam_winbind_warn_pwd_expire.py @@ -31,7 +31,10 @@ class PasswordExpirePamTests(samba.tests.TestCase): expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) - res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + try: + res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) + except pypamtest.PamTestError as e: + raise AssertionError(str(e)) self.assertTrue(res is not None) if warn_pwd_expire == 0: -- 2.24.1 From 54999a5fccc1777c1ee766c552cf32bb489634c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Sep 2019 08:13:28 +0200 Subject: [PATCH 14/22] tests/pam_winbind.py: allow upn names to be used in USERNAME with an empty DOMAIN value BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 653e90485854d978dc522e689cd78c19dcc22a70) --- python/samba/tests/pam_winbind.py | 10 ++++++++-- python/samba/tests/pam_winbind_chauthtok.py | 5 ++++- python/samba/tests/pam_winbind_warn_pwd_expire.py | 5 ++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/python/samba/tests/pam_winbind.py b/python/samba/tests/pam_winbind.py index b05e8af6ffb..708f408f768 100644 --- a/python/samba/tests/pam_winbind.py +++ b/python/samba/tests/pam_winbind.py @@ -26,7 +26,10 @@ class SimplePamTests(samba.tests.TestCase): domain = os.environ["DOMAIN"] username = os.environ["USERNAME"] password = os.environ["PASSWORD"] - unix_username = "%s/%s" % (domain, username) + if domain != "": + unix_username = "%s/%s" % (domain, username) + else: + unix_username = "%s" % username expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) @@ -41,7 +44,10 @@ class SimplePamTests(samba.tests.TestCase): domain = os.environ["DOMAIN"] username = os.environ["USERNAME"] password = "WrongPassword" - unix_username = "%s/%s" % (domain, username) + if domain != "": + unix_username = "%s/%s" % (domain, username) + else: + unix_username = "%s" % username expected_rc = 7 # PAM_AUTH_ERR tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) diff --git a/python/samba/tests/pam_winbind_chauthtok.py b/python/samba/tests/pam_winbind_chauthtok.py index 18c2705127a..c1d569b3cd0 100644 --- a/python/samba/tests/pam_winbind_chauthtok.py +++ b/python/samba/tests/pam_winbind_chauthtok.py @@ -27,7 +27,10 @@ class PamChauthtokTests(samba.tests.TestCase): username = os.environ["USERNAME"] password = os.environ["PASSWORD"] newpassword = os.environ["NEWPASSWORD"] - unix_username = "%s/%s" % (domain, username) + if domain != "": + unix_username = "%s/%s" % (domain, username) + else: + unix_username = "%s" % username expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_CHAUTHTOK, expected_rc) diff --git a/python/samba/tests/pam_winbind_warn_pwd_expire.py b/python/samba/tests/pam_winbind_warn_pwd_expire.py index 1af2f9befe1..56f5da94f98 100644 --- a/python/samba/tests/pam_winbind_warn_pwd_expire.py +++ b/python/samba/tests/pam_winbind_warn_pwd_expire.py @@ -27,7 +27,10 @@ class PasswordExpirePamTests(samba.tests.TestCase): username = os.environ["USERNAME"] password = os.environ["PASSWORD"] warn_pwd_expire = int(os.environ["WARN_PWD_EXPIRE"]) - unix_username = "%s/%s" % (domain, username) + if domain != "": + unix_username = "%s/%s" % (domain, username) + else: + unix_username = "%s" % username expected_rc = 0 # PAM_SUCCESS tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) -- 2.24.1 From a36c24e3553477c52864db8b4796cbe63ed6462a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 01:25:58 +0200 Subject: [PATCH 15/22] test_pam_winbind.sh: allow different pam_winbindd config options to be specified BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 3d38a8e9135bb72bc4ca079fab0eb5358942b3f1) --- python/samba/tests/test_pam_winbind.sh | 12 +++++++---- .../samba/tests/test_pam_winbind_chauthtok.sh | 4 ++-- .../tests/test_pam_winbind_warn_pwd_expire.sh | 20 +++++++++++-------- selftest/tests.py | 6 +++--- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/python/samba/tests/test_pam_winbind.sh b/python/samba/tests/test_pam_winbind.sh index 0406b108b31..755e67280fa 100755 --- a/python/samba/tests/test_pam_winbind.sh +++ b/python/samba/tests/test_pam_winbind.sh @@ -12,6 +12,10 @@ PASSWORD="$3" export PASSWORD shift 3 +PAM_OPTIONS="$1" +export PAM_OPTIONS +shift 1 + PAM_WRAPPER_PATH="$BINDIR/default/third_party/pam_wrapper" pam_winbind="$BINDIR/shared/pam_winbind.so" @@ -19,10 +23,10 @@ service_dir="$SELFTEST_TMPDIR/pam_services" service_file="$service_dir/samba" mkdir $service_dir -echo "auth required $pam_winbind debug debug_state" > $service_file -echo "account required $pam_winbind debug debug_state" >> $service_file -echo "password required $pam_winbind debug debug_state" >> $service_file -echo "session required $pam_winbind debug debug_state" >> $service_file +echo "auth required $pam_winbind debug debug_state $PAM_OPTIONS" > $service_file +echo "account required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file +echo "password required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file +echo "session required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file PAM_WRAPPER="1" export PAM_WRAPPER diff --git a/python/samba/tests/test_pam_winbind_chauthtok.sh b/python/samba/tests/test_pam_winbind_chauthtok.sh index 5887699300a..48adc81859d 100755 --- a/python/samba/tests/test_pam_winbind_chauthtok.sh +++ b/python/samba/tests/test_pam_winbind_chauthtok.sh @@ -53,11 +53,11 @@ PAM_WRAPPER_DEBUGLEVEL=${PAM_WRAPPER_DEBUGLEVEL:="2"} export PAM_WRAPPER_DEBUGLEVEL case $PAM_OPTIONS in - use_authtok) + *use_authtok*) PAM_AUTHTOK="$NEWPASSWORD" export PAM_AUTHTOK ;; - try_authtok) + *try_authtok*) PAM_AUTHTOK="$NEWPASSWORD" export PAM_AUTHTOK ;; diff --git a/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh index 16dede44227..348d2ae8387 100755 --- a/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh +++ b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh @@ -12,6 +12,10 @@ PASSWORD="$3" export PASSWORD shift 3 +PAM_OPTIONS="$1" +export PAM_OPTIONS +shift 1 + PAM_WRAPPER_PATH="$BINDIR/default/third_party/pam_wrapper" pam_winbind="$BINDIR/shared/pam_winbind.so" @@ -37,10 +41,10 @@ export PAM_WRAPPER_DEBUGLEVEL WARN_PWD_EXPIRE="50" export WARN_PWD_EXPIRE -echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" > $service_file -echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file -echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file -echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file +echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" > $service_file +echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file +echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file +echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file PYTHONPATH="$PYTHONPATH:$PAM_WRAPPER_PATH:$(dirname $0)" $PYTHON -m samba.subunit.run samba.tests.pam_winbind_warn_pwd_expire exit_code=$? @@ -54,10 +58,10 @@ fi WARN_PWD_EXPIRE="0" export WARN_PWD_EXPIRE -echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" > $service_file -echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file -echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file -echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file +echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" > $service_file +echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file +echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file +echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file PYTHONPATH="$PYTHONPATH:$PAM_WRAPPER_PATH:$(dirname $0)" $PYTHON -m samba.subunit.run samba.tests.pam_winbind_warn_pwd_expire exit_code=$? diff --git a/selftest/tests.py b/selftest/tests.py index 7dbc0a9871f..507f7c3ea55 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -168,11 +168,11 @@ if with_pam: plantestsuite("samba.tests.pam_winbind(local)", "ad_member", [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), valgrindify(python), pam_wrapper_so_path, - "$SERVER", "$USERNAME", "$PASSWORD"]) + "$SERVER", "$USERNAME", "$PASSWORD", "''"]) plantestsuite("samba.tests.pam_winbind(domain)", "ad_member", [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), valgrindify(python), pam_wrapper_so_path, - "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD"]) + "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", "''"]) for pam_options in ["''", "use_authtok", "try_authtok"]: plantestsuite("samba.tests.pam_winbind_chauthtok with options %s" % pam_options, "ad_member", @@ -185,7 +185,7 @@ if with_pam: plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain)", "ad_member", [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), valgrindify(python), pam_wrapper_so_path, - "$DOMAIN", "alice", "Secret007"]) + "$DOMAIN", "alice", "Secret007", "''"]) plantestsuite("samba.unittests.krb5samba", "none", -- 2.24.1 From a1a34241a96e2dc2bb5a1157c51f8d7b85973b32 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 01:25:23 +0200 Subject: [PATCH 16/22] selftest/tests.py: prepare looping over pam_winbindd tests BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 72daf99fd1ffd8269fce25d69458de35e2ae32cc) --- selftest/tests.py | 58 ++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/selftest/tests.py b/selftest/tests.py index 507f7c3ea55..3224de493f9 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -165,27 +165,43 @@ planpythontestsuite("none", "samba.tests.tdb_util", py3_compatible=True) planpythontestsuite("none", "samba.tests.samdb_api", py3_compatible=True) if with_pam: - plantestsuite("samba.tests.pam_winbind(local)", "ad_member", - [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), - valgrindify(python), pam_wrapper_so_path, - "$SERVER", "$USERNAME", "$PASSWORD", "''"]) - plantestsuite("samba.tests.pam_winbind(domain)", "ad_member", - [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), - valgrindify(python), pam_wrapper_so_path, - "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", "''"]) - - for pam_options in ["''", "use_authtok", "try_authtok"]: - plantestsuite("samba.tests.pam_winbind_chauthtok with options %s" % pam_options, "ad_member", - [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_chauthtok.sh"), - valgrindify(python), pam_wrapper_so_path, pam_set_items_so_path, - "$DOMAIN", "TestPamOptionsUser", "oldp@ssword0", "newp@ssword0", - pam_options, 'yes', - "$DC_SERVER", "$DC_USERNAME", "$DC_PASSWORD"]) - - plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain)", "ad_member", - [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), - valgrindify(python), pam_wrapper_so_path, - "$DOMAIN", "alice", "Secret007", "''"]) + env = "ad_member" + options = [ + { + "description": "default", + "pam_options": "", + }, + ] + for o in options: + description = o["description"] + pam_options = "'%s'" % o["pam_options"] + + plantestsuite("samba.tests.pam_winbind(local+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "$SERVER", "$USERNAME", "$PASSWORD", + pam_options]) + plantestsuite("samba.tests.pam_winbind(domain+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", + pam_options]) + + for authtok_options in ["", "use_authtok", "try_authtok"]: + _pam_options = "'%s %s'" % (o["pam_options"], authtok_options) + _description = "%s %s" % (description, authtok_options) + plantestsuite("samba.tests.pam_winbind_chauthtok(domain+%s)" % _description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_chauthtok.sh"), + valgrindify(python), pam_wrapper_so_path, pam_set_items_so_path, + "$DOMAIN", "TestPamOptionsUser", "oldp@ssword0", "newp@ssword0", + _pam_options, 'yes', + "$DC_SERVER", "$DC_USERNAME", "$DC_PASSWORD"]) + + plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), + valgrindify(python), pam_wrapper_so_path, + "$DOMAIN", "alice", "Secret007", + pam_options]) plantestsuite("samba.unittests.krb5samba", "none", -- 2.24.1 From 71047f27e44dd9b3c7aaf421990199de408ee67b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 08:08:57 +0200 Subject: [PATCH 17/22] selftest/tests.py: test pam_winbind with krb5_auth BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit 36e95e42ea8a7e5a4091a647215d06d2ab47fab6) --- selftest/tests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selftest/tests.py b/selftest/tests.py index 3224de493f9..c2d94262c3c 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -167,6 +167,10 @@ planpythontestsuite("none", "samba.tests.samdb_api", py3_compatible=True) if with_pam: env = "ad_member" options = [ + { + "description": "krb5", + "pam_options": "krb5_auth krb5_ccache_type=FILE", + }, { "description": "default", "pam_options": "", -- 2.24.1 From 2262c07316a247aa20b306767af172c22e47d438 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 14:03:34 +0200 Subject: [PATCH 18/22] selftest/tests.py: test pam_winbind with a lot of username variations BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (cherry picked from commit f07b542c61f84a97c097208e10bf9375ddfa9a15) --- selftest/tests.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/selftest/tests.py b/selftest/tests.py index c2d94262c3c..c9529328359 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -185,11 +185,36 @@ if with_pam: valgrindify(python), pam_wrapper_so_path, "$SERVER", "$USERNAME", "$PASSWORD", pam_options]) - plantestsuite("samba.tests.pam_winbind(domain+%s)" % description, env, + plantestsuite("samba.tests.pam_winbind(domain1+%s)" % description, env, [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), valgrindify(python), pam_wrapper_so_path, "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", pam_options]) + plantestsuite("samba.tests.pam_winbind(domain2+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "$REALM", "$DC_USERNAME", "$DC_PASSWORD", + pam_options]) + plantestsuite("samba.tests.pam_winbind(domain3+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "''", "${DC_USERNAME}@${DOMAIN}", "$DC_PASSWORD", + pam_options]) + plantestsuite("samba.tests.pam_winbind(domain4+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "''", "${DC_USERNAME}@${REALM}", "$DC_PASSWORD", + pam_options]) + plantestsuite("samba.tests.pam_winbind(domain5+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "$REALM", "${DC_USERNAME}@${DOMAIN}", "$DC_PASSWORD", + pam_options]) + plantestsuite("samba.tests.pam_winbind(domain6+%s)" % description, env, + [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), + valgrindify(python), pam_wrapper_so_path, + "$DOMAIN", "${DC_USERNAME}@${REALM}", "$DC_PASSWORD", + pam_options]) for authtok_options in ["", "use_authtok", "try_authtok"]: _pam_options = "'%s %s'" % (o["pam_options"], authtok_options) -- 2.24.1 From 2ed154a74c10d77a1db4543e9c1b498875777a4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 08:02:38 +0200 Subject: [PATCH 19/22] selftest/Samba3.pm: use "winbind scan trusted domains = no" for ad_member This demonstrates that we rely on knowning about trusted domains before we can do krb5_auth in winbindd. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner (similar to commit e2737a74d4453a3d65e5466ddc4405d68444df27) --- selftest/target/Samba3.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 892a6a15e2d..751304d9166 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -412,6 +412,7 @@ sub setup_ad_member realm = $dcvars->{REALM} netbios aliases = foo bar template homedir = /home/%D/%G/%U + winbind scan trusted domains = no [sub_dug] path = $share_dir/D_%D/U_%U/G_%G -- 2.24.1 From 27a48944cfbfb2932558a799d5b9c057e0d4ea42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2019 08:10:26 +0200 Subject: [PATCH 20/22] selftest/Samba3.pm: use "winbind use krb5 enterprise principals = yes" for ad_member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This demonstrates that can do krb5_auth in winbindd without knowning about trusted domains. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner Autobuild-User(master): Günther Deschner Autobuild-Date(master): Tue Sep 24 19:51:29 UTC 2019 on sn-devel-184 (similar to commit 0ee085b594878f5e0e83839f465303754f015459) --- selftest/target/Samba3.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 751304d9166..89e75e54a91 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -413,6 +413,7 @@ sub setup_ad_member netbios aliases = foo bar template homedir = /home/%D/%G/%U winbind scan trusted domains = no + winbind use krb5 enterprise principals = yes [sub_dug] path = $share_dir/D_%D/U_%U/G_%G -- 2.24.1 From f70c0339b7e0f22351bdb2604504bf4f2c794544 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 9 Oct 2019 20:11:03 +0200 Subject: [PATCH 21/22] lib:krb5_wrap: Do not create a temporary file for MEMORY keytabs The autobuild cleanup script fails with: The tree has 3 new uncommitted files!!! git clean -n Would remove MEMORY:tmp_smb_creds_SK98Lv Would remove MEMORY:tmp_smb_creds_kornU6 Would remove MEMORY:tmp_smb_creds_ljR828 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit d888655244b4d8ec7a69a042e0ff3c074585b0de) (cherry picked from commit d533a588b62829688824824da681cb360a399651) --- lib/krb5_wrap/krb5_samba.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c index abdcb308728..6ce1d09952e 100644 --- a/lib/krb5_wrap/krb5_samba.c +++ b/lib/krb5_wrap/krb5_samba.c @@ -2002,21 +2002,21 @@ krb5_error_code smb_krb5_kinit_keyblock_ccache(krb5_context ctx, krb_options); #elif defined(HAVE_KRB5_GET_INIT_CREDS_KEYTAB) { -#define SMB_CREDS_KEYTAB "MEMORY:tmp_smb_creds_XXXXXX" - char tmp_name[sizeof(SMB_CREDS_KEYTAB)]; +#define SMB_CREDS_KEYTAB "MEMORY:tmp_kinit_keyblock_ccache" + char tmp_name[64] = {0}; krb5_keytab_entry entry; krb5_keytab keytab; - mode_t mask; + int rc; memset(&entry, 0, sizeof(entry)); entry.principal = principal; *(KRB5_KT_KEY(&entry)) = *keyblock; - memcpy(tmp_name, SMB_CREDS_KEYTAB, sizeof(SMB_CREDS_KEYTAB)); - mask = umask(S_IRWXO | S_IRWXG); - mktemp(tmp_name); - umask(mask); - if (tmp_name[0] == 0) { + rc = snprintf(tmp_name, sizeof(tmp_name), + "%s-%p", + SMB_CREDS_KEYTAB, + &my_creds); + if (rc < 0) { return KRB5_KT_BADNAME; } code = krb5_kt_resolve(ctx, tmp_name, &keytab); -- 2.24.1 From 496c7702401cdce4603bdb143742fdf59e614fdd Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 9 Oct 2019 16:32:47 +0200 Subject: [PATCH 22/22] s3:libads: Do not turn on canonicalization flag for MIT Kerberos This partially reverts 303b7e59a286896888ee2473995fc50bb2b5ce5e. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14155 Pair-Programmed-With: Isaac Boukris Signed-off-by: Andreas Schneider Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher (cherry picked from commit 123584294cfd153acc2d9a5be9d71c395c847a25) Autobuild-User(v4-10-test): Stefan Metzmacher Autobuild-Date(v4-10-test): Wed Oct 16 16:43:59 UTC 2019 on sn-devel-144 (cherry picked from commit 3ad42536f873f21cc2db774ca3ea694ca7142253) --- source3/libads/krb5_setpw.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 67bc2f4640d..028b0dcfa65 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -207,7 +207,22 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, krb5_get_init_creds_opt_set_win2k(context, opts, true); krb5_get_init_creds_opt_set_canonicalize(context, opts, true); #else /* MIT */ +#if 0 + /* + * FIXME + * + * Due to an upstream MIT Kerberos bug, this feature is not + * not working. Affection versions (2019-10-09): <= 1.17 + * + * Reproducer: + * kinit -C aDmInIsTrAtOr@ACME.COM -S kadmin/changepw@ACME.COM + * + * This is NOT a problem if the service is a krbtgt. + * + * https://bugzilla.samba.org/show_bug.cgi?id=14155 + */ krb5_get_init_creds_opt_set_canonicalize(opts, true); +#endif #endif /* MIT */ /* note that heimdal will fill in the local addresses if the addresses -- 2.24.1