From 7b9c156bdd35095c4d6a6fd61f42a5185f92c7df Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Mar 2018 20:44:31 +1300 Subject: [PATCH 1/3] winbindd: Do re-connect if the RPC call fails in the passdb case This is very, very unlikely but possible as in the AD case the RPC server is in another process that may eventually be able to restart. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13349 Signed-off-by: Andrew Bartlett --- source3/winbindd/winbindd_samr.c | 309 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 308 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index 68064d725a2..70e07fa30a6 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -28,6 +28,7 @@ #include "winbindd_rpc.h" #include "lib/util_unixsids.h" #include "rpc_client/rpc_client.h" +#include "rpc_client/cli_pipe.h" #include "../librpc/gen_ndr/ndr_samr_c.h" #include "rpc_client/cli_samr.h" #include "../librpc/gen_ndr/ndr_lsa_c.h" @@ -223,6 +224,29 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, &dom_pol, &num_info, &info); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(tmp_ctx); + return status; + } + + status = rpc_enum_dom_groups(tmp_ctx, + samr_pipe, + &dom_pol, + &num_info, + &info); + } + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(tmp_ctx); return status; @@ -272,6 +296,28 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, &dom_pol, &domain->sid, &rids); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_query_user_list(tmp_ctx, + samr_pipe, + &dom_pol, + &domain->sid, + &rids); + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -323,6 +369,27 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, &lsa_policy, &num_trusts, &trusts); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(lsa_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_trusted_domains(tmp_ctx, + lsa_pipe, + &lsa_policy, + &num_trusts, + &trusts); + } if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -396,6 +463,34 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, &names, &name_types); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_lookup_groupmem(tmp_ctx, + samr_pipe, + &dom_pol, + domain->name, + &domain->sid, + group_sid, + type, + &num_names, + &sid_mem, + &names, + &name_types); + } + if (pnum_names) { *pnum_names = num_names; } @@ -494,6 +589,28 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, &dom_pol, &num_info, &info); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_enum_local_groups(mem_ctx, + samr_pipe, + &dom_pol, + &num_info, + &info); + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -551,6 +668,30 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, flags, &sid, &type); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(lsa_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_name_to_sid(tmp_ctx, + lsa_pipe, + &lsa_policy, + domain_name, + name, + flags, + &sid, + &type); + } if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -622,7 +763,32 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, &domain_name, &name, &type); - + + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(lsa_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_sid_to_name(tmp_ctx, + lsa_pipe, + &lsa_policy, + domain, + sid, + &domain_name, + &name, + &type); + } + if (ptype) { *ptype = type; } @@ -695,6 +861,32 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, &domain_name, &names, &types); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(lsa_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_rids_to_names(tmp_ctx, + lsa_pipe, + &lsa_policy, + domain, + domain_sid, + rids, + num_rids, + &domain_name, + &names, + &types); + } if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -751,6 +943,28 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, DomainLockoutInformation, &info, &result); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto error; + } + + status = dcerpc_samr_QueryDomainInfo(b, + mem_ctx, + &dom_pol, + DomainLockoutInformation, + &info, + &result); + } if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -801,6 +1015,29 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, DomainPasswordInformation, &info, &result); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto error; + } + + status = dcerpc_samr_QueryDomainInfo(b, + mem_ctx, + &dom_pol, + DomainPasswordInformation, + &info, + &result); + } + if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -859,6 +1096,30 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, user_sid, &num_groups, &user_grpsids); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_lookup_usergroups(tmp_ctx, + samr_pipe, + &dom_pol, + &domain->sid, + user_sid, + &num_groups, + &user_grpsids); + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -918,6 +1179,30 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, sids, &num_aliases, &alias_rids); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_lookup_useraliases(tmp_ctx, + samr_pipe, + &dom_pol, + num_sids, + sids, + &num_aliases, + &alias_rids); + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -971,6 +1256,28 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, &dom_pol, domain->name, &seq); + /* + * Very unlikely, but before checking the result, + * if we disconnected try again + */ + if (!rpccli_is_connected(samr_pipe)) { + TALLOC_FREE(domain->private_data); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_sequence_number(tmp_ctx, + samr_pipe, + &dom_pol, + domain->name, + &seq); + } + if (!NT_STATUS_IS_OK(status)) { goto done; } -- 2.11.0 From b75cb0400e79898dedf6d6999c4ef41a53642b33 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Mar 2018 21:23:13 +1300 Subject: [PATCH 2/3] winbindd: Use talloc_zero_array for consistency with other winbindd_domain allocators The other allocator for this structure uses talloc_zero() BUG: https://bugzilla.samba.org/show_bug.cgi?id=13349 Signed-off-by: Andrew Bartlett --- source3/winbindd/wb_seqnums.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/wb_seqnums.c b/source3/winbindd/wb_seqnums.c index 2a4cdc930e8..3c9af01e40f 100644 --- a/source3/winbindd/wb_seqnums.c +++ b/source3/winbindd/wb_seqnums.c @@ -56,8 +56,8 @@ struct tevent_req *wb_seqnums_send(TALLOC_CTX *mem_ctx, state->subreqs = talloc_array(state, struct tevent_req *, state->num_domains); - state->domains = talloc_array(state, struct winbindd_domain *, - state->num_domains); + state->domains = talloc_zero_array(state, struct winbindd_domain *, + state->num_domains); state->stati = talloc_array(state, NTSTATUS, state->num_domains); state->seqnums = talloc_array(state, uint32_t, state->num_domains); -- 2.11.0 From 04a94b8eb209e254af28be06a2d85dd5be988a03 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 21 Mar 2018 20:25:09 +0100 Subject: [PATCH 3/3] s3:lib: Fix probably a copy&paste error in namemap_cache_set_sid2name() BUG: https://bugzilla.samba.org/show_bug.cgi?id=13350 Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- source3/lib/namemap_cache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/lib/namemap_cache.c b/source3/lib/namemap_cache.c index 0d6ed32abc5..38f7a2ddc88 100644 --- a/source3/lib/namemap_cache.c +++ b/source3/lib/namemap_cache.c @@ -53,7 +53,6 @@ bool namemap_cache_set_sid2name(const struct dom_sid *sid, } snprintf(typebuf, sizeof(typebuf), "%d", (int)type); - snprintf(keybuf, sizeof(keybuf), "SID2NAME/%s", sidbuf); ret = strv_add(talloc_tos(), &val, domain); if (ret != 0) { -- 2.11.0