diff options
-rw-r--r-- | librpc/idl/lsa.idl | 6 | ||||
-rw-r--r-- | source3/librpc/idl/wbint.idl | 6 | ||||
-rw-r--r-- | source3/winbindd/winbindd_dual_srv.c | 18 | ||||
-rw-r--r-- | source3/winbindd/winbindd_proto.h | 5 | ||||
-rw-r--r-- | source3/winbindd/winbindd_rpc.c | 98 |
5 files changed, 130 insertions, 3 deletions
diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl index fc59cd0433..c8aaa47c9d 100644 --- a/librpc/idl/lsa.idl +++ b/librpc/idl/lsa.idl @@ -519,7 +519,7 @@ import "misc.idl", "security.idl"; } lsa_TransSidArray; const int LSA_REF_DOMAIN_LIST_MULTIPLIER = 32; - typedef struct { + typedef [public] struct { [range(0,1000)] uint32 count; [size_is(count)] lsa_DomainInfo *domains; uint32 max_size; @@ -533,7 +533,7 @@ import "misc.idl", "security.idl"; * Level 6: Like 4 */ - typedef enum { + typedef [public] enum { LSA_LOOKUP_NAMES_ALL = 1, LSA_LOOKUP_NAMES_DOMAINS_ONLY = 2, LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY = 3, @@ -563,7 +563,7 @@ import "misc.idl", "security.idl"; uint32 sid_index; } lsa_TranslatedName; - typedef struct { + typedef [public] struct { [range(0,20480)] uint32 count; [size_is(count)] lsa_TranslatedName *names; } lsa_TransNameArray; diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index 470fb8b7eb..ec37b381ff 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -23,6 +23,12 @@ interface wbint [out,string,charset(UTF8)] char **name ); + NTSTATUS wbint_LookupSids( + [in] lsa_SidArray *sids, + [out,ref] lsa_RefDomainList *domains, + [out,ref] lsa_TransNameArray *names + ); + NTSTATUS wbint_LookupName( [in,string,charset(UTF8)] char *domain, [in,string,charset(UTF8)] char *name, diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index f5a5739fe8..e95dac234b 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -59,6 +59,24 @@ NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct wbint_LookupSid *r) return NT_STATUS_OK; } +NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct wbint_LookupSids *r) +{ + struct winbindd_domain *domain = wb_child_domain(); + + if (domain == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + /* + * This breaks the winbindd_domain->methods abstraction: This + * is only called for remote domains, and both winbindd_msrpc + * and winbindd_ad call into lsa_lookupsids anyway. Caching is + * done at the wbint RPC layer. + */ + return rpc_lookup_sids(p->mem_ctx, domain, r->in.sids, + &r->out.domains, &r->out.names); +} + NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r) { struct winbindd_domain *domain = wb_child_domain(); diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index a5b4a64643..d1007f420b 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -54,6 +54,11 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, const char ***domains, struct dom_sid **sids, enum lsa_SidType **types); +NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, + struct winbindd_domain *domain, + struct lsa_SidArray *sids, + struct lsa_RefDomainList **pdomains, + struct lsa_TransNameArray **pnames); /* The following definitions come from winbindd/winbindd_cache.c */ diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index ed7d994ca9..82599e7878 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -1033,3 +1033,101 @@ NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } + +static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx, + struct winbindd_domain *domain, + struct lsa_SidArray *sids, + struct lsa_RefDomainList **pdomains, + struct lsa_TransNameArray **pnames) +{ + struct lsa_TransNameArray2 lsa_names2; + struct lsa_TransNameArray *names; + uint32_t i, count; + struct rpc_pipe_client *cli; + NTSTATUS status, result; + + status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli); + if (!NT_STATUS_IS_OK(status)) { + domain->can_do_ncacn_ip_tcp = false; + return status; + } + + ZERO_STRUCT(lsa_names2); + status = dcerpc_lsa_LookupSids3(cli->binding_handle, + mem_ctx, + sids, + pdomains, + &lsa_names2, + LSA_LOOKUP_NAMES_ALL, + &count, + LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES, + LSA_CLIENT_REVISION_2, + &result); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (NT_STATUS_IS_ERR(result)) { + return result; + } + names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); + if (names == NULL) { + return NT_STATUS_NO_MEMORY; + } + names->count = lsa_names2.count; + names->names = talloc_array(names, struct lsa_TranslatedName, + names->count); + if (names->names == NULL) { + return NT_STATUS_NO_MEMORY; + } + for (i=0; i<names->count; i++) { + names->names[i].sid_type = lsa_names2.names[i].sid_type; + names->names[i].name.string = talloc_move( + names->names, &lsa_names2.names[i].name.string); + names->names[i].sid_index = lsa_names2.names[i].sid_index; + } + *pnames = names; + return result; +} + +NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, + struct winbindd_domain *domain, + struct lsa_SidArray *sids, + struct lsa_RefDomainList **pdomains, + struct lsa_TransNameArray **pnames) +{ + struct lsa_TransNameArray *names; + struct rpc_pipe_client *cli = NULL; + struct policy_handle lsa_policy; + uint32_t count; + NTSTATUS status, result; + + if (domain->can_do_ncacn_ip_tcp) { + status = rpc_try_lookup_sids3(mem_ctx, domain, sids, + pdomains, pnames); + if (!NT_STATUS_IS_ERR(status)) { + return status; + } + } + + status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); + if (names == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx, + &lsa_policy, sids, pdomains, + names, LSA_LOOKUP_NAMES_ALL, + &count, &result); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (NT_STATUS_IS_ERR(result)) { + return result; + } + *pnames = names; + return result; +} |