From 2d455e28ab10ad77c601b0b451d503aea594fee1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Mar 2018 20:43:10 +1300 Subject: [PATCH 1/2] winbindd: Add a cache of the samr and lsa handles for the passdb domain This domain is very close, in AD DC configurations over a internal ncacn_np pipe and otherwise in the same process via C linking. It is however very expensive to re-create the binding handle per SID->name lookup, so keep a cache. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13430 Signed-off-by: Andrew Bartlett Reviewed-by: Ralph Boehme (cherry picked from commit d418d0ca33afb41a793a2fff19ca68871aa5e9ef) --- source3/winbindd/winbindd_samr.c | 267 +++++++++++++++++++++++---------------- 1 file changed, 159 insertions(+), 108 deletions(-) diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index aedb77bdee9..da54d697909 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -40,6 +40,20 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND +/* + * The other end of this won't go away easily, so we can trust it + * + * It is either a long-lived process with the same lifetime as + * winbindd or a part of this process + */ +struct winbind_internal_pipes { + struct rpc_pipe_client *samr_pipe; + struct policy_handle samr_domain_hnd; + struct rpc_pipe_client *lsa_pipe; + struct policy_handle lsa_hnd; +}; + + NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct rpc_pipe_client **samr_pipe, @@ -101,6 +115,70 @@ NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx, return status; } + +static NTSTATUS open_cached_internal_pipe_conn( + struct winbindd_domain *domain, + struct rpc_pipe_client **samr_pipe, + struct policy_handle *samr_domain_hnd, + struct rpc_pipe_client **lsa_pipe, + struct policy_handle *lsa_hnd) +{ + struct winbind_internal_pipes *internal_pipes = NULL; + + if (domain->private_data == NULL) { + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + + internal_pipes = talloc_zero(frame, + struct winbind_internal_pipes); + + status = open_internal_samr_conn( + internal_pipes, + domain, + &internal_pipes->samr_pipe, + &internal_pipes->samr_domain_hnd); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + status = open_internal_lsa_conn(internal_pipes, + &internal_pipes->lsa_pipe, + &internal_pipes->lsa_hnd); + + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + domain->private_data = talloc_move(domain, &internal_pipes); + + TALLOC_FREE(frame); + + } + + internal_pipes = talloc_get_type_abort( + domain->private_data, struct winbind_internal_pipes); + + if (samr_domain_hnd) { + *samr_domain_hnd = internal_pipes->samr_domain_hnd; + } + + if (samr_pipe) { + *samr_pipe = internal_pipes->samr_pipe; + } + + if (lsa_hnd) { + *lsa_hnd = internal_pipes->lsa_hnd; + } + + if (lsa_pipe) { + *lsa_pipe = internal_pipes->lsa_pipe; + } + + return NT_STATUS_OK; +} + /********************************************************************* SAM specific functions. *********************************************************************/ @@ -116,8 +194,7 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, struct wb_acct_info *info = NULL; uint32_t num_info = 0; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_enum_dom_groups\n")); @@ -130,20 +207,24 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { - goto error; + TALLOC_FREE(tmp_ctx); + return status; } - b = samr_pipe->binding_handle; - status = rpc_enum_dom_groups(tmp_ctx, samr_pipe, &dom_pol, &num_info, &info); if (!NT_STATUS_IS_OK(status)) { - goto error; + TALLOC_FREE(tmp_ctx); + return status; } if (pnum_info) { @@ -154,10 +235,6 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, *pinfo = talloc_move(mem_ctx, &info); } -error: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } TALLOC_FREE(tmp_ctx); return status; } @@ -171,8 +248,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, struct policy_handle dom_pol = { 0 }; uint32_t *rids = NULL; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("samr_query_user_list\n")); @@ -181,13 +257,15 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_query_user_list(tmp_ctx, samr_pipe, &dom_pol, @@ -202,10 +280,6 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } - TALLOC_FREE(rids); TALLOC_FREE(tmp_ctx); return status; @@ -221,8 +295,7 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, struct netr_DomainTrust *trusts = NULL; uint32_t num_trusts = 0; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("samr: trusted domains\n")); @@ -235,13 +308,15 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = lsa_pipe->binding_handle; - status = rpc_trusted_domains(tmp_ctx, lsa_pipe, &lsa_policy, @@ -257,10 +332,6 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&lsa_policy)) { - dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -284,8 +355,7 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, uint32_t *name_types = NULL; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_lookup_groupmem\n")); @@ -304,13 +374,15 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_lookup_groupmem(tmp_ctx, samr_pipe, &dom_pol, @@ -340,10 +412,6 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -398,8 +466,7 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, struct wb_acct_info *info = NULL; uint32_t num_info = 0; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("samr: enum local groups\n")); @@ -412,13 +479,15 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_enum_local_groups(mem_ctx, samr_pipe, &dom_pol, @@ -437,10 +506,6 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -459,8 +524,7 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, struct dom_sid sid; enum lsa_SidType type; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_name_to_sid\n")); @@ -469,13 +533,15 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = lsa_pipe->binding_handle; - status = rpc_name_to_sid(tmp_ctx, lsa_pipe, &lsa_policy, @@ -496,10 +562,6 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&lsa_policy)) { - dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -518,8 +580,7 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, char *name = NULL; enum lsa_SidType type; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_sid_to_name\n")); @@ -543,13 +604,15 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = lsa_pipe->binding_handle; - status = rpc_sid_to_name(tmp_ctx, lsa_pipe, &lsa_policy, @@ -572,9 +635,6 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&lsa_policy)) { - dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result); - } TALLOC_FREE(tmp_ctx); return status; @@ -595,8 +655,7 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, char *domain_name = NULL; char **names = NULL; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_rids_to_names for %s\n", domain->name)); @@ -616,13 +675,15 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy); + status = open_cached_internal_pipe_conn(domain, + NULL, + NULL, + &lsa_pipe, + &lsa_policy); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = lsa_pipe->binding_handle; - status = rpc_rids_to_names(tmp_ctx, lsa_pipe, &lsa_policy, @@ -650,10 +711,6 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&lsa_policy)) { - dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -676,7 +733,11 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -700,10 +761,6 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, *lockout_policy = info->info12; error: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -726,7 +783,11 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -750,10 +811,6 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, *passwd_policy = info->info1; error: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } - TALLOC_FREE(tmp_ctx); return status; } @@ -770,8 +827,7 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, struct dom_sid *user_grpsids = NULL; uint32_t num_groups = 0; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_lookup_usergroups\n")); @@ -786,13 +842,15 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_lookup_usergroups(tmp_ctx, samr_pipe, &dom_pol, @@ -813,9 +871,6 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } TALLOC_FREE(tmp_ctx); return status; @@ -833,8 +888,7 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, uint32_t num_aliases = 0; uint32_t *alias_rids = NULL; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("sam_lookup_useraliases\n")); @@ -847,13 +901,15 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_lookup_useraliases(tmp_ctx, samr_pipe, &dom_pol, @@ -874,9 +930,6 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, } done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result); - } TALLOC_FREE(tmp_ctx); return status; @@ -890,8 +943,7 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, struct policy_handle dom_pol = { 0 }; uint32_t seq = DOM_SEQUENCE_NONE; TALLOC_CTX *tmp_ctx; - NTSTATUS status, result; - struct dcerpc_binding_handle *b = NULL; + NTSTATUS status; DEBUG(3,("samr: sequence number\n")); @@ -904,13 +956,15 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } - status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol); + status = open_cached_internal_pipe_conn(domain, + &samr_pipe, + &dom_pol, + NULL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } - b = samr_pipe->binding_handle; - status = rpc_sequence_number(tmp_ctx, samr_pipe, &dom_pol, @@ -923,11 +977,8 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, if (pseq) { *pseq = seq; } -done: - if (b && is_valid_policy_hnd(&dom_pol)) { - dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result); - } +done: TALLOC_FREE(tmp_ctx); return status; } -- 2.14.3 From 89c81e65f05fb0fd66a576b12613ccc8281ef72d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Mar 2018 20:44:31 +1300 Subject: [PATCH 2/2] 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=13430 Signed-off-by: Andrew Bartlett Reviewed-by: Ralph Boehme (cherry picked from commit fc9150dcab231fe9beb72e198b0c2742d5f2505f) --- source3/winbindd/winbindd_samr.c | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index da54d697909..31720d54997 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" @@ -179,6 +180,32 @@ static NTSTATUS open_cached_internal_pipe_conn( return NT_STATUS_OK; } +static bool reset_connection_on_error(struct winbindd_domain *domain, + struct rpc_pipe_client *p, + NTSTATUS status) +{ + struct winbind_internal_pipes *internal_pipes = NULL; + + internal_pipes = talloc_get_type_abort( + domain->private_data, struct winbind_internal_pipes); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || + NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) + { + TALLOC_FREE(internal_pipes); + domain->private_data = NULL; + return true; + } + + if (!rpccli_is_connected(p)) { + TALLOC_FREE(internal_pipes); + domain->private_data = NULL; + return true; + } + + return false; +} + /********************************************************************* SAM specific functions. *********************************************************************/ @@ -195,6 +222,7 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, uint32_t num_info = 0; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_enum_dom_groups\n")); @@ -207,6 +235,7 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -222,6 +251,12 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain, &dom_pol, &num_info, &info); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(tmp_ctx); return status; @@ -249,6 +284,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, uint32_t *rids = NULL; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("samr_query_user_list\n")); @@ -257,6 +293,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -271,6 +308,11 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, &dom_pol, &domain->sid, &rids); + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -296,6 +338,7 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, uint32_t num_trusts = 0; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("samr: trusted domains\n")); @@ -308,6 +351,7 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, NULL, NULL, @@ -322,6 +366,12 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, &lsa_policy, &num_trusts, &trusts); + + if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -356,6 +406,7 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_lookup_groupmem\n")); @@ -374,6 +425,7 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -395,6 +447,11 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, &names, &name_types); + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (pnum_names) { *pnum_names = num_names; } @@ -467,6 +524,7 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, uint32_t num_info = 0; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("samr: enum local groups\n")); @@ -479,6 +537,7 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -492,7 +551,13 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain, samr_pipe, &dom_pol, &num_info, + &info); + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -525,6 +590,7 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, enum lsa_SidType type; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_name_to_sid\n")); @@ -533,6 +599,7 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, NULL, NULL, @@ -550,6 +617,12 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain, flags, &sid, &type); + + if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -581,6 +654,7 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, enum lsa_SidType type; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_sid_to_name\n")); @@ -604,6 +678,7 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, NULL, NULL, @@ -622,6 +697,11 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain, &name, &type); + if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) { + retry = true; + goto again; + } + if (ptype) { *ptype = type; } @@ -656,6 +736,7 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, char **names = NULL; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_rids_to_names for %s\n", domain->name)); @@ -675,6 +756,7 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, NULL, NULL, @@ -694,6 +776,12 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, &domain_name, &names, &types); + + if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -725,6 +813,7 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, TALLOC_CTX *tmp_ctx; NTSTATUS status, result; struct dcerpc_binding_handle *b = NULL; + bool retry = false; DEBUG(3,("sam_lockout_policy\n")); @@ -733,6 +822,7 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -750,6 +840,12 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain, DomainLockoutInformation, &info, &result); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -775,6 +871,7 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, TALLOC_CTX *tmp_ctx; NTSTATUS status, result; struct dcerpc_binding_handle *b = NULL; + bool retry = false; DEBUG(3,("sam_password_policy\n")); @@ -783,6 +880,7 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -800,6 +898,12 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain, DomainPasswordInformation, &info, &result); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto error; } @@ -828,6 +932,7 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, uint32_t num_groups = 0; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_lookup_usergroups\n")); @@ -842,6 +947,7 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -858,6 +964,12 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain, user_sid, &num_groups, &user_grpsids); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -889,6 +1001,7 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, uint32_t *alias_rids = NULL; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("sam_lookup_useraliases\n")); @@ -901,6 +1014,7 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -917,6 +1031,12 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain, sids, &num_aliases, &alias_rids); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -944,6 +1064,7 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, uint32_t seq = DOM_SEQUENCE_NONE; TALLOC_CTX *tmp_ctx; NTSTATUS status; + bool retry = false; DEBUG(3,("samr: sequence number\n")); @@ -956,6 +1077,7 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, return NT_STATUS_NO_MEMORY; } +again: status = open_cached_internal_pipe_conn(domain, &samr_pipe, &dom_pol, @@ -970,6 +1092,12 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain, &dom_pol, domain->name, &seq); + + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { + retry = true; + goto again; + } + if (!NT_STATUS_IS_OK(status)) { goto done; } -- 2.14.3