From 06ec4526c2ec20f2db8b7193a27602bcbaf92458 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Sep 2016 15:04:49 -0700 Subject: [PATCH 1/4] s3: winbind: Make WBC_AUTH_USER_LEVEL_PAC prime the name2sid cache. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In addition to priming the netsamlogon cache. This prevents a winbind AD-DC lookup for something the PAC already told us. Note we only do this in the case where the PAC successfully passed signature verification. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 Signed-off-by: Jeremy Allison Reviewed-by: Günther Deschner (cherry picked from commit cf0f28819e771d433af00b3532011de70112b1f8) --- source3/winbindd/winbindd_pam.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 8ec4fe4..da874c7 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2568,7 +2568,15 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, } if (logon_info) { - /* Signature verification succeeded, trust the PAC */ + /* + * Signature verification succeeded, we can + * trust the PAC and prime the netsamlogon + * and name2sid caches. DO NOT DO THIS + * in the signature verification failed + * code path. + */ + struct winbindd_domain *domain = NULL; + result = create_info3_from_pac_logon_info(state->mem_ctx, logon_info, &info3_copy); @@ -2577,6 +2585,31 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, } netsamlogon_cache_store(NULL, info3_copy); + /* + * We're in the parent here, so find the child + * pointer from the PAC domain name. + */ + domain = find_domain_from_name_noinit( + info3_copy->base.logon_domain.string); + if (domain && domain->primary ) { + struct dom_sid user_sid; + + sid_compose(&user_sid, + info3_copy->base.domain_sid, + info3_copy->base.rid); + + cache_name2sid(domain, + info3_copy->base.logon_domain.string, + info3_copy->base.account_name.string, + SID_NAME_USER, + &user_sid); + + DBG_INFO("PAC for user %s\%s SID %s primed cache\n", + info3_copy->base.logon_domain.string, + info3_copy->base.account_name.string, + sid_string_dbg(&user_sid)); + } + } else { /* Try without signature verification */ result = kerberos_pac_logon_info(state->mem_ctx, pac_blob, NULL, -- 2.8.0.rc3.226.g39d4020 From 57df81c4e1f0f3540abac5e3d382bca89ec10bc2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 26 Sep 2016 17:07:44 -0700 Subject: [PATCH 2/4] s3: auth: Use wbcAuthenticateUserEx to prime the caches. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Idea by Volker - use WBC_AUTH_USER_LEVEL_PAC to pass the PAC to winbind from smbd on auth, this allows winbind to prime the user info via netsamlogon_cache_store() and the name2sid cache *before* smbd looks up the user. Note that as this is merely a cache prime having winbind not available is not an error. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 Signed-off-by: Jeremy Allison Reviewed-by: Günther Deschner Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Wed Sep 28 22:45:27 CEST 2016 on sn-devel-144 (cherry picked from commit ccfba2537d0ea081fbeeee0feecf8e2774850300) --- source3/auth/auth_generic.c | 49 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 74eb2fa..f9b9184 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -28,6 +28,7 @@ #include "lib/param/param.h" #ifdef HAVE_KRB5 #include "auth/kerberos/pac_utils.h" +#include "nsswitch/libwbclient/wbclient.h" #endif #include "librpc/crypto/gse.h" #include "auth/credentials/credentials.h" @@ -63,6 +64,51 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, if (pac_blob) { #ifdef HAVE_KRB5 + struct wbcAuthUserParams params = {}; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + wbcErr wbc_err; + + /* + * Let winbind decode the PAC. + * This will also store the user + * data in the netsamlogon cache. + * + * We need to do this *before* we + * call get_user_from_kerberos_info() + * as that does a user lookup that + * expects info in the netsamlogon cache. + * + * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 + */ + params.level = WBC_AUTH_USER_LEVEL_PAC; + params.password.pac.data = pac_blob->data; + params.password.pac.length = pac_blob->length; + + become_root(); + wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err); + unbecome_root(); + + /* + * As this is merely a cache prime + * WBC_ERR_WINBIND_NOT_AVAILABLE + * is not a fatal error, treat it + * as success. + */ + + switch (wbc_err) { + case WBC_ERR_WINBIND_NOT_AVAILABLE: + case WBC_ERR_SUCCESS: + break; + case WBC_ERR_AUTH_ERROR: + status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + goto done; + default: + status = NT_STATUS_LOGON_FAILURE; + goto done; + } + status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, NULL, NULL, 0, &logon_info); #else @@ -101,7 +147,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, goto done; } - /* save the PAC data if we have it */ + /* Get the info3 from the PAC data if we have it */ if (logon_info) { status = create_info3_from_pac_logon_info(tmp_ctx, logon_info, @@ -109,7 +155,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, if (!NT_STATUS_IS_OK(status)) { goto done; } - netsamlogon_cache_store(ntuser, info3_copy); } /* setup the string used by %U */ -- 2.8.0.rc3.226.g39d4020 From fab2397bb4c101201d899692cef7b38135db431e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Sep 2016 10:12:36 -0700 Subject: [PATCH 3/4] s3: winbind: refresh_sequence_number is only ever called with 'false'. Remove redundant parameter. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 Signed-off-by: Jeremy Allison Reviewed-by: Ira Cooper Reviewed-by: Guenther Deschner (cherry picked from commit 32ae6721cf02412af3c5a82d5da4806f4d931bcd) --- source3/winbindd/winbindd_cache.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index b2c0ae2..0cb0ca2 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -509,11 +509,10 @@ static bool store_cache_seqnum( struct winbindd_domain *domain ) } /* - refresh the domain sequence number. If force is true - then always refresh it, no matter how recently we fetched it + refresh the domain sequence number on timeout. */ -static void refresh_sequence_number(struct winbindd_domain *domain, bool force) +static void refresh_sequence_number(struct winbindd_domain *domain) { NTSTATUS status; unsigned time_diff; @@ -536,7 +535,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, bool force) time_diff = t - domain->last_seq_check; /* see if we have to refetch the domain sequence number */ - if (!force && (time_diff < cache_time) && + if ((time_diff < cache_time) && (domain->sequence_number != DOM_SEQUENCE_NONE) && NT_STATUS_IS_OK(domain->last_status)) { DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name)); @@ -710,7 +709,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache, return NULL; } - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); va_start(ap, format); smb_xvasprintf(&kstr, format, ap); @@ -1558,7 +1557,7 @@ do_query: (retry++ < 5)); /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1670,7 +1669,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1775,7 +1774,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1890,7 +1889,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (domain->online && (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))) { @@ -2004,7 +2003,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2229,7 +2228,7 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain, return result; } - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); for (i=0; isequence_number; @@ -2998,7 +2997,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3070,7 +3069,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3335,7 +3334,7 @@ void cache_name2sid(struct winbindd_domain *domain, const char *domain_name, const char *name, enum lsa_SidType type, const struct dom_sid *sid) { - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); wcache_save_name_to_sid(domain, NT_STATUS_OK, domain_name, name, sid, type); } -- 2.8.0.rc3.226.g39d4020 From f9c70c323af208b0eee59cc32158fa465f2616fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Sep 2016 11:26:04 -0700 Subject: [PATCH 4/4] s3: winbind: Trust name2sid mappings from the PAC. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't refresh sequence number in parent as the mapping comes from a trusted DC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259 Signed-off-by: Jeremy Allison Reviewed-by: Günther Deschner (cherry picked from commit 1017b22f68e798a080e0738d3beecf008b2284ef) --- source3/winbindd/winbindd_cache.c | 19 +++++++++++++++++++ source3/winbindd/winbindd_pam.c | 2 +- source3/winbindd/winbindd_proto.h | 5 +++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 0cb0ca2..cd1b578 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -3330,6 +3330,25 @@ bool lookup_cached_name(const char *domain_name, return NT_STATUS_IS_OK(status); } +/* + * Cache a name to sid without checking the sequence number. + * Used when caching from a trusted PAC. + */ + +void cache_name2sid_trusted(struct winbindd_domain *domain, + const char *domain_name, + const char *name, + enum lsa_SidType type, + const struct dom_sid *sid) +{ + wcache_save_name_to_sid(domain, + NT_STATUS_OK, + domain_name, + name, + sid, + type); +} + void cache_name2sid(struct winbindd_domain *domain, const char *domain_name, const char *name, enum lsa_SidType type, const struct dom_sid *sid) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index da874c7..8456876 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2598,7 +2598,7 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, info3_copy->base.domain_sid, info3_copy->base.rid); - cache_name2sid(domain, + cache_name2sid_trusted(domain, info3_copy->base.logon_domain.string, info3_copy->base.account_name.string, SID_NAME_USER, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 4d99927..5e3d9fb 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -86,6 +86,11 @@ bool lookup_cached_name(const char *domain_name, const char *name, struct dom_sid *sid, enum lsa_SidType *type); +void cache_name2sid_trusted(struct winbindd_domain *domain, + const char *domain_name, + const char *name, + enum lsa_SidType type, + const struct dom_sid *sid); void cache_name2sid(struct winbindd_domain *domain, const char *domain_name, const char *name, enum lsa_SidType type, const struct dom_sid *sid); -- 2.8.0.rc3.226.g39d4020