The branch, master has been updated
       via  2610a3f winbindd: Use talloc_zero_array for consistency with other 
winbindd_domain allocators
       via  fc9150d winbindd: Do re-connect if the RPC call fails in the passdb 
case
       via  d418d0c winbindd: Add a cache of the samr and lsa handles for the 
passdb domain
      from  da72c40 autobuild: Move "none" environment to samba-none-env

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2610a3f2f7437309b259387e286e6e43d654b6e4
Author: Andrew Bartlett <abart...@samba.org>
Date:   Wed Mar 21 21:23:13 2018 +1300

    winbindd: Use talloc_zero_array for consistency with other winbindd_domain 
allocators
    
    The other allocator for this structure uses talloc_zero()
    
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abart...@samba.org>
    Autobuild-Date(master): Sat Mar 24 07:21:37 CET 2018 on sn-devel-144

commit fc9150dcab231fe9beb72e198b0c2742d5f2505f
Author: Andrew Bartlett <abart...@samba.org>
Date:   Wed Mar 21 20:44:31 2018 +1300

    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.
    
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit d418d0ca33afb41a793a2fff19ca68871aa5e9ef
Author: Andrew Bartlett <abart...@samba.org>
Date:   Wed Mar 21 20:43:10 2018 +1300

    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.
    
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/winbindd/wb_seqnums.c    |   4 +-
 source3/winbindd/winbindd_samr.c | 395 ++++++++++++++++++++++++++++-----------
 2 files changed, 289 insertions(+), 110 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/winbindd/wb_seqnums.c b/source3/winbindd/wb_seqnums.c
index 2a4cdc9..3c9af01 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);
 
diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c
index aedb77b..31720d5 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"
@@ -40,6 +41,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 +116,96 @@ 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;
+}
+
+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.
 *********************************************************************/
@@ -116,8 +221,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("sam_enum_dom_groups\n"));
 
@@ -130,20 +235,31 @@ 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);
+again:
+       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 (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+               retry = true;
+               goto again;
+       }
+
        if (!NT_STATUS_IS_OK(status)) {
-               goto error;
+               TALLOC_FREE(tmp_ctx);
+               return status;
        }
 
        if (pnum_info) {
@@ -154,10 +270,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 +283,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("samr_query_user_list\n"));
 
@@ -181,18 +293,26 @@ 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);
+again:
+       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,
                                     &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;
        }
@@ -202,10 +322,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 +337,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("samr: trusted domains\n"));
 
@@ -235,18 +351,27 @@ 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);
+again:
+       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,
                                     &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;
        }
@@ -257,10 +382,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 +405,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("sam_lookup_groupmem\n"));
 
@@ -304,13 +425,16 @@ 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);
+again:
+       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,
@@ -323,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;
        }
@@ -340,10 +469,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 +523,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("samr: enum local groups\n"));
 
@@ -412,18 +537,27 @@ 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);
+again:
+       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,
                                       &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;
        }
@@ -437,10 +571,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 +589,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("sam_name_to_sid\n"));
 
@@ -469,13 +599,16 @@ 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);
+again:
+       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,
@@ -484,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;
        }
@@ -496,10 +635,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 +653,8 @@ 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;
+       bool retry = false;
 
        DEBUG(3,("sam_sid_to_name\n"));
 
@@ -543,13 +678,16 @@ 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);
+again:
+       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,


-- 
Samba Shared Repository

Reply via email to