From a73697116f5b65dc0182e16c2f7bdb0b03dccc75 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 10:58:52 +0100 Subject: [PATCH 1/8] s3: user_domain is not used in wb_getpwsid --- source3/winbindd/wb_getpwsid.c | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diff --git a/source3/winbindd/wb_getpwsid.c b/source3/winbindd/wb_getpwsid.c index 4ccc51a..807ae3d 100644 --- a/source3/winbindd/wb_getpwsid.c +++ b/source3/winbindd/wb_getpwsid.c @@ -22,7 +22,6 @@ #include "librpc/gen_ndr/cli_wbint.h" struct wb_getpwsid_state { - struct winbindd_domain *user_domain; struct tevent_context *ev; struct dom_sid sid; struct wbint_userinfo *userinfo; @@ -49,12 +48,6 @@ struct tevent_req *wb_getpwsid_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->pw = pw; - state->user_domain = find_domain_from_sid_noinit(user_sid); - if (state->user_domain == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - subreq = wb_queryuser_send(state, ev, &state->sid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); -- 1.7.3.4 From 439bbcc224c6974fecdb7c59bfab4dc57b1d3a94 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 11:12:11 +0100 Subject: [PATCH 2/8] s3: Do wb_queryuser out of the netsamlogon_cache if possible --- source3/winbindd/wb_queryuser.c | 33 ++++++++++++++++++++++++++++----- 1 files changed, 28 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c index d85af78..1cf6070 100644 --- a/source3/winbindd/wb_queryuser.c +++ b/source3/winbindd/wb_queryuser.c @@ -35,6 +35,7 @@ struct tevent_req *wb_queryuser_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct wb_queryuser_state *state; struct winbindd_domain *domain; + struct netr_SamInfo3 *info3; req = tevent_req_create(mem_ctx, &state, struct wb_queryuser_state); if (req == NULL) { @@ -42,14 +43,36 @@ struct tevent_req *wb_queryuser_send(TALLOC_CTX *mem_ctx, } sid_copy(&state->sid, user_sid); - domain = find_domain_from_sid_noinit(user_sid); - if (domain == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + state->info = talloc(state, struct wbint_userinfo); + if (tevent_req_nomem(state->info, req)) { return tevent_req_post(req, ev); } - state->info = talloc(state, struct wbint_userinfo); - if (tevent_req_nomem(state->info, req)) { + info3 = netsamlogon_cache_get(talloc_tos(), user_sid); + if (info3 != NULL) { + struct dom_sid domain_sid; + sid_copy(&domain_sid, user_sid); + sid_split_rid(&domain_sid, NULL); + + sid_copy(&state->info->user_sid, user_sid); + sid_compose(&state->info->group_sid, &domain_sid, + info3->base.primary_gid); + state->info->acct_name = talloc_strdup( + state->info, info3->base.account_name.string); + state->info->full_name = talloc_strdup( + state->info, info3->base.full_name.string); + state->info->homedir = talloc_strdup( + state->info, ""); + state->info->shell = talloc_strdup( + state->info, "/bin/false"); + TALLOC_FREE(info3); + tevent_req_done(req); + return tevent_req_post(req, ev); + } + + domain = find_domain_from_sid_noinit(user_sid); + if (domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); return tevent_req_post(req, ev); } -- 1.7.3.4 From a14ca8c3d2bf190781a8c6f86567adb1ad4d42fa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 11:16:23 +0100 Subject: [PATCH 3/8] s3: Allow rid==NULL in sid_split_rid --- source3/lib/util_sid.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index bea04d8..d9c778d 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -311,7 +311,9 @@ bool sid_split_rid(DOM_SID *sid, uint32 *rid) { if (sid->num_auths > 0) { sid->num_auths--; - *rid = sid->sub_auths[sid->num_auths]; + if (rid != NULL) { + *rid = sid->sub_auths[sid->num_auths]; + } return True; } return False; -- 1.7.3.4 From 673fbe1c84e08e7190b1123124648837468b108d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 11:31:01 +0100 Subject: [PATCH 4/8] s3: Move domain lookup to wb_lookupusergroups --- source3/winbindd/wb_gettoken.c | 18 +----------------- source3/winbindd/wb_lookupusergroups.c | 17 ++++++++++++++++- source3/winbindd/winbindd_getuserdomgroups.c | 11 +---------- source3/winbindd/winbindd_proto.h | 1 - 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/source3/winbindd/wb_gettoken.c b/source3/winbindd/wb_gettoken.c index f2fbe4c..623c78e 100644 --- a/source3/winbindd/wb_gettoken.c +++ b/source3/winbindd/wb_gettoken.c @@ -43,7 +43,6 @@ struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct wb_gettoken_state *state; - struct winbindd_domain *domain; req = tevent_req_create(mem_ctx, &state, struct wb_gettoken_state); if (req == NULL) { @@ -52,22 +51,7 @@ struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx, sid_copy(&state->usersid, sid); state->ev = ev; - domain = find_domain_from_sid_noinit(sid); - if (domain == NULL) { - DEBUG(5, ("Could not find domain from SID %s\n", - sid_string_dbg(sid))); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - - if (lp_winbind_trusted_domains_only() && domain->primary) { - DEBUG(7, ("wb_gettoken: My domain -- rejecting getgroups() " - "for %s.\n", sid_string_tos(sid))); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - - subreq = wb_lookupusergroups_send(state, ev, domain, &state->usersid); + subreq = wb_lookupusergroups_send(state, ev, &state->usersid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } diff --git a/source3/winbindd/wb_lookupusergroups.c b/source3/winbindd/wb_lookupusergroups.c index 99c75b6..9d8017b 100644 --- a/source3/winbindd/wb_lookupusergroups.c +++ b/source3/winbindd/wb_lookupusergroups.c @@ -31,11 +31,11 @@ static void wb_lookupusergroups_done(struct tevent_req *subreq); struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct winbindd_domain *domain, const struct dom_sid *sid) { struct tevent_req *req, *subreq; struct wb_lookupusergroups_state *state; + struct winbindd_domain *domain; req = tevent_req_create(mem_ctx, &state, struct wb_lookupusergroups_state); @@ -44,6 +44,21 @@ struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx, } sid_copy(&state->sid, sid); + domain = find_domain_from_sid_noinit(&state->sid); + if (domain == NULL) { + DEBUG(1, ("could not find domain entry for sid %s\n", + sid_string_tos(sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); + return tevent_req_post(req, ev); + } + + if (lp_winbind_trusted_domains_only() && domain->primary) { + DEBUG(7, ("wb_gettoken: My domain -- rejecting getgroups() " + "for %s.\n", sid_string_tos(sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return tevent_req_post(req, ev); + } + subreq = rpccli_wbint_LookupUserGroups_send( state, ev, domain->child.rpccli, &state->sid, &state->sids); if (tevent_req_nomem(subreq, req)) { diff --git a/source3/winbindd/winbindd_getuserdomgroups.c b/source3/winbindd/winbindd_getuserdomgroups.c index 0bba024..3abb5b1 100644 --- a/source3/winbindd/winbindd_getuserdomgroups.c +++ b/source3/winbindd/winbindd_getuserdomgroups.c @@ -35,7 +35,6 @@ struct tevent_req *winbindd_getuserdomgroups_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct winbindd_getuserdomgroups_state *state; - struct winbindd_domain *domain; req = tevent_req_create(mem_ctx, &state, struct winbindd_getuserdomgroups_state); @@ -55,15 +54,7 @@ struct tevent_req *winbindd_getuserdomgroups_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - domain = find_domain_from_sid_noinit(&state->sid); - if (domain == NULL) { - DEBUG(1,("could not find domain entry for sid %s\n", - request->data.sid)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); - return tevent_req_post(req, ev); - } - - subreq = wb_lookupusergroups_send(state, ev, domain, &state->sid); + subreq = wb_lookupusergroups_send(state, ev, &state->sid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 62fbc8e..28bcf56 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -636,7 +636,6 @@ NTSTATUS winbindd_getsidaliases_recv(struct tevent_req *req, struct winbindd_response *response); struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct winbindd_domain *domain, const struct dom_sid *sid); NTSTATUS wb_lookupusergroups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *num_sids, struct dom_sid **sids); -- 1.7.3.4 From 7048e3e583a52b8cd8471440c637a8919010f499 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 11:38:42 +0100 Subject: [PATCH 5/8] s3: Attempt lookup_usergroups_cached in wb_lookupusergroups --- source3/winbindd/wb_lookupusergroups.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/source3/winbindd/wb_lookupusergroups.c b/source3/winbindd/wb_lookupusergroups.c index 9d8017b..e42b6e5 100644 --- a/source3/winbindd/wb_lookupusergroups.c +++ b/source3/winbindd/wb_lookupusergroups.c @@ -36,6 +36,7 @@ struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct wb_lookupusergroups_state *state; struct winbindd_domain *domain; + NTSTATUS status; req = tevent_req_create(mem_ctx, &state, struct wb_lookupusergroups_state); @@ -44,6 +45,14 @@ struct tevent_req *wb_lookupusergroups_send(TALLOC_CTX *mem_ctx, } sid_copy(&state->sid, sid); + status = lookup_usergroups_cached(NULL, state, &state->sid, + &state->sids.num_sids, + &state->sids.sids); + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + return tevent_req_post(req, ev); + } + domain = find_domain_from_sid_noinit(&state->sid); if (domain == NULL) { DEBUG(1, ("could not find domain entry for sid %s\n", -- 1.7.3.4 From 523649fc5f4709156d453dba17208cc82a08e423 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 15:09:37 +0100 Subject: [PATCH 6/8] s3: Try the netsamlogon_cache in wb_fill_pwent --- source3/winbindd/wb_fill_pwent.c | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-) diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c index 8998bf9..c98d089 100644 --- a/source3/winbindd/wb_fill_pwent.c +++ b/source3/winbindd/wb_fill_pwent.c @@ -91,7 +91,7 @@ static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) struct wb_fill_pwent_state *state = tevent_req_data( req, struct wb_fill_pwent_state); struct winbindd_domain *domain; - char *dom_name; + char *dom_name = NULL; fstring user_name, output_username; char *mapped_name = NULL; NTSTATUS status; @@ -104,17 +104,37 @@ static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) } domain = find_domain_from_sid_noinit(&state->info->user_sid); - if (domain == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return; + if (domain != NULL) { + dom_name = domain->name; + } else { + struct netr_SamInfo3 *info3 = NULL; + + info3 = netsamlogon_cache_get( + talloc_tos(), &state->info->user_sid); + if (info3 == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return; + } + + dom_name = talloc_strdup( + state, info3->base.domain.string); + if (tevent_req_nomem(dom_name, req)) { + return; + } + TALLOC_FREE(info3); } - dom_name = domain->name; /* Username */ fstrcpy(user_name, state->info->acct_name); strlower_m(user_name); - status = normalize_name_map(state, domain, user_name, &mapped_name); + + if (domain != NULL) { + status = normalize_name_map(state, domain, user_name, + &mapped_name); + } else { + status = NT_STATUS_NONE_MAPPED; + } /* Basic removal of whitespace */ if (NT_STATUS_IS_OK(status)) { -- 1.7.3.4 From 9e33c90ffc7c38e5b4d9fbbcbbb3832ef287dc4a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Nov 2011 10:11:02 +0100 Subject: [PATCH 7/8] s3: Apply some const --- source3/include/proto.h | 4 ++-- source3/libsmb/trustdom_cache.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 579fc1b..f278c01 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3331,8 +3331,8 @@ WERROR map_werror_from_unix(int error); bool trustdom_cache_enable(void); bool trustdom_cache_shutdown(void); -bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, - time_t timeout); +bool trustdom_cache_store(const char *name, const char *alt_name, + const DOM_SID *sid, time_t timeout); bool trustdom_cache_fetch(const char* name, DOM_SID* sid); uint32 trustdom_cache_fetch_timestamp( void ); bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index eb52b35..63a4544 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -95,8 +95,8 @@ static char* trustdom_cache_key(const char* name) * false if store attempt failed **/ -bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, - time_t timeout) +bool trustdom_cache_store(const char *name, const char *alt_name, + const DOM_SID *sid, time_t timeout) { char *key, *alt_key; fstring sid_string; -- 1.7.3.4 From 7be26e24170db0763b7ffc08d5d24167ab27a6eb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Nov 2011 21:42:11 +0100 Subject: [PATCH 8/8] s3: Make sure that we get domain_info for authenticated users Without this, if winbind does not know about a trust, make_user_info_map will map any legitimate authentication request to the local sam, even if our DC could have authenticated it via weird trust paths. --- source3/auth/auth_domain.c | 4 ++++ source3/smbd/sesssetup.c | 4 ++++ source3/winbindd/winbindd_creds.c | 4 ++++ source3/winbindd/winbindd_misc.c | 10 ++++++++++ source3/winbindd/winbindd_pam.c | 8 ++++++++ 5 files changed, 30 insertions(+), 0 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 9677ce7..08fd5c6 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -355,6 +355,10 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, } netsamlogon_cache_store(user_info->smb_name, info3); + trustdom_cache_store( + info3->base.domain.string, "", + info3->base.domain_sid, + time(NULL) + 600); TALLOC_FREE(info3); } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0de5a4b..48ef8f5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -355,6 +355,10 @@ static void reply_spnego_kerberos(struct smb_request *req, logon_info = get_logon_info_from_pac(pac_data); if (logon_info) { netsamlogon_cache_store( client, &logon_info->info3 ); + trustdom_cache_store( + logon_info->info3.base.domain.string, "", + logon_info->info3.base.domain_sid, + time(NULL) + 600); } } diff --git a/source3/winbindd/winbindd_creds.c b/source3/winbindd/winbindd_creds.c index 98a16ee..b70172d 100644 --- a/source3/winbindd/winbindd_creds.c +++ b/source3/winbindd/winbindd_creds.c @@ -130,6 +130,10 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, if (!netsamlogon_cache_store(user, info3)) { return NT_STATUS_ACCESS_DENIED; } + trustdom_cache_store( + info3->base.domain.string, "", + info3->base.domain_sid, + time(NULL) + 600); } return NT_STATUS_OK; diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index ac8f1a7..9c9ad9f 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -246,8 +246,18 @@ void winbindd_domain_info(struct winbindd_cli_state *cli) domain = find_domain_from_name_noinit(cli->request->domain_name); if (domain == NULL) { + struct dom_sid sid; DEBUG(3, ("Did not find domain [%s]\n", cli->request->domain_name)); + if (trustdom_cache_fetch(cli->request->domain_name, + &sid)) { + fstrcpy(cli->response->data.domain_info.name, + cli->request->domain_name); + sid_to_fstring(cli->response->data.domain_info.sid, + &sid); + request_ok(cli); + return; + } request_error(cli); return; } diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 5c56b87..a1dd3d0 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1691,6 +1691,10 @@ process_result: wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3); netsamlogon_cache_store(name_user, info3); + trustdom_cache_store( + info3->base.domain.string, "", + info3->base.domain_sid, + time(NULL) + 600); /* save name_to_sid info as early as possible (only if this is our primary domain so we don't invalidate @@ -2078,6 +2082,10 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3); netsamlogon_cache_store(name_user, info3); + trustdom_cache_store( + info3->base.domain.string, "", + info3->base.domain_sid, + time(NULL) + 600); /* Check if the user is in the right group */ -- 1.7.3.4