diff options
-rw-r--r-- | source3/Makefile.in | 1 | ||||
-rw-r--r-- | source3/librpc/idl/wbint.idl | 19 | ||||
-rw-r--r-- | source3/winbindd/winbindd_dual_srv.c | 92 |
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 : "", |