summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/librpc/idl/wbint.idl19
-rw-r--r--source3/winbindd/winbindd_dual_srv.c92
3 files changed, 111 insertions, 1 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 902e5af167..8211edc79a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1342,6 +1342,7 @@ WINBINDD_OBJ1 = \
librpc/gen_ndr/ndr_wbint_c.o \
librpc/gen_ndr/srv_wbint.o \
librpc/gen_ndr/ndr_wbint.o \
+ librpc/gen_ndr/ndr_idmap.o \
winbindd/winbindd_async.o \
winbindd/winbindd_creds.o \
winbindd/winbindd_cred_cache.o \
diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl
index ec37b381ff..5f7e9bf808 100644
--- a/source3/librpc/idl/wbint.idl
+++ b/source3/librpc/idl/wbint.idl
@@ -1,5 +1,5 @@
#include "idl_types.h"
-import "lsa.idl", "netlogon.idl", "misc.idl", "security.idl";
+import "lsa.idl", "netlogon.idl", "misc.idl", "security.idl", "idmap.idl";
[
uuid("bf09192c-ed60-4928-9dff-d0d7bcb03ed8"),
@@ -49,6 +49,23 @@ interface wbint
[out] hyper *gid
);
+ typedef struct {
+ id_type type;
+ uint32 domain_index;
+ uint32 rid;
+ hyper unix_id;
+ } wbint_TransID;
+
+ typedef struct {
+ uint32 num_ids;
+ [size_is(num_ids)] wbint_TransID ids[];
+ } wbint_TransIDArray;
+
+ NTSTATUS wbint_Sids2UnixIDs(
+ [in] lsa_RefDomainList *domains,
+ [in,out] wbint_TransIDArray *ids
+ );
+
NTSTATUS wbint_Uid2Sid(
[in,unique,string,charset(UTF8)] char *dom_name,
[in] hyper uid,
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index e95dac234b..230edae908 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -118,6 +118,98 @@ NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r)
return NT_STATUS_OK;
}
+NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
+ struct wbint_Sids2UnixIDs *r)
+{
+ uint32_t i, j;
+ struct id_map *ids = NULL;
+ struct id_map **id_ptrs = NULL;
+ struct dom_sid *sids = NULL;
+ uint32_t *id_idx = NULL;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<r->in.domains->count; i++) {
+ struct lsa_DomainInfo *d = &r->in.domains->domains[i];
+ struct idmap_domain *dom;
+ uint32_t num_ids;
+
+ dom = idmap_find_domain(d->name.string);
+ if (dom == NULL) {
+ DEBUG(10, ("idmap domain %s not found\n",
+ d->name.string));
+ continue;
+ }
+
+ num_ids = 0;
+
+ for (j=0; j<r->in.ids->num_ids; j++) {
+ if (r->in.ids->ids[j].domain_index == i) {
+ num_ids += 1;
+ }
+ }
+
+ ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids,
+ struct id_map, num_ids);
+ if (ids == NULL) {
+ goto nomem;
+ }
+ id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs,
+ struct id_map *, num_ids+1);
+ if (id_ptrs == NULL) {
+ goto nomem;
+ }
+ id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx,
+ uint32_t, num_ids);
+ if (id_idx == NULL) {
+ goto nomem;
+ }
+ sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids,
+ struct dom_sid, num_ids);
+ if (sids == NULL) {
+ goto nomem;
+ }
+
+ num_ids = 0;
+
+ for (j=0; j<r->in.ids->num_ids; j++) {
+ struct wbint_TransID *id = &r->in.ids->ids[j];
+
+ if (id->domain_index != i) {
+ continue;
+ }
+ id_idx[num_ids] = j;
+ id_ptrs[num_ids] = &ids[num_ids];
+
+ ids[num_ids].sid = &sids[num_ids];
+ sid_compose(ids[num_ids].sid, d->sid, id->rid);
+ ids[num_ids].xid.type = id->type;
+ ids[num_ids].status = ID_UNKNOWN;
+ num_ids += 1;
+ }
+ id_ptrs[num_ids] = NULL;
+
+ status = dom->methods->sids_to_unixids(dom, id_ptrs);
+ DEBUG(10, ("sids_to_unixids returned %s\n",
+ nt_errstr(status)));
+
+ for (j=0; j<num_ids; j++) {
+ struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
+
+ if (ids[j].status != ID_MAPPED) {
+ continue;
+ }
+ id->unix_id = ids[j].xid.id;
+ }
+ }
+ status = NT_STATUS_OK;
+nomem:
+ TALLOC_FREE(ids);
+ TALLOC_FREE(id_ptrs);
+ TALLOC_FREE(id_idx);
+ TALLOC_FREE(sids);
+ return status;
+}
+
NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
{
return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "",