From: Volker Lendecke Date: Tue, 23 Feb 2021 15:03:17 +0000 (+0100) Subject: winbindd: Use samr in sam_rids_to_names() instead of lsa X-Git-Tag: tevent-0.11.0~1314 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bf1012ee7063f03503eb2e348757b1b12d5bff0b;p=thirdparty%2Fsamba.git winbindd: Use samr in sam_rids_to_names() instead of lsa Same argument as with previous patches: We don't need fancy lsa routing and samr is less prone to deadlock back into winbind Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index d4057ed74ef..a346916f3fc 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -882,63 +882,151 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain, char ***pnames, enum lsa_SidType **ptypes) { - struct rpc_pipe_client *lsa_pipe; - struct policy_handle lsa_policy = { 0 }; + struct rpc_pipe_client *samr_pipe = NULL; + struct dcerpc_binding_handle *h = NULL; + struct policy_handle dom_pol = { .handle_type = 0, }; + struct lsa_Strings lsa_names = { .count = 0, }; + struct samr_Ids samr_types = { .count = 0, }; enum lsa_SidType *types = NULL; - char *domain_name = NULL; char **names = NULL; + const char *domain_name = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); - NTSTATUS status; + NTSTATUS status = NT_STATUS_NO_MEMORY; + NTSTATUS result; bool retry = false; + uint32_t i; DEBUG(3,("sam_rids_to_names for %s\n", domain->name)); - /* Paranoia check */ - if (!sid_check_is_builtin(domain_sid) && - !sid_check_is_our_sam(domain_sid) && - !sid_check_is_unix_users(domain_sid) && - !sid_check_is_unix_groups(domain_sid) && - !sid_check_is_in_wellknown_domain(domain_sid)) { - struct dom_sid_buf buf; - DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to " - "lookup SID %s\n", - dom_sid_str_buf(domain_sid, &buf))); + types = talloc_array(tmp_ctx, enum lsa_SidType, num_rids); + if (types == NULL) { + goto fail; + } + + names = talloc_array(tmp_ctx, char *, num_rids); + if (names == NULL) { + goto fail; + } + + if (sid_check_is_unix_users(domain_sid)) { + domain_name = unix_users_domain_name(); + domain_sid = &global_sid_Unix_Users; + } + if (sid_check_is_unix_groups(domain_sid)) { + domain_name = unix_groups_domain_name(); + domain_sid = &global_sid_Unix_Groups; + } + + /* Here we're only interested in the domain name being set */ + sid_check_is_wellknown_domain(domain_sid, &domain_name); + + if (domain_name != NULL) { + uint32_t num_mapped = 0; + + /* + * Do unix users/groups and wkn in a loop. There is no + * getpwuids() call & friends anyway + */ + + for (i=0; i 0) { + status = (num_mapped == num_rids) ? + NT_STATUS_OK : STATUS_SOME_UNMAPPED; + } goto done; } + domain_name = domain->name; + again: - status = open_cached_internal_pipe_conn(domain, - NULL, - NULL, - &lsa_pipe, - &lsa_policy); + status = open_cached_internal_pipe_conn( + domain, &samr_pipe, &dom_pol, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { goto done; } + h = samr_pipe->binding_handle; - status = rpc_rids_to_names(tmp_ctx, - lsa_pipe, - &lsa_policy, - domain, - domain_sid, - rids, - num_rids, - &domain_name, - &names, - &types); + status = dcerpc_samr_LookupRids( + h, + tmp_ctx, + &dom_pol, + num_rids, + rids, + &lsa_names, + &samr_types, + &result); - if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) { + if (!retry && reset_connection_on_error(domain, samr_pipe, status)) { retry = true; goto again; } if (!NT_STATUS_IS_OK(status)) { - goto done; + DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n", + nt_errstr(status)); + goto fail; + } + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { + DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n", + nt_errstr(result)); + status = result; + goto fail; } + for (i=0; i