summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2018-03-21 20:43:10 +1300
committerKarolin Seeger <kseeger@samba.org>2018-05-14 09:58:19 +0200
commit6a41a0dcbec9644f2661c919c669144c67bf9394 (patch)
treefd004a0a3e3dd1ed1908a1dbf0f786b57b56882c /source3
parent139743ec1ed9078be0891e416c536305b6dd1b33 (diff)
downloadsamba-6a41a0dcbec9644f2661c919c669144c67bf9394.tar.gz
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 <abartlet@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> (cherry picked from commit d418d0ca33afb41a793a2fff19ca68871aa5e9ef)
Diffstat (limited to 'source3')
-rw-r--r--source3/winbindd/winbindd_samr.c267
1 files 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;
}