summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--librpc/idl/lsa.idl6
-rw-r--r--source3/librpc/idl/wbint.idl6
-rw-r--r--source3/winbindd/winbindd_dual_srv.c18
-rw-r--r--source3/winbindd/winbindd_proto.h5
-rw-r--r--source3/winbindd/winbindd_rpc.c98
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;
+}