[PATCH] winbind cleanups

Volker Lendecke Volker.Lendecke at SerNet.DE
Thu Feb 18 14:30:00 UTC 2016


Hi!

The attached patchset consolidates the winbind pipe
protocol, replacing the one-element idmapping calls with the
plural ones. The first few patches are preparations for more
idmap simplification.

Review appreciated!

Thanks, Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 90414b6193c3be382378071d5a91bf8353553740 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 29 Dec 2015 11:59:54 +0100
Subject: [PATCH 01/26] winbind: Remove a level of indirection

idmap_doms does not need a talloc of its own

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/wb_sids2xids.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index 940a06b..a78187e 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -47,7 +47,7 @@ struct wb_sids2xids_state {
 	 * new domain, but this approach avoids id mappings for
 	 * invalid SIDs.
 	 */
-	struct lsa_RefDomainList *idmap_doms;
+	struct lsa_RefDomainList idmap_doms;
 
 	struct wbint_TransIDArray ids;
 };
@@ -174,11 +174,6 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 		return;
 	}
 
-	state->idmap_doms = talloc_zero(state, struct lsa_RefDomainList);
-	if (tevent_req_nomem(state->idmap_doms, req)) {
-		return;
-	}
-
 	for (i=0; i<state->num_non_cached; i++) {
 		struct dom_sid dom_sid;
 		struct lsa_DomainInfo *info;
@@ -193,7 +188,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 		t->type = lsa_SidType_to_id_type(n->sid_type);
 
 		domain_index = init_lsa_ref_domain_list(
-			state, state->idmap_doms, info->name.string, &dom_sid);
+			state, &state->idmap_doms, info->name.string, &dom_sid);
 		if (domain_index == -1) {
 			tevent_req_oom(req);
 			return;
@@ -210,7 +205,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 	child = idmap_child();
 
 	subreq = dcerpc_wbint_Sids2UnixIDs_send(
-		state, state->ev, child->binding_handle, state->idmap_doms,
+		state, state->ev, child->binding_handle, &state->idmap_doms,
 		&state->ids);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
-- 
1.7.9.5


From f5a157cc9f77750e29f0062b414a3c9264b0c95e Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 29 Dec 2015 15:19:34 +0000
Subject: [PATCH 02/26] winbind: Make _wbint_Sids2UnixIDs single-domain

This is required to handle domain-specific error messages properly in the
parent. Currently unused, but I want to handle DOMAIN_CONTROLLER_NOT_FOUND
for the idmap_ad backend soon by doing a getdcname (RPC or ourselves or
so) from the parent context.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/wb_sids2xids.c |  109 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 105 insertions(+), 4 deletions(-)

diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index a78187e..7cb7ec4 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -49,6 +49,10 @@ struct wb_sids2xids_state {
 	 */
 	struct lsa_RefDomainList idmap_doms;
 
+	uint32_t dom_index;
+	struct wbint_TransIDArray *dom_ids;
+	struct lsa_RefDomainList idmap_dom;
+
 	struct wbint_TransIDArray ids;
 };
 
@@ -148,6 +152,9 @@ static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map)
 }
 
 static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type);
+static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index(
+	TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src,
+	uint32_t domain_index);
 
 static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 {
@@ -204,9 +211,21 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 
 	child = idmap_child();
 
+	state->dom_ids = wb_sids2xids_extract_for_domain_index(
+		state, &state->ids, state->dom_index);
+	if (tevent_req_nomem(state->dom_ids, req)) {
+		return;
+	}
+
+	state->idmap_dom = (struct lsa_RefDomainList) {
+		.count = 1,
+		.domains = &state->idmap_doms.domains[state->dom_index],
+		.max_size = 1
+	};
+
 	subreq = dcerpc_wbint_Sids2UnixIDs_send(
-		state, state->ev, child->binding_handle, &state->idmap_doms,
-		&state->ids);
+		state, state->ev, child->binding_handle, &state->idmap_dom,
+		state->dom_ids);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
@@ -243,14 +262,68 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
 	struct wb_sids2xids_state *state = tevent_req_data(
 		req, struct wb_sids2xids_state);
 	NTSTATUS status, result;
+	struct winbindd_child *child;
+
+	struct wbint_TransIDArray *src, *dst;
+	uint32_t i, src_idx;
 
 	status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result);
 	TALLOC_FREE(subreq);
+
+	src = state->dom_ids;
+	src_idx = 0;
+	dst = &state->ids;
+
 	if (any_nt_status_not_ok(status, result, &status)) {
-		tevent_req_nterror(req, status);
+		DBG_DEBUG("status=%s, result=%s\n", nt_errstr(status),
+			  nt_errstr(result));
+
+		/*
+		 * All we can do here is to report "not mapped"
+		 */
+		for (i=0; i<src->num_ids; i++) {
+			src->ids[i].type = ID_TYPE_NOT_SPECIFIED;
+		}
+	}
+
+	for (i=0; i<dst->num_ids; i++) {
+		if (dst->ids[i].domain_index == state->dom_index) {
+			dst->ids[i].type = src->ids[src_idx].type;
+			dst->ids[i].xid  = src->ids[src_idx].xid;
+			src_idx += 1;
+		}
+	}
+
+	TALLOC_FREE(state->dom_ids);
+
+	state->dom_index += 1;
+
+	if (state->dom_index == state->idmap_doms.count) {
+		tevent_req_done(req);
 		return;
 	}
-	tevent_req_done(req);
+
+	child = idmap_child();
+
+	state->dom_ids = wb_sids2xids_extract_for_domain_index(
+		state, &state->ids, state->dom_index);
+	if (tevent_req_nomem(state->dom_ids, req)) {
+		return;
+	}
+
+	state->idmap_dom = (struct lsa_RefDomainList) {
+		.count = 1,
+		.domains = &state->idmap_doms.domains[state->dom_index],
+		.max_size = 1
+	};
+
+	subreq = dcerpc_wbint_Sids2UnixIDs_send(
+		state, state->ev, child->binding_handle, &state->idmap_dom,
+		state->dom_ids);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, wb_sids2xids_done, req);
 }
 
 NTSTATUS wb_sids2xids_recv(struct tevent_req *req,
@@ -296,3 +369,31 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req,
 
 	return NT_STATUS_OK;
 }
+
+static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index(
+	TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src,
+	uint32_t domain_index)
+{
+	struct wbint_TransIDArray *ret;
+	uint32_t i;
+
+	ret = talloc_zero(mem_ctx, struct wbint_TransIDArray);
+	if (ret == NULL) {
+		return NULL;
+	}
+	ret->ids = talloc_array(ret, struct wbint_TransID, src->num_ids);
+	if (ret->ids == NULL) {
+		TALLOC_FREE(ret);
+		return NULL;
+	}
+
+	for (i=0; i<src->num_ids; i++) {
+		if (src->ids[i].domain_index == domain_index) {
+			ret->ids[ret->num_ids] = src->ids[i];
+			ret->ids[ret->num_ids].domain_index = 0;
+			ret->num_ids += 1;
+		}
+	}
+
+	return ret;
+}
-- 
1.7.9.5


From dc3ee232931b03be92bbfc534f42524c3844cf41 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 29 Dec 2015 21:33:20 +0000
Subject: [PATCH 03/26] winbind: Simplify _wbint_Sids2UnixIDs

Same number of lines, but from my point of view quite a bit simpler now
that we only have to handle one domain.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_dual_srv.c |  153 +++++++++++++++++-----------------
 1 file changed, 77 insertions(+), 76 deletions(-)

diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index cdd9bbd..2f4b0e2 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -121,102 +121,103 @@ NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r)
 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;
+	uint32_t i;
+
+	struct lsa_DomainInfo *d;
+	struct wbint_TransID *ids;
+	uint32_t num_ids;
+
+	struct id_map *id_maps = NULL;
+	struct id_map **id_map_ptrs = NULL;
 	struct dom_sid *sids = NULL;
-	uint32_t *id_idx = NULL;
+	struct idmap_domain *dom;
 	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;
+	if (r->in.domains->count != 1) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
 
-		dom = idmap_find_domain_with_sid(d->name.string, d->sid);
-		if (dom == NULL) {
-			DEBUG(10, ("idmap domain %s:%s not found\n",
-				   d->name.string, sid_string_dbg(d->sid)));
-			continue;
-		}
+	d = &r->in.domains->domains[0];
+	ids = r->in.ids->ids;
+	num_ids = r->in.ids->num_ids;
 
-		num_ids = 0;
+	dom = idmap_find_domain_with_sid(d->name.string, d->sid);
+	if (dom == NULL) {
+		DEBUG(10, ("idmap domain %s:%s not found\n",
+			   d->name.string, sid_string_dbg(d->sid)));
 
-		for (j=0; j<r->in.ids->num_ids; j++) {
-			if (r->in.ids->ids[j].domain_index == i) {
-				num_ids += 1;
-			}
-		}
+		for (i=0; i<num_ids; i++) {
 
-		ids = talloc_realloc(talloc_tos(), ids,
-					   struct id_map, num_ids);
-		if (ids == NULL) {
-			goto nomem;
-		}
-		id_ptrs = talloc_realloc(talloc_tos(), id_ptrs,
-					       struct id_map *, num_ids+1);
-		if (id_ptrs == NULL) {
-			goto nomem;
-		}
-		id_idx = talloc_realloc(talloc_tos(), id_idx,
-					      uint32_t, num_ids);
-		if (id_idx == NULL) {
-			goto nomem;
-		}
-		sids = talloc_realloc(talloc_tos(), sids,
-					    struct dom_sid, num_ids);
-		if (sids == NULL) {
-			goto nomem;
+			ids[i].xid = (struct unixid) {
+				.id = UINT32_MAX,
+				.type = ID_TYPE_NOT_SPECIFIED
+			};
 		}
 
-		num_ids = 0;
+		return NT_STATUS_OK;
+	}
 
-		/*
-		 * Convert the input data into a list of
-		 * id_map structs suitable for handing in
-		 * to the idmap sids_to_unixids method.
-		 */
-		for (j=0; j<r->in.ids->num_ids; j++) {
-			struct wbint_TransID *id = &r->in.ids->ids[j];
+	id_maps = talloc_array(talloc_tos(), struct id_map, num_ids);
+	if (id_maps == NULL) {
+		goto nomem;
+	}
+	id_map_ptrs = talloc_array(talloc_tos(), struct id_map *, num_ids+1);
+	if (id_map_ptrs == NULL) {
+		goto nomem;
+	}
+	sids = talloc_array(talloc_tos(), struct dom_sid, num_ids);
+	if (sids == NULL) {
+		goto nomem;
+	}
 
-			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;
+	/*
+	 * Convert the input data into a list of id_map structs
+	 * suitable for handing in to the idmap sids_to_unixids
+	 * method.
+	 */
+
+	for (i=0; i<num_ids; i++) {
+
+		sid_compose(&sids[i], d->sid, ids[i].rid);
+
+		id_maps[i] = (struct id_map) {
+			.sid = &sids[i],
+			.xid.type = ids[i].type,
+			.status = ID_UNKNOWN
+		};
+
+		id_map_ptrs[i] = &id_maps[i];
+	}
+	id_map_ptrs[num_ids] = NULL;
+
+	status = dom->methods->sids_to_unixids(dom, id_map_ptrs);
 
-		status = dom->methods->sids_to_unixids(dom, id_ptrs);
+	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("sids_to_unixids returned %s\n",
 			   nt_errstr(status)));
+		goto done;
+	}
 
-		/*
-		 * Extract the results for handing them back to the caller.
-		 */
-		for (j=0; j<num_ids; j++) {
-			struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
+	/*
+	 * Extract the results for handing them back to the caller.
+	 */
 
-			if (ids[j].status != ID_MAPPED) {
-				id->xid.id = UINT32_MAX;
-				id->xid.type = ID_TYPE_NOT_SPECIFIED;
-				continue;
-			}
+	for (i=0; i<num_ids; i++) {
 
-			id->xid = ids[j].xid;
+		if (id_maps[i].status == ID_MAPPED) {
+			ids[i].xid = id_maps[i].xid;
+		} else {
+			ids[i].xid.id = UINT32_MAX;
+			ids[i].xid.type = ID_TYPE_NOT_SPECIFIED;
 		}
 	}
-	status = NT_STATUS_OK;
+
+	goto done;
 nomem:
-	TALLOC_FREE(ids);
-	TALLOC_FREE(id_ptrs);
-	TALLOC_FREE(id_idx);
+	status = NT_STATUS_NO_MEMORY;
+done:
+	TALLOC_FREE(id_maps);
+	TALLOC_FREE(id_map_ptrs);
 	TALLOC_FREE(sids);
 	return status;
 }
-- 
1.7.9.5


From f950ba707d1e9b1242e8a49645f1b955501e25bf Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 20 Aug 2015 17:07:19 +0200
Subject: [PATCH 04/26] winbind: Add wbint_UnixIDs2Sids

The idmap backend function is doing multiple conversions in one run, but this
is not used so far. First step in exposing plural xid2sid. This is a fake
routine in that it does the one-element calls, but you have to start somewhere.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 librpc/idl/winbind.idl               |    6 ++++++
 source3/winbindd/winbindd_dual_srv.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl
index 07deb80..7150e3f 100644
--- a/librpc/idl/winbind.idl
+++ b/librpc/idl/winbind.idl
@@ -66,6 +66,12 @@ interface winbind
 	[out] dom_sid *sid
 	);
 
+    NTSTATUS wbint_UnixIDs2Sids(
+	[in] uint32 num_ids,
+	[in] unixid xids[num_ids],
+	[out] dom_sid sids[num_ids]
+	);
+
     NTSTATUS wbint_AllocateUid(
 	[out] hyper *uid
 	);
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 2f4b0e2..d6070707 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -232,6 +232,36 @@ NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
 	return idmap_gid_to_sid(r->out.sid, r->in.gid);
 }
 
+NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
+			     struct wbint_UnixIDs2Sids *r)
+{
+	uint32_t i;
+
+	for (i=0; i<r->in.num_ids; i++) {
+		struct unixid *xid = &r->in.xids[i];
+		struct dom_sid *sid = &r->out.sids[i];
+		NTSTATUS status;
+
+		switch (xid->type) {
+		    case ID_TYPE_UID:
+			    status = idmap_uid_to_sid(sid, xid->id);
+			    break;
+		    case ID_TYPE_GID:
+			    status = idmap_gid_to_sid(sid, xid->id);
+			    break;
+		    default:
+			    status = NT_STATUS_NONE_MAPPED;
+			    break;
+		}
+
+		if (!NT_STATUS_IS_OK(status)) {
+			*sid = (struct dom_sid) {0};
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
 NTSTATUS _wbint_AllocateUid(struct pipes_struct *p, struct wbint_AllocateUid *r)
 {
 	struct unixid xid;
-- 
1.7.9.5


From 35b0037206a4d5d6ed1b50288269d60ff9346aca Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 20 Aug 2015 17:07:47 +0200
Subject: [PATCH 05/26] winbind: Add wb_xids2sids

Async wrapper around wbint_UnixIDs2Sids

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/wb_xids2sids.c   |   94 +++++++++++++++++++++++++++++++++++++
 source3/winbindd/winbindd_proto.h |    6 +++
 source3/wscript_build             |    1 +
 3 files changed, 101 insertions(+)
 create mode 100644 source3/winbindd/wb_xids2sids.c

diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
new file mode 100644
index 0000000..6c3f0f6
--- /dev/null
+++ b/source3/winbindd/wb_xids2sids.c
@@ -0,0 +1,94 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * async xids2sids
+ * Copyright (C) Volker Lendecke 2015
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "winbindd.h"
+#include "../libcli/security/security.h"
+#include "idmap_cache.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
+
+struct wb_xids2sids_state {
+	struct dom_sid *sids;
+};
+
+static void wb_xids2sids_done(struct tevent_req *subreq);
+
+struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
+				     struct tevent_context *ev,
+				     struct unixid *xids,
+				     uint32_t num_xids)
+{
+	struct tevent_req *req, *subreq;
+	struct wb_xids2sids_state *state;
+	struct winbindd_child *child;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct wb_xids2sids_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	state->sids = talloc_array(state, struct dom_sid, num_xids);
+	if (tevent_req_nomem(state->sids, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	child = idmap_child();
+
+	subreq = dcerpc_wbint_UnixIDs2Sids_send(
+		state, ev, child->binding_handle, num_xids, xids, state->sids);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, wb_xids2sids_done, req);
+	return req;
+}
+
+static void wb_xids2sids_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct wb_xids2sids_state *state = tevent_req_data(
+		req, struct wb_xids2sids_state);
+	NTSTATUS status, result;
+
+	status = dcerpc_wbint_UnixIDs2Sids_recv(subreq, state, &result);
+	TALLOC_FREE(subreq);
+	if (any_nt_status_not_ok(status, result, &status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	tevent_req_done(req);
+}
+
+NTSTATUS wb_xids2sids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+			   struct dom_sid **sids)
+{
+	struct wb_xids2sids_state *state = tevent_req_data(
+		req, struct wb_xids2sids_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status)));
+		return status;
+	}
+
+	*sids = talloc_move(mem_ctx, &state->sids);
+	return NT_STATUS_OK;
+}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 1f4f174..bc3ac65 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -904,6 +904,12 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
 					      struct winbindd_request *request);
 NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
 				    struct winbindd_response *response);
+struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
+				     struct tevent_context *ev,
+				     struct unixid *xids,
+				     uint32_t num_xids);
+NTSTATUS wb_xids2sids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+			   struct dom_sid **sids);
 struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
 					   struct tevent_context *ev,
 					   struct winbindd_cli_state *cli,
diff --git a/source3/wscript_build b/source3/wscript_build
index 6f47c35..67a787e 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -927,6 +927,7 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/wb_uid2sid.c
                  winbindd/wb_gid2sid.c
                  winbindd/wb_sids2xids.c
+                 winbindd/wb_xids2sids.c
                  winbindd/wb_queryuser.c
                  winbindd/wb_lookupuseraliases.c
                  winbindd/wb_lookupusergroups.c
-- 
1.7.9.5


From b3d313ce8934dbad6c22117c2d38a33e8514293a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 14 Aug 2015 17:14:53 +0200
Subject: [PATCH 06/26] winbind: Add parse_xidlist()

This will be part of parsing the socket protocols xids2sids request

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_proto.h |    2 ++
 source3/winbindd/winbindd_util.c  |   64 +++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index bc3ac65..f3c5c99 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -468,6 +468,8 @@ bool is_domain_offline(const struct winbindd_domain *domain);
 bool is_domain_online(const struct winbindd_domain *domain);
 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
 		   struct dom_sid **sids, uint32_t *num_sids);
+bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
+		   struct unixid **pxids, uint32_t *pnum_xids);
 
 /* The following definitions come from winbindd/winbindd_wins.c  */
 
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 8139daa..0cd77f7 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -1610,3 +1610,67 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
 	}
 	return True;
 }
+
+bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
+		   struct unixid **pxids, uint32_t *pnum_xids)
+{
+	const char *p;
+	struct unixid *xids = NULL;
+	uint32_t num_xids = 0;
+
+	p = xidstr;
+	if (p == NULL) {
+		return false;
+	}
+
+	while (p[0] != '\0') {
+		struct unixid *tmp;
+		struct unixid xid;
+		unsigned long long id;
+		char *endp;
+
+		switch (p[0]) {
+		case 'U':
+			xid = (struct unixid) { .type = ID_TYPE_UID };
+			break;
+		case 'G':
+			xid = (struct unixid) { .type = ID_TYPE_GID };
+			break;
+		default:
+			return false;
+		}
+
+		p += 1;
+
+		id = strtoull(p, &endp, 10);
+		if ((id == ULLONG_MAX) && (errno == ERANGE)) {
+			goto fail;
+		}
+		if (*endp != '\n') {
+			goto fail;
+		}
+		p = endp+1;
+
+		xid.id = id;
+		if ((unsigned long long)xid.id != id) {
+			goto fail;
+		}
+
+		tmp = talloc_realloc(mem_ctx, xids, struct unixid, num_xids+1);
+		if (tmp == NULL) {
+			return 0;
+		}
+		xids = tmp;
+
+		xids[num_xids] = xid;
+		num_xids += 1;
+	}
+
+	*pxids = xids;
+	*pnum_xids = num_xids;
+	return true;
+
+fail:
+	TALLOC_FREE(xids);
+	return false;
+}
-- 
1.7.9.5


From da4f5aa7c199a6f763ad7286ed9230a7cab21670 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 14 Aug 2015 17:15:33 +0200
Subject: [PATCH 07/26] winbind: Expose WINBINDD_XIDS_TO_SIDS externally

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_struct_protocol.h       |    4 +-
 source3/winbindd/winbindd.c              |    2 +
 source3/winbindd/winbindd_proto.h        |    6 ++
 source3/winbindd/winbindd_xids_to_sids.c |  136 ++++++++++++++++++++++++++++++
 source3/wscript_build                    |    1 +
 5 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 source3/winbindd/winbindd_xids_to_sids.c

diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 0dffa4b..178906d 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -53,8 +53,9 @@ typedef char fstring[FSTRING_LEN];
  *     removed WINBINDD_REMOVE_MAPPING
  * 26: added WINBINDD_DC_INFO
  * 27: added WINBINDD_LOOKUPSIDS
+ * 28: added WINBINDD_XIDS_TO_SIDS
  */
-#define WINBIND_INTERFACE_VERSION 27
+#define WINBIND_INTERFACE_VERSION 28
 
 /* Have to deal with time_t being 4 or 8 bytes due to structure alignment.
    On a 64bit Linux box, we have to support a constant structure size
@@ -113,6 +114,7 @@ enum winbindd_cmd {
 	WINBINDD_SID_TO_UID,
 	WINBINDD_SID_TO_GID,
 	WINBINDD_SIDS_TO_XIDS,
+	WINBINDD_XIDS_TO_SIDS,
 	WINBINDD_UID_TO_SID,
 	WINBINDD_GID_TO_SID,
 
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index d555127..ec49ea5 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -618,6 +618,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
 	{ WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
 	  winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
+	{ WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
+	  winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
 	{ WINBINDD_GETPWSID, "GETPWSID",
 	  winbindd_getpwsid_send, winbindd_getpwsid_recv },
 	{ WINBINDD_GETPWNAM, "GETPWNAM",
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index f3c5c99..063e793 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -912,6 +912,12 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
 				     uint32_t num_xids);
 NTSTATUS wb_xids2sids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 			   struct dom_sid **sids);
+struct tevent_req *winbindd_xids_to_sids_send(TALLOC_CTX *mem_ctx,
+					      struct tevent_context *ev,
+					      struct winbindd_cli_state *cli,
+					      struct winbindd_request *request);
+NTSTATUS winbindd_xids_to_sids_recv(struct tevent_req *req,
+				    struct winbindd_response *response);
 struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
 					   struct tevent_context *ev,
 					   struct winbindd_cli_state *cli,
diff --git a/source3/winbindd/winbindd_xids_to_sids.c b/source3/winbindd/winbindd_xids_to_sids.c
new file mode 100644
index 0000000..d1424cd
--- /dev/null
+++ b/source3/winbindd/winbindd_xids_to_sids.c
@@ -0,0 +1,136 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_SIDS_TO_XIDS
+   Copyright (C) Volker Lendecke 2011
+   Copyright (C) Michael Adam 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "../libcli/security/security.h"
+
+
+struct winbindd_xids_to_sids_state {
+	struct tevent_context *ev;
+
+	struct unixid *xids;
+	uint32_t num_xids;
+
+	struct dom_sid *sids;
+};
+
+static void winbindd_xids_to_sids_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_xids_to_sids_send(TALLOC_CTX *mem_ctx,
+					      struct tevent_context *ev,
+					      struct winbindd_cli_state *cli,
+					      struct winbindd_request *request)
+{
+	struct tevent_req *req, *subreq;
+	struct winbindd_xids_to_sids_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct winbindd_xids_to_sids_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+
+	DEBUG(3, ("xids_to_sids\n"));
+
+	if (request->extra_len == 0) {
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
+	}
+	if (request->extra_data.data[request->extra_len-1] != '\0') {
+		DEBUG(10, ("Got invalid xids list\n"));
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+	if (!parse_xidlist(state, request->extra_data.data,
+			   &state->xids, &state->num_xids)) {
+		DEBUG(10, ("parse_sidlist failed\n"));
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+
+	DEBUG(10, ("num_xids: %d\n", (int)state->num_xids));
+
+	subreq = wb_xids2sids_send(state, ev, state->xids, state->num_xids);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, winbindd_xids_to_sids_done, req);
+	return req;
+}
+
+static void winbindd_xids_to_sids_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct winbindd_xids_to_sids_state *state = tevent_req_data(
+		req, struct winbindd_xids_to_sids_state);
+	NTSTATUS status;
+
+	status = wb_xids2sids_recv(subreq, state, &state->sids);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+	tevent_req_done(req);
+}
+
+NTSTATUS winbindd_xids_to_sids_recv(struct tevent_req *req,
+				    struct winbindd_response *response)
+{
+	struct winbindd_xids_to_sids_state *state = tevent_req_data(
+		req, struct winbindd_xids_to_sids_state);
+	NTSTATUS status;
+	char *result = NULL;
+	uint32_t i;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		DEBUG(5, ("Could not convert sids: %s\n", nt_errstr(status)));
+		return status;
+	}
+
+	result = talloc_strdup(response, "");
+	if (result == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	for (i=0; i<state->num_xids; i++) {
+		char sidbuf[DOM_SID_STR_BUFLEN];
+
+		if (is_null_sid(&state->sids[i])) {
+			strlcpy(sidbuf, "-", sizeof(sidbuf));
+		} else {
+			dom_sid_string_buf(&state->sids[i],
+					   sidbuf, sizeof(sidbuf));
+		}
+
+		result = talloc_asprintf_append_buffer(
+			result, "%s\n", sidbuf);
+		if (result == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+
+	response->extra_data.data = result;
+	response->length += talloc_get_size(result);
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/wscript_build b/source3/wscript_build
index 67a787e..a14551f 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -951,6 +951,7 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/winbindd_uid_to_sid.c
                  winbindd/winbindd_gid_to_sid.c
                  winbindd/winbindd_sids_to_xids.c
+                 winbindd/winbindd_xids_to_sids.c
                  winbindd/winbindd_allocate_uid.c
                  winbindd/winbindd_allocate_gid.c
                  winbindd/winbindd_getpwsid.c
-- 
1.7.9.5


From 3c539da590cacbd3b5e4742df36e72d8caf5ced0 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 14 Aug 2015 11:55:37 +0200
Subject: [PATCH 08/26] libwbclient: Implement wbc[Ctx]UnixIdsToSids

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/libwbclient/ABI/wbclient-0.13.sigs |  132 +++++++++++++++++++++++++++
 nsswitch/libwbclient/wbc_idmap.c            |   85 +++++++++++++++++
 nsswitch/libwbclient/wbclient.h             |    9 +-
 nsswitch/libwbclient/wscript                |    2 +-
 4 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 nsswitch/libwbclient/ABI/wbclient-0.13.sigs

diff --git a/nsswitch/libwbclient/ABI/wbclient-0.13.sigs b/nsswitch/libwbclient/ABI/wbclient-0.13.sigs
new file mode 100644
index 0000000..b07a6a8
--- /dev/null
+++ b/nsswitch/libwbclient/ABI/wbclient-0.13.sigs
@@ -0,0 +1,132 @@
+wbcAddNamedBlob: wbcErr (size_t *, struct wbcNamedBlob **, const char *, uint32_t, uint8_t *, size_t)
+wbcAllocateGid: wbcErr (gid_t *)
+wbcAllocateMemory: void *(size_t, size_t, void (*)(void *))
+wbcAllocateStringArray: const char **(int)
+wbcAllocateUid: wbcErr (uid_t *)
+wbcAuthenticateUser: wbcErr (const char *, const char *)
+wbcAuthenticateUserEx: wbcErr (const struct wbcAuthUserParams *, struct wbcAuthUserInfo **, struct wbcAuthErrorInfo **)
+wbcChangeTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **)
+wbcChangeUserPassword: wbcErr (const char *, const char *, const char *)
+wbcChangeUserPasswordEx: wbcErr (const struct wbcChangePasswordParams *, struct wbcAuthErrorInfo **, enum wbcPasswordChangeRejectReason *, struct wbcUserPasswordPolicyInfo **)
+wbcCheckTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **)
+wbcCredentialCache: wbcErr (struct wbcCredentialCacheParams *, struct wbcCredentialCacheInfo **, struct wbcAuthErrorInfo **)
+wbcCredentialSave: wbcErr (const char *, const char *)
+wbcCtxAllocateGid: wbcErr (struct wbcContext *, gid_t *)
+wbcCtxAllocateUid: wbcErr (struct wbcContext *, uid_t *)
+wbcCtxAuthenticateUser: wbcErr (struct wbcContext *, const char *, const char *)
+wbcCtxAuthenticateUserEx: wbcErr (struct wbcContext *, const struct wbcAuthUserParams *, struct wbcAuthUserInfo **, struct wbcAuthErrorInfo **)
+wbcCtxChangeTrustCredentials: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **)
+wbcCtxChangeUserPassword: wbcErr (struct wbcContext *, const char *, const char *, const char *)
+wbcCtxChangeUserPasswordEx: wbcErr (struct wbcContext *, const struct wbcChangePasswordParams *, struct wbcAuthErrorInfo **, enum wbcPasswordChangeRejectReason *, struct wbcUserPasswordPolicyInfo **)
+wbcCtxCheckTrustCredentials: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **)
+wbcCtxCreate: struct wbcContext *(void)
+wbcCtxCredentialCache: wbcErr (struct wbcContext *, struct wbcCredentialCacheParams *, struct wbcCredentialCacheInfo **, struct wbcAuthErrorInfo **)
+wbcCtxCredentialSave: wbcErr (struct wbcContext *, const char *, const char *)
+wbcCtxDcInfo: wbcErr (struct wbcContext *, const char *, size_t *, const char ***, const char ***)
+wbcCtxDomainInfo: wbcErr (struct wbcContext *, const char *, struct wbcDomainInfo **)
+wbcCtxEndgrent: wbcErr (struct wbcContext *)
+wbcCtxEndpwent: wbcErr (struct wbcContext *)
+wbcCtxFree: void (struct wbcContext *)
+wbcCtxGetDisplayName: wbcErr (struct wbcContext *, const struct wbcDomainSid *, char **, char **, enum wbcSidType *)
+wbcCtxGetGroups: wbcErr (struct wbcContext *, const char *, uint32_t *, gid_t **)
+wbcCtxGetSidAliases: wbcErr (struct wbcContext *, const struct wbcDomainSid *, struct wbcDomainSid *, uint32_t, uint32_t **, uint32_t *)
+wbcCtxGetgrent: wbcErr (struct wbcContext *, struct group **)
+wbcCtxGetgrgid: wbcErr (struct wbcContext *, gid_t, struct group **)
+wbcCtxGetgrlist: wbcErr (struct wbcContext *, struct group **)
+wbcCtxGetgrnam: wbcErr (struct wbcContext *, const char *, struct group **)
+wbcCtxGetpwent: wbcErr (struct wbcContext *, struct passwd **)
+wbcCtxGetpwnam: wbcErr (struct wbcContext *, const char *, struct passwd **)
+wbcCtxGetpwsid: wbcErr (struct wbcContext *, struct wbcDomainSid *, struct passwd **)
+wbcCtxGetpwuid: wbcErr (struct wbcContext *, uid_t, struct passwd **)
+wbcCtxGidToSid: wbcErr (struct wbcContext *, gid_t, struct wbcDomainSid *)
+wbcCtxInterfaceDetails: wbcErr (struct wbcContext *, struct wbcInterfaceDetails **)
+wbcCtxListGroups: wbcErr (struct wbcContext *, const char *, uint32_t *, const char ***)
+wbcCtxListTrusts: wbcErr (struct wbcContext *, struct wbcDomainInfo **, size_t *)
+wbcCtxListUsers: wbcErr (struct wbcContext *, const char *, uint32_t *, const char ***)
+wbcCtxLogoffUser: wbcErr (struct wbcContext *, const char *, uid_t, const char *)
+wbcCtxLogoffUserEx: wbcErr (struct wbcContext *, const struct wbcLogoffUserParams *, struct wbcAuthErrorInfo **)
+wbcCtxLogonUser: wbcErr (struct wbcContext *, const struct wbcLogonUserParams *, struct wbcLogonUserInfo **, struct wbcAuthErrorInfo **, struct wbcUserPasswordPolicyInfo **)
+wbcCtxLookupDomainController: wbcErr (struct wbcContext *, const char *, uint32_t, struct wbcDomainControllerInfo **)
+wbcCtxLookupDomainControllerEx: wbcErr (struct wbcContext *, const char *, struct wbcGuid *, const char *, uint32_t, struct wbcDomainControllerInfoEx **)
+wbcCtxLookupName: wbcErr (struct wbcContext *, const char *, const char *, struct wbcDomainSid *, enum wbcSidType *)
+wbcCtxLookupRids: wbcErr (struct wbcContext *, struct wbcDomainSid *, int, uint32_t *, const char **, const char ***, enum wbcSidType **)
+wbcCtxLookupSid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, char **, char **, enum wbcSidType *)
+wbcCtxLookupSids: wbcErr (struct wbcContext *, const struct wbcDomainSid *, int, struct wbcDomainInfo **, int *, struct wbcTranslatedName **)
+wbcCtxLookupUserSids: wbcErr (struct wbcContext *, const struct wbcDomainSid *, bool, uint32_t *, struct wbcDomainSid **)
+wbcCtxPing: wbcErr (struct wbcContext *)
+wbcCtxPingDc: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **)
+wbcCtxPingDc2: wbcErr (struct wbcContext *, const char *, struct wbcAuthErrorInfo **, char **)
+wbcCtxResolveWinsByIP: wbcErr (struct wbcContext *, const char *, char **)
+wbcCtxResolveWinsByName: wbcErr (struct wbcContext *, const char *, char **)
+wbcCtxSetgrent: wbcErr (struct wbcContext *)
+wbcCtxSetpwent: wbcErr (struct wbcContext *)
+wbcCtxSidToGid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, gid_t *)
+wbcCtxSidToUid: wbcErr (struct wbcContext *, const struct wbcDomainSid *, uid_t *)
+wbcCtxSidsToUnixIds: wbcErr (struct wbcContext *, const struct wbcDomainSid *, uint32_t, struct wbcUnixId *)
+wbcCtxUidToSid: wbcErr (struct wbcContext *, uid_t, struct wbcDomainSid *)
+wbcCtxUnixIdsToSids: wbcErr (struct wbcContext *, const struct wbcUnixId *, uint32_t, struct wbcDomainSid *)
+wbcDcInfo: wbcErr (const char *, size_t *, const char ***, const char ***)
+wbcDomainInfo: wbcErr (const char *, struct wbcDomainInfo **)
+wbcEndgrent: wbcErr (void)
+wbcEndpwent: wbcErr (void)
+wbcErrorString: const char *(wbcErr)
+wbcFreeMemory: void (void *)
+wbcGetDisplayName: wbcErr (const struct wbcDomainSid *, char **, char **, enum wbcSidType *)
+wbcGetGlobalCtx: struct wbcContext *(void)
+wbcGetGroups: wbcErr (const char *, uint32_t *, gid_t **)
+wbcGetSidAliases: wbcErr (const struct wbcDomainSid *, struct wbcDomainSid *, uint32_t, uint32_t **, uint32_t *)
+wbcGetgrent: wbcErr (struct group **)
+wbcGetgrgid: wbcErr (gid_t, struct group **)
+wbcGetgrlist: wbcErr (struct group **)
+wbcGetgrnam: wbcErr (const char *, struct group **)
+wbcGetpwent: wbcErr (struct passwd **)
+wbcGetpwnam: wbcErr (const char *, struct passwd **)
+wbcGetpwsid: wbcErr (struct wbcDomainSid *, struct passwd **)
+wbcGetpwuid: wbcErr (uid_t, struct passwd **)
+wbcGidToSid: wbcErr (gid_t, struct wbcDomainSid *)
+wbcGuidToString: wbcErr (const struct wbcGuid *, char **)
+wbcInterfaceDetails: wbcErr (struct wbcInterfaceDetails **)
+wbcLibraryDetails: wbcErr (struct wbcLibraryDetails **)
+wbcListGroups: wbcErr (const char *, uint32_t *, const char ***)
+wbcListTrusts: wbcErr (struct wbcDomainInfo **, size_t *)
+wbcListUsers: wbcErr (const char *, uint32_t *, const char ***)
+wbcLogoffUser: wbcErr (const char *, uid_t, const char *)
+wbcLogoffUserEx: wbcErr (const struct wbcLogoffUserParams *, struct wbcAuthErrorInfo **)
+wbcLogonUser: wbcErr (const struct wbcLogonUserParams *, struct wbcLogonUserInfo **, struct wbcAuthErrorInfo **, struct wbcUserPasswordPolicyInfo **)
+wbcLookupDomainController: wbcErr (const char *, uint32_t, struct wbcDomainControllerInfo **)
+wbcLookupDomainControllerEx: wbcErr (const char *, struct wbcGuid *, const char *, uint32_t, struct wbcDomainControllerInfoEx **)
+wbcLookupName: wbcErr (const char *, const char *, struct wbcDomainSid *, enum wbcSidType *)
+wbcLookupRids: wbcErr (struct wbcDomainSid *, int, uint32_t *, const char **, const char ***, enum wbcSidType **)
+wbcLookupSid: wbcErr (const struct wbcDomainSid *, char **, char **, enum wbcSidType *)
+wbcLookupSids: wbcErr (const struct wbcDomainSid *, int, struct wbcDomainInfo **, int *, struct wbcTranslatedName **)
+wbcLookupUserSids: wbcErr (const struct wbcDomainSid *, bool, uint32_t *, struct wbcDomainSid **)
+wbcPing: wbcErr (void)
+wbcPingDc: wbcErr (const char *, struct wbcAuthErrorInfo **)
+wbcPingDc2: wbcErr (const char *, struct wbcAuthErrorInfo **, char **)
+wbcQueryGidToSid: wbcErr (gid_t, struct wbcDomainSid *)
+wbcQuerySidToGid: wbcErr (const struct wbcDomainSid *, gid_t *)
+wbcQuerySidToUid: wbcErr (const struct wbcDomainSid *, uid_t *)
+wbcQueryUidToSid: wbcErr (uid_t, struct wbcDomainSid *)
+wbcRemoveGidMapping: wbcErr (gid_t, const struct wbcDomainSid *)
+wbcRemoveUidMapping: wbcErr (uid_t, const struct wbcDomainSid *)
+wbcRequestResponse: wbcErr (struct wbcContext *, int, struct winbindd_request *, struct winbindd_response *)
+wbcRequestResponsePriv: wbcErr (struct wbcContext *, int, struct winbindd_request *, struct winbindd_response *)
+wbcResolveWinsByIP: wbcErr (const char *, char **)
+wbcResolveWinsByName: wbcErr (const char *, char **)
+wbcSetGidHwm: wbcErr (gid_t)
+wbcSetGidMapping: wbcErr (gid_t, const struct wbcDomainSid *)
+wbcSetUidHwm: wbcErr (uid_t)
+wbcSetUidMapping: wbcErr (uid_t, const struct wbcDomainSid *)
+wbcSetgrent: wbcErr (void)
+wbcSetpwent: wbcErr (void)
+wbcSidToGid: wbcErr (const struct wbcDomainSid *, gid_t *)
+wbcSidToString: wbcErr (const struct wbcDomainSid *, char **)
+wbcSidToStringBuf: int (const struct wbcDomainSid *, char *, int)
+wbcSidToUid: wbcErr (const struct wbcDomainSid *, uid_t *)
+wbcSidTypeString: const char *(enum wbcSidType)
+wbcSidsToUnixIds: wbcErr (const struct wbcDomainSid *, uint32_t, struct wbcUnixId *)
+wbcStrDup: char *(const char *)
+wbcStringToGuid: wbcErr (const char *, struct wbcGuid *)
+wbcStringToSid: wbcErr (const char *, struct wbcDomainSid *)
+wbcUidToSid: wbcErr (uid_t, struct wbcDomainSid *)
+wbcUnixIdsToSids: wbcErr (const struct wbcUnixId *, uint32_t, struct wbcDomainSid *)
diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index 3e8366a..cc5fce6 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -433,3 +433,88 @@ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
 {
 	return wbcCtxSidsToUnixIds(NULL, sids, num_sids, ids);
 }
+
+wbcErr wbcCtxUnixIdsToSids(struct wbcContext *ctx,
+			   const struct wbcUnixId *ids, uint32_t num_ids,
+			   struct wbcDomainSid *sids)
+{
+	struct winbindd_request request;
+	struct winbindd_response response;
+	wbcErr wbc_status;
+	char *buf;
+	char *s;
+	size_t ofs, buflen;
+	uint32_t i;
+
+	buflen = num_ids * (1 /* U/G */ + 10 /* 2^32 */ + 1 /* \n */) + 1;
+	buf = malloc(buflen);
+	if (buf == NULL) {
+		return WBC_ERR_NO_MEMORY;
+	}
+
+	ofs = 0;
+
+	for (i=0; i<num_ids; i++) {
+		const struct wbcUnixId *id = &ids[i];
+		int len;
+
+		switch (id->type) {
+		case WBC_ID_TYPE_UID:
+			len = snprintf(buf+ofs, buflen-ofs, "U%"PRIu32"\n",
+				       (uint32_t)id->id.uid);
+			break;
+		case WBC_ID_TYPE_GID:
+			len = snprintf(buf+ofs, buflen-ofs, "G%"PRIu32"\n",
+				       (uint32_t)id->id.gid);
+			break;
+		default:
+			free(buf);
+			return WBC_ERR_INVALID_PARAM;
+		}
+
+		if (len + ofs >= buflen) { /* >= for the terminating '\0' */
+			free(buf);
+			return WBC_ERR_UNKNOWN_FAILURE;
+		}
+		ofs += len;
+	}
+
+	request = (struct winbindd_request) {
+		.extra_data.data = buf, .extra_len = ofs+1
+	};
+	response = (struct winbindd_response) {0};
+
+	wbc_status = wbcRequestResponse(ctx, WINBINDD_XIDS_TO_SIDS,
+					&request, &response);
+	free(buf);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		return wbc_status;
+	}
+
+	s = response.extra_data.data;
+	for (i=0; i<num_ids; i++) {
+		char *n = strchr(s, '\n');
+
+		if (n == NULL) {
+			goto fail;
+		}
+		*n = '\0';
+
+		wbc_status = wbcStringToSid(s, &sids[i]);
+		if (!WBC_ERROR_IS_OK(wbc_status)) {
+			sids[i] = (struct wbcDomainSid) {0};
+		}
+		s = n+1;
+	}
+
+	wbc_status = WBC_ERR_SUCCESS;
+fail:
+	winbindd_free_response(&response);
+	return wbc_status;
+}
+
+wbcErr wbcUnixIdsToSids(const struct wbcUnixId *ids, uint32_t num_ids,
+			struct wbcDomainSid *sids)
+{
+	return wbcCtxUnixIdsToSids(NULL, ids, num_ids, sids);
+}
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index adf8fe3..6ec8377 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -73,9 +73,10 @@ const char *wbcErrorString(wbcErr error);
  *  0.10: Added wbcPingDc2()
  *  0.11: Extended wbcAuthenticateUserEx to provide PAC parsing
  *  0.12: Added wbcCtxCreate and friends
+ *  0.13: Added wbcCtxUnixIdsToSids and wbcUnixIdsToSids
  **/
 #define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 12
+#define WBCLIENT_MINOR_VERSION 13
 #define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
 struct wbcLibraryDetails {
 	uint16_t major_version;
@@ -1030,6 +1031,12 @@ wbcErr wbcCtxSidsToUnixIds(struct wbcContext *ctx,
 wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
 			struct wbcUnixId *ids);
 
+wbcErr wbcCtxUnixIdsToSids(struct wbcContext *ctx,
+			   const struct wbcUnixId *ids, uint32_t num_ids,
+			   struct wbcDomainSid *sids);
+wbcErr wbcUnixIdsToSids(const struct wbcUnixId *ids, uint32_t num_ids,
+			struct wbcDomainSid *sids);
+
 /**
  * @brief Obtain a new uid from Winbind
  *
diff --git a/nsswitch/libwbclient/wscript b/nsswitch/libwbclient/wscript
index 8602c1c..5c5002a 100644
--- a/nsswitch/libwbclient/wscript
+++ b/nsswitch/libwbclient/wscript
@@ -3,7 +3,7 @@
 import Options, Logs
 
 # Remember to also update wbclient.h
-VERSION="0.12"
+VERSION="0.13"
 
 # It may be useful at some point to allow Samba to build against a
 # system libwbclient, such as the one provided by Likewise.  To to
-- 
1.7.9.5


From 88f686240e1d9b9e565b0a17c726f47f16224dd0 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 14 Aug 2015 17:13:57 +0200
Subject: [PATCH 09/26] wbinfo: Add --unix-ids-to-sids

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/wbinfo.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 330fa91..f7b5ace 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -1046,6 +1046,72 @@ static bool wbinfo_sids_to_unix_ids(const char *arg)
 	return true;
 }
 
+static bool wbinfo_xids_to_sids(const char *arg)
+{
+	fstring idstr;
+	struct wbcUnixId *xids = NULL;
+	struct wbcDomainSid *sids;
+	wbcErr wbc_status;
+	int num_xids = 0;
+	const char *p;
+	int i;
+
+	p = arg;
+
+	while (next_token(&p, idstr, LIST_SEP, sizeof(idstr))) {
+		xids = talloc_realloc(talloc_tos(), xids, struct wbcUnixId,
+				      num_xids+1);
+		if (xids == NULL) {
+			d_fprintf(stderr, "talloc failed\n");
+			return false;
+		}
+
+		switch (idstr[0]) {
+		case 'u':
+			xids[num_xids] = (struct wbcUnixId) {
+				.type = WBC_ID_TYPE_UID,
+				.id.uid = atoi(&idstr[1])
+			};
+			break;
+		case 'g':
+			xids[num_xids] = (struct wbcUnixId) {
+				.type = WBC_ID_TYPE_GID,
+				.id.gid = atoi(&idstr[1])
+			};
+			break;
+		default:
+			d_fprintf(stderr, "%s is an invalid id\n", idstr);
+			TALLOC_FREE(xids);
+			return false;
+		}
+		num_xids += 1;
+	}
+
+	sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_xids);
+	if (sids == NULL) {
+		d_fprintf(stderr, "talloc failed\n");
+		TALLOC_FREE(xids);
+		return false;
+	}
+
+	wbc_status = wbcUnixIdsToSids(xids, num_xids, sids);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		d_fprintf(stderr, "wbcUnixIdsToSids failed: %s\n",
+			  wbcErrorString(wbc_status));
+		TALLOC_FREE(sids);
+		TALLOC_FREE(xids);
+		return false;
+	}
+
+	for (i=0; i<num_xids; i++) {
+		char str[WBC_SID_STRING_BUFLEN];
+		wbcSidToStringBuf(&sids[i], str, sizeof(str));
+		d_printf("%s\n", str);
+	}
+
+	return true;
+}
+
 static bool wbinfo_allocate_uid(void)
 {
 	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
@@ -2149,6 +2215,7 @@ enum {
 	OPT_REMOVE_UID_MAPPING,
 	OPT_REMOVE_GID_MAPPING,
 	OPT_SIDS_TO_XIDS,
+	OPT_XIDS_TO_SIDS,
 	OPT_SEPARATOR,
 	OPT_LIST_ALL_DOMAINS,
 	OPT_LIST_OWN_DOMAIN,
@@ -2220,6 +2287,9 @@ int main(int argc, const char **argv, char **envp)
 		{ "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
 		{ "sids-to-unix-ids", 0, POPT_ARG_STRING, &string_arg,
 		  OPT_SIDS_TO_XIDS, "Translate SIDs to Unix IDs", "Sid-List" },
+		{ "unix-ids-to-sids", 0, POPT_ARG_STRING, &string_arg,
+		  OPT_XIDS_TO_SIDS, "Translate Unix IDs to SIDs",
+		  "ID-List (u<num> g<num>)" },
 		{ "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
 		{ "change-secret", 'c', POPT_ARG_NONE, 0, 'c', "Change shared secret" },
 		{ "ping-dc", 'P', POPT_ARG_NONE, 0, 'P',
@@ -2476,6 +2546,13 @@ int main(int argc, const char **argv, char **envp)
 				goto done;
 			}
 			break;
+		case OPT_XIDS_TO_SIDS:
+			if (!wbinfo_xids_to_sids(string_arg)) {
+				d_fprintf(stderr, "wbinfo_xids_to_sids "
+					  "failed\n");
+				goto done;
+			}
+			break;
 		case 't':
 			if (!wbinfo_check_secret(opt_domain_name)) {
 				d_fprintf(stderr, "Could not check secret\n");
-- 
1.7.9.5


From abeb773323dd0dc779f243cc3ec510376ed43e35 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:34:38 +0100
Subject: [PATCH 10/26] winbind: Use xids2sids in uid2sid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_uid_to_sid.c |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/source3/winbindd/winbindd_uid_to_sid.c b/source3/winbindd/winbindd_uid_to_sid.c
index 653a96f..d0ea9c6 100644
--- a/source3/winbindd/winbindd_uid_to_sid.c
+++ b/source3/winbindd/winbindd_uid_to_sid.c
@@ -19,11 +19,12 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "libcli/security/dom_sid.h"
 
 struct winbindd_uid_to_sid_state {
 	struct tevent_context *ev;
-	uid_t uid;
-	struct dom_sid sid;
+	struct unixid xid;
+	struct dom_sid *sid;
 };
 
 static void winbindd_uid_to_sid_done(struct tevent_req *subreq);
@@ -45,7 +46,10 @@ struct tevent_req *winbindd_uid_to_sid_send(TALLOC_CTX *mem_ctx,
 
 	DEBUG(3, ("uid_to_sid %d\n", (int)request->data.uid));
 
-	subreq = wb_uid2sid_send(state, ev, request->data.uid);
+	state->xid = (struct unixid) {
+		.id = request->data.uid, .type = ID_TYPE_UID };
+
+	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -61,7 +65,7 @@ static void winbindd_uid_to_sid_done(struct tevent_req *subreq)
 		req, struct winbindd_uid_to_sid_state);
 	NTSTATUS status;
 
-	status = wb_uid2sid_recv(subreq, &state->sid);
+	status = wb_xids2sids_recv(subreq, state, &state->sid);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
@@ -78,10 +82,13 @@ NTSTATUS winbindd_uid_to_sid_recv(struct tevent_req *req,
 
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
+			  sid_string_dbg(state->sid), nt_errstr(status)));
 		return status;
 	}
-	sid_to_fstring(response->data.sid.sid, &state->sid);
+	if (is_null_sid(state->sid)) {
+		return NT_STATUS_NONE_MAPPED;
+	}
+	sid_to_fstring(response->data.sid.sid, state->sid);
 	response->data.sid.type = SID_NAME_USER;
 	return NT_STATUS_OK;
 }
-- 
1.7.9.5


From fecdd9baf68ae2037a9c2ead3a0f5a2fa94b097a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:34:38 +0100
Subject: [PATCH 11/26] winbind: Use xids2sids in getpwuid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_getpwuid.c |   19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/source3/winbindd/winbindd_getpwuid.c b/source3/winbindd/winbindd_getpwuid.c
index 30f3a04..d7a1f4d 100644
--- a/source3/winbindd/winbindd_getpwuid.c
+++ b/source3/winbindd/winbindd_getpwuid.c
@@ -19,10 +19,12 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "libcli/security/dom_sid.h"
 
 struct winbindd_getpwuid_state {
 	struct tevent_context *ev;
-	struct dom_sid sid;
+	struct unixid xid;
+	struct dom_sid *sid;
 	struct winbindd_pw pw;
 };
 
@@ -46,7 +48,10 @@ struct tevent_req *winbindd_getpwuid_send(TALLOC_CTX *mem_ctx,
 
 	DEBUG(3, ("getpwuid %d\n", (int)request->data.uid));
 
-	subreq = wb_uid2sid_send(state, ev, request->data.uid);
+	state->xid = (struct unixid) {
+		.id = request->data.uid, .type = ID_TYPE_UID };
+
+	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -63,13 +68,17 @@ static void winbindd_getpwuid_uid2sid_done(struct tevent_req *subreq)
 		req, struct winbindd_getpwuid_state);
 	NTSTATUS status;
 
-	status = wb_uid2sid_recv(subreq, &state->sid);
+	status = wb_xids2sids_recv(subreq, state, &state->sid);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
+	if (is_null_sid(state->sid)) {
+		tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
+		return;
+	}
 
-	subreq = wb_getpwsid_send(state, state->ev, &state->sid, &state->pw);
+	subreq = wb_getpwsid_send(state, state->ev, state->sid, &state->pw);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
@@ -99,7 +108,7 @@ NTSTATUS winbindd_getpwuid_recv(struct tevent_req *req,
 
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
+			  sid_string_dbg(state->sid), nt_errstr(status)));
 		return status;
 	}
 	response->data.pw = state->pw;
-- 
1.7.9.5


From 02aa78658939fe3850f2893ed9bf482f0eb55432 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:43:58 +0100
Subject: [PATCH 12/26] winbind: Remove unused wbint_Uid2Sid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 librpc/idl/winbind.idl               |    5 --
 source3/winbindd/wb_uid2sid.c        |  105 ----------------------------------
 source3/winbindd/winbindd_dual_srv.c |    5 --
 source3/winbindd/winbindd_proto.h    |    5 --
 source3/wscript_build                |    1 -
 5 files changed, 121 deletions(-)
 delete mode 100644 source3/winbindd/wb_uid2sid.c

diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl
index 7150e3f..e4288e2 100644
--- a/librpc/idl/winbind.idl
+++ b/librpc/idl/winbind.idl
@@ -56,11 +56,6 @@ interface winbind
 	[in,out] wbint_TransIDArray *ids
 	);
 
-    NTSTATUS wbint_Uid2Sid(
-	[in] hyper uid,
-	[out] dom_sid *sid
-	);
-
     NTSTATUS wbint_Gid2Sid(
 	[in] hyper gid,
 	[out] dom_sid *sid
diff --git a/source3/winbindd/wb_uid2sid.c b/source3/winbindd/wb_uid2sid.c
deleted file mode 100644
index c95bcd9..0000000
--- a/source3/winbindd/wb_uid2sid.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async uid2sid
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "librpc/gen_ndr/ndr_winbind_c.h"
-#include "idmap_cache.h"
-#include "idmap.h"
-#include "../libcli/security/security.h"
-
-struct wb_uid2sid_state {
-	struct tevent_context *ev;
-	struct dom_sid sid;
-};
-
-static void wb_uid2sid_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_uid2sid_send(TALLOC_CTX *mem_ctx,
-				   struct tevent_context *ev,
-				   uid_t uid)
-{
-	struct tevent_req *req, *subreq;
-	struct wb_uid2sid_state *state;
-	struct winbindd_child *child;
-	bool expired;
-
-	req = tevent_req_create(mem_ctx, &state, struct wb_uid2sid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	if (winbindd_use_idmap_cache()
-	    && idmap_cache_find_uid2sid(uid, &state->sid, &expired)) {
-
-		DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n",
-			   (int)uid, expired ? " (expired)": ""));
-
-		if (!expired || idmap_is_offline()) {
-			if (is_null_sid(&state->sid)) {
-				tevent_req_nterror(req,
-						   NT_STATUS_NONE_MAPPED);
-			} else {
-				tevent_req_done(req);
-			}
-			return tevent_req_post(req, ev);
-		}
-	}
-
-	child = idmap_child();
-
-	subreq = dcerpc_wbint_Uid2Sid_send(
-		state, ev, child->binding_handle,
-		uid, &state->sid);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, wb_uid2sid_done, req);
-	return req;
-}
-
-static void wb_uid2sid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct wb_uid2sid_state *state = tevent_req_data(
-		req, struct wb_uid2sid_state);
-	NTSTATUS status, result;
-
-	status = dcerpc_wbint_Uid2Sid_recv(subreq, state, &result);
-	TALLOC_FREE(subreq);
-	if (any_nt_status_not_ok(status, result, &status)) {
-		tevent_req_nterror(req, status);
-		return;
-	}
-	tevent_req_done(req);
-}
-
-NTSTATUS wb_uid2sid_recv(struct tevent_req *req, struct dom_sid *sid)
-{
-	struct wb_uid2sid_state *state = tevent_req_data(
-		req, struct wb_uid2sid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		return status;
-	}
-	sid_copy(sid, &state->sid);
-	return NT_STATUS_OK;
-}
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index d6070707..4d6c3d1 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -222,11 +222,6 @@ done:
 	return status;
 }
 
-NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
-{
-	return idmap_uid_to_sid(r->out.sid, r->in.uid);
-}
-
 NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
 {
 	return idmap_gid_to_sid(r->out.sid, r->in.gid);
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 063e793..4cce2d1 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -539,11 +539,6 @@ struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx,
 NTSTATUS winbindd_sid_to_gid_recv(struct tevent_req *req,
 				  struct winbindd_response *response);
 
-struct tevent_req *wb_uid2sid_send(TALLOC_CTX *mem_ctx,
-				   struct tevent_context *ev,
-				   uid_t uid);
-NTSTATUS wb_uid2sid_recv(struct tevent_req *req, struct dom_sid *sid);
-
 struct tevent_req *winbindd_uid_to_sid_send(TALLOC_CTX *mem_ctx,
 					    struct tevent_context *ev,
 					    struct winbindd_cli_state *cli,
diff --git a/source3/wscript_build b/source3/wscript_build
index a14551f..ad5f3b4 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -924,7 +924,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/wb_lookupsid.c
                  winbindd/wb_lookupsids.c
                  winbindd/wb_lookupname.c
-                 winbindd/wb_uid2sid.c
                  winbindd/wb_gid2sid.c
                  winbindd/wb_sids2xids.c
                  winbindd/wb_xids2sids.c
-- 
1.7.9.5


From b921d2330657b7a65729578ca2b66fcdc26b34d7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:34:38 +0100
Subject: [PATCH 13/26] winbind: Use xids2sids in gid2sid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_gid_to_sid.c |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/source3/winbindd/winbindd_gid_to_sid.c b/source3/winbindd/winbindd_gid_to_sid.c
index 4a378d3..b1644ec 100644
--- a/source3/winbindd/winbindd_gid_to_sid.c
+++ b/source3/winbindd/winbindd_gid_to_sid.c
@@ -19,11 +19,12 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "libcli/security/dom_sid.h"
 
 struct winbindd_gid_to_sid_state {
 	struct tevent_context *ev;
-	gid_t gid;
-	struct dom_sid sid;
+	struct unixid xid;
+	struct dom_sid *sid;
 };
 
 static void winbindd_gid_to_sid_done(struct tevent_req *subreq);
@@ -45,7 +46,10 @@ struct tevent_req *winbindd_gid_to_sid_send(TALLOC_CTX *mem_ctx,
 
 	DEBUG(3, ("gid_to_sid %d\n", (int)request->data.gid));
 
-	subreq = wb_gid2sid_send(state, ev, request->data.gid);
+	state->xid = (struct unixid) {
+		.id = request->data.gid, .type = ID_TYPE_GID };
+
+	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -61,7 +65,7 @@ static void winbindd_gid_to_sid_done(struct tevent_req *subreq)
 		req, struct winbindd_gid_to_sid_state);
 	NTSTATUS status;
 
-	status = wb_gid2sid_recv(subreq, &state->sid);
+	status = wb_xids2sids_recv(subreq, state, &state->sid);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
@@ -78,10 +82,13 @@ NTSTATUS winbindd_gid_to_sid_recv(struct tevent_req *req,
 
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
+			  sid_string_dbg(state->sid), nt_errstr(status)));
 		return status;
 	}
-	sid_to_fstring(response->data.sid.sid, &state->sid);
+	if (is_null_sid(state->sid)) {
+		return NT_STATUS_NONE_MAPPED;
+	}
+	sid_to_fstring(response->data.sid.sid, state->sid);
 	response->data.sid.type = SID_NAME_USER;
 	return NT_STATUS_OK;
 }
-- 
1.7.9.5


From 09efcf89d74e623ac06b5bbeebc16f7325bb7365 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:34:38 +0100
Subject: [PATCH 14/26] winbind: Use xids2sids in getgrgid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/winbindd/winbindd_getgrgid.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/source3/winbindd/winbindd_getgrgid.c b/source3/winbindd/winbindd_getgrgid.c
index 0f12fa4..8e8bdee 100644
--- a/source3/winbindd/winbindd_getgrgid.c
+++ b/source3/winbindd/winbindd_getgrgid.c
@@ -19,10 +19,12 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "libcli/security/dom_sid.h"
 
 struct winbindd_getgrgid_state {
 	struct tevent_context *ev;
-	struct dom_sid sid;
+	struct unixid xid;
+	struct dom_sid *sid;
 	const char *domname;
 	const char *name;
 	gid_t gid;
@@ -49,7 +51,10 @@ struct tevent_req *winbindd_getgrgid_send(TALLOC_CTX *mem_ctx,
 
 	DEBUG(3, ("getgrgid %d\n", (int)request->data.gid));
 
-	subreq = wb_gid2sid_send(state, ev, request->data.gid);
+	state->xid = (struct unixid) {
+		.id = request->data.uid, .type = ID_TYPE_GID };
+
+	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -66,13 +71,13 @@ static void winbindd_getgrgid_gid2sid_done(struct tevent_req *subreq)
 		req, struct winbindd_getgrgid_state);
 	NTSTATUS status;
 
-	status = wb_gid2sid_recv(subreq, &state->sid);
+	status = wb_xids2sids_recv(subreq, state, &state->sid);
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
 
-	subreq = wb_getgrsid_send(state, state->ev, &state->sid,
+	subreq = wb_getgrsid_send(state, state->ev, state->sid,
 				  lp_winbind_expand_groups());
 	if (tevent_req_nomem(subreq, req)) {
 		return;
@@ -108,7 +113,7 @@ NTSTATUS winbindd_getgrgid_recv(struct tevent_req *req,
 
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
+			  sid_string_dbg(state->sid), nt_errstr(status)));
 		return status;
 	}
 
-- 
1.7.9.5


From 7b7c8b52d99c6acb6c1c75630358557e317bbdc3 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 8 Feb 2016 17:43:58 +0100
Subject: [PATCH 15/26] winbind: Remove unused wbint_Gid2Sid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 librpc/idl/winbind.idl               |    5 --
 source3/winbindd/wb_gid2sid.c        |  105 ----------------------------------
 source3/winbindd/winbindd_dual_srv.c |    5 --
 source3/winbindd/winbindd_proto.h    |    5 --
 source3/wscript_build                |    1 -
 5 files changed, 121 deletions(-)
 delete mode 100644 source3/winbindd/wb_gid2sid.c

diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl
index e4288e2..b1aed30 100644
--- a/librpc/idl/winbind.idl
+++ b/librpc/idl/winbind.idl
@@ -56,11 +56,6 @@ interface winbind
 	[in,out] wbint_TransIDArray *ids
 	);
 
-    NTSTATUS wbint_Gid2Sid(
-	[in] hyper gid,
-	[out] dom_sid *sid
-	);
-
     NTSTATUS wbint_UnixIDs2Sids(
 	[in] uint32 num_ids,
 	[in] unixid xids[num_ids],
diff --git a/source3/winbindd/wb_gid2sid.c b/source3/winbindd/wb_gid2sid.c
deleted file mode 100644
index 97cc754..0000000
--- a/source3/winbindd/wb_gid2sid.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async gid2sid
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "librpc/gen_ndr/ndr_winbind_c.h"
-#include "idmap_cache.h"
-#include "idmap.h"
-#include "../libcli/security/security.h"
-
-struct wb_gid2sid_state {
-	struct tevent_context *ev;
-	struct dom_sid sid;
-};
-
-static void wb_gid2sid_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_gid2sid_send(TALLOC_CTX *mem_ctx,
-				   struct tevent_context *ev,
-				   gid_t gid)
-{
-	struct tevent_req *req, *subreq;
-	struct wb_gid2sid_state *state;
-	struct winbindd_child *child;
-	bool expired;
-
-	req = tevent_req_create(mem_ctx, &state, struct wb_gid2sid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	if (winbindd_use_idmap_cache()
-	    && idmap_cache_find_gid2sid(gid, &state->sid, &expired)) {
-
-		DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n",
-			   (int)gid, expired ? " (expired)": ""));
-
-		if (!expired || idmap_is_offline()) {
-			if (is_null_sid(&state->sid)) {
-				tevent_req_nterror(req,
-						   NT_STATUS_NONE_MAPPED);
-			} else {
-				tevent_req_done(req);
-			}
-			return tevent_req_post(req, ev);
-		}
-	}
-
-	child = idmap_child();
-
-	subreq = dcerpc_wbint_Gid2Sid_send(
-		state, ev, child->binding_handle,
-		gid, &state->sid);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, wb_gid2sid_done, req);
-	return req;
-}
-
-static void wb_gid2sid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct wb_gid2sid_state *state = tevent_req_data(
-		req, struct wb_gid2sid_state);
-	NTSTATUS status, result;
-
-	status = dcerpc_wbint_Gid2Sid_recv(subreq, state, &result);
-	TALLOC_FREE(subreq);
-	if (any_nt_status_not_ok(status, result, &status)) {
-		tevent_req_nterror(req, status);
-		return;
-	}
-	tevent_req_done(req);
-}
-
-NTSTATUS wb_gid2sid_recv(struct tevent_req *req, struct dom_sid *sid)
-{
-	struct wb_gid2sid_state *state = tevent_req_data(
-		req, struct wb_gid2sid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		return status;
-	}
-	sid_copy(sid, &state->sid);
-	return NT_STATUS_OK;
-}
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 4d6c3d1..e42dce5 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -222,11 +222,6 @@ done:
 	return status;
 }
 
-NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
-{
-	return idmap_gid_to_sid(r->out.sid, r->in.gid);
-}
-
 NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
 			     struct wbint_UnixIDs2Sids *r)
 {
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 4cce2d1..dd389c2 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -546,11 +546,6 @@ struct tevent_req *winbindd_uid_to_sid_send(TALLOC_CTX *mem_ctx,
 NTSTATUS winbindd_uid_to_sid_recv(struct tevent_req *req,
 				  struct winbindd_response *response);
 
-struct tevent_req *wb_gid2sid_send(TALLOC_CTX *mem_ctx,
-				   struct tevent_context *ev,
-				   gid_t gid);
-NTSTATUS wb_gid2sid_recv(struct tevent_req *req, struct dom_sid *sid);
-
 struct tevent_req *winbindd_gid_to_sid_send(TALLOC_CTX *mem_ctx,
 					    struct tevent_context *ev,
 					    struct winbindd_cli_state *cli,
diff --git a/source3/wscript_build b/source3/wscript_build
index ad5f3b4..d5dbd4e 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -924,7 +924,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/wb_lookupsid.c
                  winbindd/wb_lookupsids.c
                  winbindd/wb_lookupname.c
-                 winbindd/wb_gid2sid.c
                  winbindd/wb_sids2xids.c
                  winbindd/wb_xids2sids.c
                  winbindd/wb_queryuser.c
-- 
1.7.9.5


From 900d7e27a48b3aa6e5b02322d0d4aabe8230b7f7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 07:36:13 +0100
Subject: [PATCH 16/26] libwbclient: Use wbcCtxSidsToUnixIds in wbcCtxSidToUid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/libwbclient/wbc_idmap.c |   31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index cc5fce6..88ca11b 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -29,32 +29,25 @@
 wbcErr wbcCtxSidToUid(struct wbcContext *ctx, const struct wbcDomainSid *sid,
 		      uid_t *puid)
 {
-	struct winbindd_request request;
-	struct winbindd_response response;
-	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+	struct wbcUnixId xid;
+	wbcErr wbc_status;
 
 	if (!sid || !puid) {
 		wbc_status = WBC_ERR_INVALID_PARAM;
 		BAIL_ON_WBC_ERROR(wbc_status);
 	}
 
-	/* Initialize request */
-
-	ZERO_STRUCT(request);
-	ZERO_STRUCT(response);
-
-	wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
-
-	/* Make request */
-
-	wbc_status = wbcRequestResponse(ctx, WINBINDD_SID_TO_UID,
-					&request,
-					&response);
-	BAIL_ON_WBC_ERROR(wbc_status);
-
-	*puid = response.data.uid;
+	wbc_status = wbcCtxSidsToUnixIds(ctx, sid, 1, &xid);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		goto done;
+	}
 
-	wbc_status = WBC_ERR_SUCCESS;
+	if ((xid.type == WBC_ID_TYPE_UID) || (xid.type == WBC_ID_TYPE_BOTH)) {
+		*puid = xid.id.gid;
+		wbc_status = WBC_ERR_SUCCESS;
+	} else {
+		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+	}
 
  done:
 	return wbc_status;
-- 
1.7.9.5


From 30df67e103199a147d3d5e2e9eed5a481a92d635 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 07:36:13 +0100
Subject: [PATCH 17/26] libwbclient: Use wbcCtxSidsToUnixIds in wbcCtxSidToGid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/libwbclient/wbc_idmap.c |   31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index 88ca11b..68da865 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -43,7 +43,7 @@ wbcErr wbcCtxSidToUid(struct wbcContext *ctx, const struct wbcDomainSid *sid,
 	}
 
 	if ((xid.type == WBC_ID_TYPE_UID) || (xid.type == WBC_ID_TYPE_BOTH)) {
-		*puid = xid.id.gid;
+		*puid = xid.id.uid;
 		wbc_status = WBC_ERR_SUCCESS;
 	} else {
 		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
@@ -123,30 +123,25 @@ wbcErr wbcQueryUidToSid(uid_t uid,
 wbcErr wbcCtxSidToGid(struct wbcContext *ctx, const struct wbcDomainSid *sid,
 		      gid_t *pgid)
 {
-	struct winbindd_request request;
-	struct winbindd_response response;
-	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+	struct wbcUnixId xid;
+	wbcErr wbc_status;
 
 	if (!sid || !pgid) {
 		wbc_status = WBC_ERR_INVALID_PARAM;
 		BAIL_ON_WBC_ERROR(wbc_status);
 	}
 
-	/* Initialize request */
-
-	ZERO_STRUCT(request);
-	ZERO_STRUCT(response);
-
-        wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
-
-	/* Make request */
-
-	wbc_status = wbcRequestResponse(ctx, WINBINDD_SID_TO_GID,
-					&request,
-					&response);
-	BAIL_ON_WBC_ERROR(wbc_status);
+	wbc_status = wbcCtxSidsToUnixIds(ctx, sid, 1, &xid);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		goto done;
+	}
 
-	*pgid = response.data.gid;
+	if ((xid.type == WBC_ID_TYPE_GID) || (xid.type == WBC_ID_TYPE_BOTH)) {
+		*pgid = xid.id.gid;
+		wbc_status = WBC_ERR_SUCCESS;
+	} else {
+		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+	}
 
 	wbc_status = WBC_ERR_SUCCESS;
 
-- 
1.7.9.5


From 49c5bb7aceb52139ff5b0accbc412661d3610f94 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 08:02:22 +0100
Subject: [PATCH 18/26] winbind: Remove unused WINBINDD_SID_TO_UID

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_struct_protocol.h     |    2 +-
 source3/winbindd/winbindd.c            |    2 -
 source3/winbindd/winbindd_sid_to_uid.c |  109 --------------------------------
 source3/wscript_build                  |    1 -
 4 files changed, 1 insertion(+), 113 deletions(-)
 delete mode 100644 source3/winbindd/winbindd_sid_to_uid.c

diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 178906d..004e2ed 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -54,6 +54,7 @@ typedef char fstring[FSTRING_LEN];
  * 26: added WINBINDD_DC_INFO
  * 27: added WINBINDD_LOOKUPSIDS
  * 28: added WINBINDD_XIDS_TO_SIDS
+ *     removed WINBINDD_SID_TO_UID
  */
 #define WINBIND_INTERFACE_VERSION 28
 
@@ -111,7 +112,6 @@ enum winbindd_cmd {
 
 	/* Lookup functions */
 
-	WINBINDD_SID_TO_UID,
 	WINBINDD_SID_TO_GID,
 	WINBINDD_SIDS_TO_XIDS,
 	WINBINDD_XIDS_TO_SIDS,
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index ec49ea5..e54c6f7 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -608,8 +608,6 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_lookupsids_send, winbindd_lookupsids_recv },
 	{ WINBINDD_LOOKUPNAME, "LOOKUPNAME",
 	  winbindd_lookupname_send, winbindd_lookupname_recv },
-	{ WINBINDD_SID_TO_UID, "SID_TO_UID",
-	  winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
 	{ WINBINDD_SID_TO_GID, "SID_TO_GID",
 	  winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
 	{ WINBINDD_UID_TO_SID, "UID_TO_SID",
diff --git a/source3/winbindd/winbindd_sid_to_uid.c b/source3/winbindd/winbindd_sid_to_uid.c
deleted file mode 100644
index cbab2d2..0000000
--- a/source3/winbindd/winbindd_sid_to_uid.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async implementation of WINBINDD_SID_TO_UID
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "../libcli/security/security.h"
-
-struct winbindd_sid_to_uid_state {
-	struct dom_sid sid;
-	uid_t uid;
-};
-
-static void winbindd_sid_to_uid_done(struct tevent_req *subreq);
-
-struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx,
-					    struct tevent_context *ev,
-					    struct winbindd_cli_state *cli,
-					    struct winbindd_request *request)
-{
-	struct tevent_req *req, *subreq;
-	struct winbindd_sid_to_uid_state *state;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct winbindd_sid_to_uid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	/* Ensure null termination */
-	request->data.sid[sizeof(request->data.sid)-1]='\0';
-
-	DEBUG(3, ("sid to uid %s\n", request->data.sid));
-
-	if (!string_to_sid(&state->sid, request->data.sid)) {
-		DEBUG(1, ("Could not get convert sid %s from string\n",
-			  request->data.sid));
-		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-		return tevent_req_post(req, ev);
-	}
-
-	subreq = wb_sids2xids_send(state, ev, &state->sid, 1);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, winbindd_sid_to_uid_done, req);
-	return req;
-}
-
-static void winbindd_sid_to_uid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct winbindd_sid_to_uid_state *state = tevent_req_data(
-		req, struct winbindd_sid_to_uid_state);
-	NTSTATUS status;
-	struct unixid xids[1];
-
-	status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
-	TALLOC_FREE(subreq);
-	if (tevent_req_nterror(req, status)) {
-		return;
-	}
-
-	/*
-	 * We are filtering further down in sids2xids, but that filtering
-	 * depends on the actual type of the sid handed in (as determined
-	 * by lookupsids). Here we need to filter for the type of object
-	 * actually requested, in this case uid.
-	 */
-	if (!(xids[0].type == ID_TYPE_UID || xids[0].type == ID_TYPE_BOTH)) {
-		tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
-		return;
-	}
-
-	state->uid = (uid_t)xids[0].id;
-	tevent_req_done(req);
-}
-
-NTSTATUS winbindd_sid_to_uid_recv(struct tevent_req *req,
-				  struct winbindd_response *response)
-{
-	struct winbindd_sid_to_uid_state *state = tevent_req_data(
-		req, struct winbindd_sid_to_uid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
-		return status;
-	}
-	response->data.uid = state->uid;
-	return NT_STATUS_OK;
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index d5dbd4e..b8072ba 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -944,7 +944,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/winbindd_lookupsid.c
                  winbindd/winbindd_lookupsids.c
                  winbindd/winbindd_lookupname.c
-                 winbindd/winbindd_sid_to_uid.c
                  winbindd/winbindd_sid_to_gid.c
                  winbindd/winbindd_uid_to_sid.c
                  winbindd/winbindd_gid_to_sid.c
-- 
1.7.9.5


From 638d39a5956fa85035f550278fbdc3da93fdd06f Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 08:02:22 +0100
Subject: [PATCH 19/26] winbind: Remove unused WINBINDD_SID_TO_GID

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_struct_protocol.h     |    2 +-
 source3/winbindd/winbindd.c            |    2 -
 source3/winbindd/winbindd_sid_to_gid.c |  109 --------------------------------
 source3/wscript_build                  |    1 -
 4 files changed, 1 insertion(+), 113 deletions(-)
 delete mode 100644 source3/winbindd/winbindd_sid_to_gid.c

diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 004e2ed..f24ba72 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -55,6 +55,7 @@ typedef char fstring[FSTRING_LEN];
  * 27: added WINBINDD_LOOKUPSIDS
  * 28: added WINBINDD_XIDS_TO_SIDS
  *     removed WINBINDD_SID_TO_UID
+ *     removed WINBINDD_SID_TO_GID
  */
 #define WINBIND_INTERFACE_VERSION 28
 
@@ -112,7 +113,6 @@ enum winbindd_cmd {
 
 	/* Lookup functions */
 
-	WINBINDD_SID_TO_GID,
 	WINBINDD_SIDS_TO_XIDS,
 	WINBINDD_XIDS_TO_SIDS,
 	WINBINDD_UID_TO_SID,
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index e54c6f7..e4090bd 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -608,8 +608,6 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_lookupsids_send, winbindd_lookupsids_recv },
 	{ WINBINDD_LOOKUPNAME, "LOOKUPNAME",
 	  winbindd_lookupname_send, winbindd_lookupname_recv },
-	{ WINBINDD_SID_TO_GID, "SID_TO_GID",
-	  winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
 	{ WINBINDD_UID_TO_SID, "UID_TO_SID",
 	  winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
 	{ WINBINDD_GID_TO_SID, "GID_TO_SID",
diff --git a/source3/winbindd/winbindd_sid_to_gid.c b/source3/winbindd/winbindd_sid_to_gid.c
deleted file mode 100644
index 978ed6a..0000000
--- a/source3/winbindd/winbindd_sid_to_gid.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async implementation of WINBINDD_SID_TO_GID
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "../libcli/security/security.h"
-
-struct winbindd_sid_to_gid_state {
-	struct dom_sid sid;
-	gid_t gid;
-};
-
-static void winbindd_sid_to_gid_done(struct tevent_req *subreq);
-
-struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx,
-					    struct tevent_context *ev,
-					    struct winbindd_cli_state *cli,
-					    struct winbindd_request *request)
-{
-	struct tevent_req *req, *subreq;
-	struct winbindd_sid_to_gid_state *state;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct winbindd_sid_to_gid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	/* Ensure null termination */
-	request->data.sid[sizeof(request->data.sid)-1]='\0';
-
-	DEBUG(3, ("sid to gid %s\n", request->data.sid));
-
-	if (!string_to_sid(&state->sid, request->data.sid)) {
-		DEBUG(1, ("Could not get convert sid %s from string\n",
-			  request->data.sid));
-		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-		return tevent_req_post(req, ev);
-	}
-
-	subreq = wb_sids2xids_send(state, ev, &state->sid, 1);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, winbindd_sid_to_gid_done, req);
-	return req;
-}
-
-static void winbindd_sid_to_gid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct winbindd_sid_to_gid_state *state = tevent_req_data(
-		req, struct winbindd_sid_to_gid_state);
-	NTSTATUS status;
-	struct unixid xids[1];
-
-	status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
-	TALLOC_FREE(subreq);
-	if (tevent_req_nterror(req, status)) {
-		return;
-	}
-
-	/*
-	 * We are filtering further down in sids2xids, but that filtering
-	 * depends on the actual type of the sid handed in (as determined
-	 * by lookupsids). Here we need to filter for the type of object
-	 * actually requested, in this case gid.
-	 */
-	if (!(xids[0].type == ID_TYPE_GID || xids[0].type == ID_TYPE_BOTH)) {
-		tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
-		return;
-	}
-
-	state->gid = (gid_t)xids[0].id;
-	tevent_req_done(req);
-}
-
-NTSTATUS winbindd_sid_to_gid_recv(struct tevent_req *req,
-				  struct winbindd_response *response)
-{
-	struct winbindd_sid_to_gid_state *state = tevent_req_data(
-		req, struct winbindd_sid_to_gid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(&state->sid), nt_errstr(status)));
-		return status;
-	}
-	response->data.gid = state->gid;
-	return NT_STATUS_OK;
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index b8072ba..ada41ac 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -944,7 +944,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/winbindd_lookupsid.c
                  winbindd/winbindd_lookupsids.c
                  winbindd/winbindd_lookupname.c
-                 winbindd/winbindd_sid_to_gid.c
                  winbindd/winbindd_uid_to_sid.c
                  winbindd/winbindd_gid_to_sid.c
                  winbindd/winbindd_sids_to_xids.c
-- 
1.7.9.5


From dfaf05e0da2e2f7fa94c4e44639cd27e8c4da8f8 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 08:17:40 +0100
Subject: [PATCH 20/26] libwbclient: Use wbcCtxUnixIdsToSids in wbcCtxUidToSid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/libwbclient/wbc_idmap.c |   35 ++++++++++++++++-------------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index 68da865..2ee9410 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -67,33 +67,30 @@ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
 
 /* Convert a Unix uid to a Windows SID, allocating a SID if needed */
 wbcErr wbcCtxUidToSid(struct wbcContext *ctx, uid_t uid,
-		      struct wbcDomainSid *sid)
+		      struct wbcDomainSid *psid)
 {
-	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-	struct winbindd_request request;
-	struct winbindd_response response;
+	struct wbcUnixId xid;
+	struct wbcDomainSid sid;
+	struct wbcDomainSid null_sid = { 0 };
+	wbcErr wbc_status;
 
-	if (!sid) {
+	if (!psid) {
 		wbc_status = WBC_ERR_INVALID_PARAM;
 		BAIL_ON_WBC_ERROR(wbc_status);
 	}
 
-	/* Initialize request */
-
-	ZERO_STRUCT(request);
-	ZERO_STRUCT(response);
-
-	request.data.uid = uid;
+	xid = (struct wbcUnixId) { .type = WBC_ID_TYPE_UID, .id.uid = uid };
 
-	/* Make request */
-
-	wbc_status = wbcRequestResponse(ctx, WINBINDD_UID_TO_SID,
-					&request,
-					&response);
-	BAIL_ON_WBC_ERROR(wbc_status);
+	wbc_status = wbcCtxUnixIdsToSids(ctx, &xid, 1, &sid);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		goto done;
+	}
 
-	wbc_status = wbcStringToSid(response.data.sid.sid, sid);
-	BAIL_ON_WBC_ERROR(wbc_status);
+	if (memcmp(&sid, &null_sid, sizeof(sid)) != 0) {
+		*psid = sid;
+	} else {
+		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+	}
 
 done:
 	return wbc_status;
-- 
1.7.9.5


From ce7f55e5df7ad479a466aa9aed1cc11b9eaa0b8d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 08:19:41 +0100
Subject: [PATCH 21/26] libwbclient: Use wbcCtxUnixIdsToSids in wbcCtxGidToSid

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/libwbclient/wbc_idmap.c |   35 ++++++++++++++++-------------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index 2ee9410..2ff6170 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -162,33 +162,30 @@ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
 
 /* Convert a Unix gid to a Windows SID, allocating a SID if needed */
 wbcErr wbcCtxGidToSid(struct wbcContext *ctx, gid_t gid,
-		      struct wbcDomainSid *sid)
+		      struct wbcDomainSid *psid)
 {
-	struct winbindd_request request;
-	struct winbindd_response response;
-	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+	struct wbcUnixId xid;
+	struct wbcDomainSid sid;
+	struct wbcDomainSid null_sid = { 0 };
+	wbcErr wbc_status;
 
-	if (!sid) {
+	if (!psid) {
 		wbc_status = WBC_ERR_INVALID_PARAM;
 		BAIL_ON_WBC_ERROR(wbc_status);
 	}
 
-	/* Initialize request */
-
-	ZERO_STRUCT(request);
-	ZERO_STRUCT(response);
-
-	request.data.gid = gid;
+	xid = (struct wbcUnixId) { .type = WBC_ID_TYPE_GID, .id.gid = gid };
 
-	/* Make request */
-
-	wbc_status = wbcRequestResponse(ctx, WINBINDD_GID_TO_SID,
-					&request,
-					&response);
-	BAIL_ON_WBC_ERROR(wbc_status);
+	wbc_status = wbcCtxUnixIdsToSids(ctx, &xid, 1, &sid);
+	if (!WBC_ERROR_IS_OK(wbc_status)) {
+		goto done;
+	}
 
-	wbc_status = wbcStringToSid(response.data.sid.sid, sid);
-	BAIL_ON_WBC_ERROR(wbc_status);
+	if (memcmp(&sid, &null_sid, sizeof(sid)) != 0) {
+		*psid = sid;
+	} else {
+		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+	}
 
 done:
 	return wbc_status;
-- 
1.7.9.5


From 2a2a034549ffb842e91d2313d161e4dff79a630d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 09:30:09 +0100
Subject: [PATCH 22/26] libwbclient: Make source4/ use nsswitch/libwbclient

Right now there's no async user of this, so I think it's okay to use the
sync libwbclient. If we really get async libwbclient users, we need to
put it there instead of calling the struct protocol directly.

The code before this patch did not look at the _NO_WINBIND environment
variable. So ignore it here too.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source4/libcli/wbclient/wbclient.c    |  424 ++++++++-------------------------
 source4/libcli/wbclient/wscript_build |    2 +-
 2 files changed, 105 insertions(+), 321 deletions(-)

diff --git a/source4/libcli/wbclient/wbclient.c b/source4/libcli/wbclient/wbclient.c
index bb89435..f306556 100644
--- a/source4/libcli/wbclient/wbclient.c
+++ b/source4/libcli/wbclient/wbclient.c
@@ -21,391 +21,175 @@
 
 #include "includes.h"
 #include <tevent.h>
-#include "lib/util/tevent_unix.h"
+#include "nsswitch/winbind_client.h"
 #include "libcli/wbclient/wbclient.h"
-#include "nsswitch/wb_reqtrans.h"
-#include "system/network.h"
-#include "libcli/util/error.h"
 #include "libcli/security/dom_sid.h"
-
-static int wb_simple_trans(struct tevent_context *ev, int fd,
-			   struct winbindd_request *wb_req,
-			   TALLOC_CTX *mem_ctx,
-			   struct winbindd_response **resp, int *err)
-{
-	struct tevent_req *req;
-	bool polled;
-	int ret;
-
-	req = wb_simple_trans_send(ev, ev, NULL, fd, wb_req);
-	if (req == NULL) {
-		*err = ENOMEM;
-		return -1;
-	}
-
-	polled = tevent_req_poll(req, ev);
-	if (!polled) {
-		*err = errno;
-		DEBUG(10, ("tevent_req_poll returned %s\n",
-			   strerror(*err)));
-		return -1;
-	}
-
-	ret = wb_simple_trans_recv(req, mem_ctx, resp, err);
-	TALLOC_FREE(req);
-	return ret;
-}
-
-static const char *winbindd_socket_dir(void)
-{
-#ifdef SOCKET_WRAPPER
-	const char *env_dir;
-
-	env_dir = getenv("SELFTEST_WINBINDD_SOCKET_DIR");
-	if (env_dir) {
-		return env_dir;
-	}
-#endif
-
-	return WINBINDD_SOCKET_DIR;
-}
-
-static int winbindd_pipe_sock(void)
-{
-	struct sockaddr_un sunaddr = {};
-	int ret, fd;
-	char *path;
-
-	ret = asprintf(&path, "%s/%s", winbindd_socket_dir(),
-		       WINBINDD_SOCKET_NAME);
-	if (ret == -1) {
-		errno = ENOMEM;
-		return -1;
-	}
-	sunaddr.sun_family = AF_UNIX;
-	strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
-	free(path);
-
-	fd = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (fd == -1) {
-		return -1;
-	}
-
-	ret = connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
-	if (ret == -1) {
-		int err = errno;
-		close(fd);
-		errno = err;
-		return -1;
-	}
-
-	return fd;
-}
+#include "nsswitch/libwbclient/wbclient.h"
 
 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids,
 			  uint32_t count)
 {
 	TALLOC_CTX *mem_ctx;
-	struct winbindd_request req = {};
-	struct winbindd_response *resp;
 	uint32_t i;
-	int fd, ret, err;
-	char *sids, *p;
-	size_t sidslen;
-
-	fd = winbindd_pipe_sock();
-	if (fd == -1) {
-		return map_nt_error_from_unix_common(errno);
-	}
+	struct wbcDomainSid *sids;
+	struct wbcUnixId *xids;
+	wbcErr result;
+	bool wb_off;
 
 	mem_ctx = talloc_new(NULL);
 	if (mem_ctx == NULL) {
-		close(fd);
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	sidslen = count * (DOM_SID_STR_BUFLEN + 1);
-
-	sids = talloc_array(mem_ctx, char, sidslen);
+	sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
 	if (sids == NULL) {
-		close(fd);
 		TALLOC_FREE(mem_ctx);
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	p = sids;
+	xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+	if (xids == NULL) {
+		TALLOC_FREE(mem_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	for (i=0; i<count; i++) {
-		p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids));
-		*p++ = '\n';
+		memcpy(&sids[i], ids[i].sid, sizeof(struct dom_sid));
 	}
-	*p++ = '\0';
 
-	DEBUG(10, ("sids=\n%s", sids));
+	wb_off = winbind_env_set();
+	if (wb_off) {
+		(void)winbind_on();
+	}
 
-	req.length = sizeof(struct winbindd_request);
-	req.cmd = WINBINDD_SIDS_TO_XIDS;
-	req.pid = getpid();
-	req.extra_data.data = sids;
-	req.extra_len = (p - sids);
+	result = wbcSidsToUnixIds(sids, count, xids);
 
-	ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err);
-	if (ret == -1) {
-		return map_nt_error_from_unix_common(err);
+	if (wb_off) {
+		(void)winbind_off();
 	}
 
-	close(fd);
-
-	if (resp->result != WINBINDD_OK || p == NULL) {
+	if (!WBC_ERROR_IS_OK(result)) {
+		TALLOC_FREE(mem_ctx);
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	p = resp->extra_data.data;
-
 	for (i=0; i<count; i++) {
+		struct wbcUnixId *xid = &xids[i];
 		struct unixid *id = &ids[i].xid;
-		char *q;
 
-		switch (p[0]) {
-		case 'U':
+		switch (xid->type) {
+		    case WBC_ID_TYPE_UID:
 			id->type = ID_TYPE_UID;
-			id->id = strtoul(p+1, &q, 10);
+			id->id = xid->id.uid;
 			break;
-		case 'G':
+		    case WBC_ID_TYPE_GID:
 			id->type = ID_TYPE_GID;
-			id->id = strtoul(p+1, &q, 10);
+			id->id = xid->id.gid;
 			break;
-		case 'B':
+		    case WBC_ID_TYPE_BOTH:
 			id->type = ID_TYPE_BOTH;
-			id->id = strtoul(p+1, &q, 10);
+			id->id = xid->id.uid;
 			break;
-		default:
+		    case WBC_ID_TYPE_NOT_SPECIFIED:
 			id->type = ID_TYPE_NOT_SPECIFIED;
 			id->id = UINT32_MAX;
-			q = strchr(p, '\n');
 			break;
-		};
-		ids[i].status = ID_MAPPED;
-
-		if (q == NULL || q[0] != '\n') {
-			TALLOC_FREE(mem_ctx);
-			return NT_STATUS_INTERNAL_ERROR;
 		}
-		p = q+1;
-	}
-
-	return NT_STATUS_OK;
-}
-
-struct wbc_id_to_sid_state {
-	struct winbindd_request wbreq;
-	struct dom_sid sid;
-};
-
-static void wbc_id_to_sid_done(struct tevent_req *subreq);
-
-static struct tevent_req *wbc_id_to_sid_send(TALLOC_CTX *mem_ctx,
-					     struct tevent_context *ev,
-					     int fd, const struct unixid *id)
-{
-	struct tevent_req *req, *subreq;
-	struct wbc_id_to_sid_state *state;
-
-	req = tevent_req_create(mem_ctx, &state, struct wbc_id_to_sid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	switch(id->type) {
-	case ID_TYPE_UID:
-		state->wbreq.cmd = WINBINDD_UID_TO_SID;
-		state->wbreq.data.uid = id->id;
-		break;
-	case ID_TYPE_GID:
-		state->wbreq.cmd = WINBINDD_GID_TO_SID;
-		state->wbreq.data.gid = id->id;
-		break;
-	default:
-		tevent_req_error(req, ENOENT);
-		return tevent_req_post(req, ev);
+		ids[i].status = ID_MAPPED;
 	}
 
-	subreq = wb_simple_trans_send(state, ev, NULL, fd, &state->wbreq);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, wbc_id_to_sid_done, req);
-	return req;
-}
+	TALLOC_FREE(mem_ctx);
 
-static void wbc_id_to_sid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct wbc_id_to_sid_state *state = tevent_req_data(
-		req, struct wbc_id_to_sid_state);
-	struct winbindd_response *wbresp;
-	int ret, err;
-
-	ret = wb_simple_trans_recv(subreq, state, &wbresp, &err);
-	TALLOC_FREE(subreq);
-	if (ret == -1) {
-		tevent_req_error(req, err);
-		return;
-	}
-	if ((wbresp->result != WINBINDD_OK) ||
-	    !dom_sid_parse(wbresp->data.sid.sid, &state->sid)) {
-		tevent_req_error(req, ENOENT);
-		return;
-	}
-	tevent_req_done(req);
+	return NT_STATUS_OK;
 }
 
-static int wbc_id_to_sid_recv(struct tevent_req *req, struct dom_sid *sid)
+NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
+			  uint32_t count)
 {
-	struct wbc_id_to_sid_state *state = tevent_req_data(
-		req, struct wbc_id_to_sid_state);
-	int err;
+	TALLOC_CTX *mem_ctx;
+	uint32_t i;
+	struct wbcDomainSid *sids;
+	struct wbcUnixId *xids;
+	wbcErr result;
+	bool wb_off;
 
-	if (tevent_req_is_unix_error(req, &err)) {
-		return err;
+	mem_ctx = talloc_new(NULL);
+	if (mem_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
 	}
-	sid_copy(sid, &state->sid);
-	return 0;
-}
-
-struct wbc_ids_to_sids_state {
-	struct tevent_context *ev;
-	int fd;
-	struct id_map *ids;
-	uint32_t count;
-	uint32_t idx;
-};
-
-static void wbc_ids_to_sids_done(struct tevent_req *subreq);
 
-static struct tevent_req *wbc_ids_to_sids_send(
-	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-	int fd, struct id_map *ids, uint32_t count)
-{
-	struct tevent_req *req, *subreq;
-	struct wbc_ids_to_sids_state *state;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct wbc_ids_to_sids_state);
-	if (req == NULL) {
-		return NULL;
-	}
-	state->ev = ev;
-	state->fd = fd;
-	state->ids = ids;
-	state->count = count;
-
-	if (count == 0) {
-		tevent_req_done(req);
-		return tevent_req_post(req, ev);
+	sids = talloc_array(mem_ctx, struct wbcDomainSid, count);
+	if (sids == NULL) {
+		TALLOC_FREE(mem_ctx);
+		return NT_STATUS_NO_MEMORY;
 	}
 
-	subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
-				    &state->ids[state->idx].xid);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
+	xids = talloc_array(mem_ctx, struct wbcUnixId, count);
+	if (xids == NULL) {
+		TALLOC_FREE(mem_ctx);
+		return NT_STATUS_NO_MEMORY;
 	}
-	tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
-	return req;
-}
 
-static void wbc_ids_to_sids_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct wbc_ids_to_sids_state *state = tevent_req_data(
-		req, struct wbc_ids_to_sids_state);
-	struct id_map *id;
-	struct dom_sid sid;
-	int ret;
-
-	ret = wbc_id_to_sid_recv(subreq, &sid);
-	TALLOC_FREE(subreq);
-
-	id = &state->ids[state->idx];
-	if (ret == 0) {
-		id->status = ID_MAPPED;
-		id->sid = dom_sid_dup(state->ids, &sid);
-		if (id->sid == NULL) {
-			tevent_req_error(req, ENOMEM);
-			return;
+	for (i=0; i<count; i++) {
+		struct id_map *id = &ids[i];
+		struct wbcUnixId *xid = &xids[i];
+
+		switch (id->xid.type) {
+		    case ID_TYPE_UID:
+			    *xid = (struct wbcUnixId) {
+				    .type = WBC_ID_TYPE_UID,
+				    .id.uid = id->xid.id
+			    };
+			    break;
+		    case ID_TYPE_GID:
+			    *xid = (struct wbcUnixId) {
+				    .type = WBC_ID_TYPE_GID,
+				    .id.uid = id->xid.id
+			    };
+			    break;
+		    default:
+			    TALLOC_FREE(mem_ctx);
+			    return NT_STATUS_NOT_FOUND;
 		}
-	} else {
-		id->status = ID_UNMAPPED;
-		id->sid = NULL;
 	}
 
-	state->idx += 1;
-	if (state->idx == state->count) {
-		tevent_req_done(req);
-		return;
-	}
-
-	subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
-				    &state->ids[state->idx].xid);
-	if (tevent_req_nomem(subreq, req)) {
-		return;
-	}
-	tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
-}
-
-static int wbc_ids_to_sids_recv(struct tevent_req *req)
-{
-	int err;
-	if (tevent_req_is_unix_error(req, &err)) {
-		return err;
+	wb_off = winbind_env_set();
+	if (wb_off) {
+		(void)winbind_on();
 	}
-	return 0;
-}
 
-NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
-			  uint32_t count)
-{
-	struct tevent_req *req;
-	NTSTATUS status;
-	bool polled;
-	int ret, fd;
-
-	DEBUG(5, ("wbc_xids_to_sids called: %u ids\n", (unsigned)count));
-
-	fd = winbindd_pipe_sock();
-	if (fd == -1) {
-		status = map_nt_error_from_unix_common(errno);
-		DEBUG(10, ("winbindd_pipe_sock returned %s\n",
-			   strerror(errno)));
-		return status;
-	}
+	result = wbcUnixIdsToSids(xids, count, sids);
 
-	req = wbc_ids_to_sids_send(ev, ev, fd, ids, count);
-	if (req == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto done;
+	if (wb_off) {
+		(void)winbind_off();
 	}
 
-	polled = tevent_req_poll(req, ev);
-	if (!polled) {
-		status = map_nt_error_from_unix_common(errno);
-		DEBUG(10, ("tevent_req_poll returned %s\n",
-			   strerror(errno)));
-		goto done;
+	if (!WBC_ERROR_IS_OK(result)) {
+		TALLOC_FREE(mem_ctx);
+		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	ret = wbc_ids_to_sids_recv(req);
-	TALLOC_FREE(req);
-	if (ret != 0) {
-		status = map_nt_error_from_unix_common(ret);
-		DEBUG(10, ("tevent_req_poll returned %s\n",
-			   strerror(ret)));
-	} else {
-		status = NT_STATUS_OK;
+	for (i=0; i<count; i++) {
+		struct wbcDomainSid *sid = &sids[i];
+		struct wbcDomainSid null_sid = { 0 };
+		struct id_map *id = &ids[i];
+
+		if (memcmp(sid, &null_sid, sizeof(*sid)) != 0) {
+			struct dom_sid domsid;
+			id->status = ID_MAPPED;
+
+			memcpy(&domsid, sid, sizeof(struct dom_sid));
+			id->sid = dom_sid_dup(ids, &domsid);
+			if (id->sid == NULL) {
+				TALLOC_FREE(mem_ctx);
+				return NT_STATUS_NO_MEMORY;
+			}
+		} else {
+			id->status = ID_UNMAPPED;
+			id->sid = NULL;
+		}
 	}
 
-done:
-	close(fd);
-	return status;
+	TALLOC_FREE(mem_ctx);
+	return NT_STATUS_OK;
 }
diff --git a/source4/libcli/wbclient/wscript_build b/source4/libcli/wbclient/wscript_build
index f3cb3af..679a281 100644
--- a/source4/libcli/wbclient/wscript_build
+++ b/source4/libcli/wbclient/wscript_build
@@ -2,7 +2,7 @@
 
 bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD',
                   source='wbclient.c',
-                  public_deps='samba-errors events',
+                  public_deps='samba-errors events wbclient',
                   cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
                   deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND',
                   private_library=True
-- 
1.7.9.5


From 70ac2bd1d44a6e81ccdfc2ce86601654c4256951 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 17 Feb 2016 11:58:43 +0100
Subject: [PATCH 23/26] selftest: "standard" process model for a few envs

This is needed as with source4/libcli/wbclient changed to nsswitch/libwbclient
we don't have a nested event loop here anymore.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 selftest/target/Samba4.pm |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 2343cec..c1c3967 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -2121,7 +2121,7 @@ sub setup_s4member($$$)
 	my $env = $self->provision_s4member($path, $dc_vars);
 
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
@@ -2138,7 +2138,7 @@ sub setup_rpc_proxy($$$)
 	my $env = $self->provision_rpc_proxy($path, $dc_vars);
 
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
@@ -2169,7 +2169,7 @@ sub setup_chgdcpass($$)
 
 	my $env = $self->provision_chgdcpass($path);
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
@@ -2184,7 +2184,7 @@ sub setup_fl2000dc($$)
 
 	my $env = $self->provision_fl2000dc($path);
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
@@ -2201,7 +2201,7 @@ sub setup_fl2003dc($$$)
 	my $env = $self->provision_fl2003dc($path);
 
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
@@ -2219,7 +2219,7 @@ sub setup_fl2008r2dc($$$)
 	my $env = $self->provision_fl2008r2dc($path);
 
 	if (defined $env) {
-	        if (not defined($self->check_or_start($env, "single"))) {
+	        if (not defined($self->check_or_start($env, "standard"))) {
 		        return undef;
 		}
 
-- 
1.7.9.5


From 0f0d29d7ee701cf54891d306add02af0a7f9a61c Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 09:36:37 +0100
Subject: [PATCH 24/26] winbind: Remove unused WINBINDD_GID_TO_SID

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_struct_protocol.h     |    2 +-
 source3/winbindd/winbindd.c            |    2 -
 source3/winbindd/winbindd_gid_to_sid.c |   94 --------------------------------
 source3/wscript_build                  |    1 -
 4 files changed, 1 insertion(+), 98 deletions(-)
 delete mode 100644 source3/winbindd/winbindd_gid_to_sid.c

diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index f24ba72..6f25619 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -56,6 +56,7 @@ typedef char fstring[FSTRING_LEN];
  * 28: added WINBINDD_XIDS_TO_SIDS
  *     removed WINBINDD_SID_TO_UID
  *     removed WINBINDD_SID_TO_GID
+ *     removed WINBINDD_GID_TO_SID
  */
 #define WINBIND_INTERFACE_VERSION 28
 
@@ -116,7 +117,6 @@ enum winbindd_cmd {
 	WINBINDD_SIDS_TO_XIDS,
 	WINBINDD_XIDS_TO_SIDS,
 	WINBINDD_UID_TO_SID,
-	WINBINDD_GID_TO_SID,
 
 	WINBINDD_ALLOCATE_UID,
 	WINBINDD_ALLOCATE_GID,
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index e4090bd..10b1979 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -610,8 +610,6 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_lookupname_send, winbindd_lookupname_recv },
 	{ WINBINDD_UID_TO_SID, "UID_TO_SID",
 	  winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
-	{ WINBINDD_GID_TO_SID, "GID_TO_SID",
-	  winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
 	{ WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
 	  winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
 	{ WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
diff --git a/source3/winbindd/winbindd_gid_to_sid.c b/source3/winbindd/winbindd_gid_to_sid.c
deleted file mode 100644
index b1644ec..0000000
--- a/source3/winbindd/winbindd_gid_to_sid.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async implementation of WINBINDD_GID_TO_SID
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "libcli/security/dom_sid.h"
-
-struct winbindd_gid_to_sid_state {
-	struct tevent_context *ev;
-	struct unixid xid;
-	struct dom_sid *sid;
-};
-
-static void winbindd_gid_to_sid_done(struct tevent_req *subreq);
-
-struct tevent_req *winbindd_gid_to_sid_send(TALLOC_CTX *mem_ctx,
-					    struct tevent_context *ev,
-					    struct winbindd_cli_state *cli,
-					    struct winbindd_request *request)
-{
-	struct tevent_req *req, *subreq;
-	struct winbindd_gid_to_sid_state *state;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct winbindd_gid_to_sid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-	state->ev = ev;
-
-	DEBUG(3, ("gid_to_sid %d\n", (int)request->data.gid));
-
-	state->xid = (struct unixid) {
-		.id = request->data.gid, .type = ID_TYPE_GID };
-
-	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, winbindd_gid_to_sid_done, req);
-	return req;
-}
-
-static void winbindd_gid_to_sid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct winbindd_gid_to_sid_state *state = tevent_req_data(
-		req, struct winbindd_gid_to_sid_state);
-	NTSTATUS status;
-
-	status = wb_xids2sids_recv(subreq, state, &state->sid);
-	TALLOC_FREE(subreq);
-	if (tevent_req_nterror(req, status)) {
-		return;
-	}
-	tevent_req_done(req);
-}
-
-NTSTATUS winbindd_gid_to_sid_recv(struct tevent_req *req,
-				  struct winbindd_response *response)
-{
-	struct winbindd_gid_to_sid_state *state = tevent_req_data(
-		req, struct winbindd_gid_to_sid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(state->sid), nt_errstr(status)));
-		return status;
-	}
-	if (is_null_sid(state->sid)) {
-		return NT_STATUS_NONE_MAPPED;
-	}
-	sid_to_fstring(response->data.sid.sid, state->sid);
-	response->data.sid.type = SID_NAME_USER;
-	return NT_STATUS_OK;
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index ada41ac..7030423 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -945,7 +945,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/winbindd_lookupsids.c
                  winbindd/winbindd_lookupname.c
                  winbindd/winbindd_uid_to_sid.c
-                 winbindd/winbindd_gid_to_sid.c
                  winbindd/winbindd_sids_to_xids.c
                  winbindd/winbindd_xids_to_sids.c
                  winbindd/winbindd_allocate_uid.c
-- 
1.7.9.5


From 578233036b57f46ff2cd1bd70ef3d142ac4e75bf Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 09:42:28 +0100
Subject: [PATCH 25/26] nss_aix: Hack away WINBINDD_UID_TO_SID

To do a proper xids2sids conversion I need a build environment.

Everyone who needs this and can build AIX please speak up!

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_nss_aix.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/nsswitch/winbind_nss_aix.c b/nsswitch/winbind_nss_aix.c
index 7a847b2..c5c223f 100644
--- a/nsswitch/winbind_nss_aix.c
+++ b/nsswitch/winbind_nss_aix.c
@@ -609,6 +609,14 @@ static attrval_t pwd_to_sid(struct passwd *pwd)
 
 	request.data.uid = pwd->pw_uid;
 
+#if 0
+	/*
+	 * Removed because WINBINDD_UID_TO_SID is replaced by
+	 * WINBINDD_XIDS_TO_SIDS. I don't have an AIX build
+	 * environment around, so I did not convert this call. If
+	 * someone stumbles over this, please contact me:
+	 * vl at samba.org, I'll convert this.
+	 */
 	if (winbindd_request_response(NULL, WINBINDD_UID_TO_SID,
 				      &request, &response) !=
 	    NSS_STATUS_SUCCESS) {
@@ -617,6 +625,9 @@ static attrval_t pwd_to_sid(struct passwd *pwd)
 		r.attr_flag = 0;
 		r.attr_un.au_char = strdup(response.data.sid.sid);
 	}
+#else
+	r.attr_flag = ENOENT;
+#endif
 
 	return r;
 }
-- 
1.7.9.5


From 0462f616fec7fc7efc0c65fe9acd55b5afac392a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 9 Feb 2016 09:36:37 +0100
Subject: [PATCH 26/26] winbind: Remove unused WINBINDD_UID_TO_SID

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 nsswitch/winbind_struct_protocol.h     |    2 +-
 source3/winbindd/winbindd.c            |    2 -
 source3/winbindd/winbindd_uid_to_sid.c |   94 --------------------------------
 source3/wscript_build                  |    1 -
 4 files changed, 1 insertion(+), 98 deletions(-)
 delete mode 100644 source3/winbindd/winbindd_uid_to_sid.c

diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 6f25619..622dcfe 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -57,6 +57,7 @@ typedef char fstring[FSTRING_LEN];
  *     removed WINBINDD_SID_TO_UID
  *     removed WINBINDD_SID_TO_GID
  *     removed WINBINDD_GID_TO_SID
+ *     removed WINBINDD_UID_TO_SID
  */
 #define WINBIND_INTERFACE_VERSION 28
 
@@ -116,7 +117,6 @@ enum winbindd_cmd {
 
 	WINBINDD_SIDS_TO_XIDS,
 	WINBINDD_XIDS_TO_SIDS,
-	WINBINDD_UID_TO_SID,
 
 	WINBINDD_ALLOCATE_UID,
 	WINBINDD_ALLOCATE_GID,
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 10b1979..78df632 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -608,8 +608,6 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
 	  winbindd_lookupsids_send, winbindd_lookupsids_recv },
 	{ WINBINDD_LOOKUPNAME, "LOOKUPNAME",
 	  winbindd_lookupname_send, winbindd_lookupname_recv },
-	{ WINBINDD_UID_TO_SID, "UID_TO_SID",
-	  winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
 	{ WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
 	  winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
 	{ WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
diff --git a/source3/winbindd/winbindd_uid_to_sid.c b/source3/winbindd/winbindd_uid_to_sid.c
deleted file mode 100644
index d0ea9c6..0000000
--- a/source3/winbindd/winbindd_uid_to_sid.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   async implementation of WINBINDD_UID_TO_SID
-   Copyright (C) Volker Lendecke 2009
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "libcli/security/dom_sid.h"
-
-struct winbindd_uid_to_sid_state {
-	struct tevent_context *ev;
-	struct unixid xid;
-	struct dom_sid *sid;
-};
-
-static void winbindd_uid_to_sid_done(struct tevent_req *subreq);
-
-struct tevent_req *winbindd_uid_to_sid_send(TALLOC_CTX *mem_ctx,
-					    struct tevent_context *ev,
-					    struct winbindd_cli_state *cli,
-					    struct winbindd_request *request)
-{
-	struct tevent_req *req, *subreq;
-	struct winbindd_uid_to_sid_state *state;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct winbindd_uid_to_sid_state);
-	if (req == NULL) {
-		return NULL;
-	}
-	state->ev = ev;
-
-	DEBUG(3, ("uid_to_sid %d\n", (int)request->data.uid));
-
-	state->xid = (struct unixid) {
-		.id = request->data.uid, .type = ID_TYPE_UID };
-
-	subreq = wb_xids2sids_send(state, ev, &state->xid, 1);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, winbindd_uid_to_sid_done, req);
-	return req;
-}
-
-static void winbindd_uid_to_sid_done(struct tevent_req *subreq)
-{
-	struct tevent_req *req = tevent_req_callback_data(
-		subreq, struct tevent_req);
-	struct winbindd_uid_to_sid_state *state = tevent_req_data(
-		req, struct winbindd_uid_to_sid_state);
-	NTSTATUS status;
-
-	status = wb_xids2sids_recv(subreq, state, &state->sid);
-	TALLOC_FREE(subreq);
-	if (tevent_req_nterror(req, status)) {
-		return;
-	}
-	tevent_req_done(req);
-}
-
-NTSTATUS winbindd_uid_to_sid_recv(struct tevent_req *req,
-				  struct winbindd_response *response)
-{
-	struct winbindd_uid_to_sid_state *state = tevent_req_data(
-		req, struct winbindd_uid_to_sid_state);
-	NTSTATUS status;
-
-	if (tevent_req_is_nterror(req, &status)) {
-		DEBUG(5, ("Could not convert sid %s: %s\n",
-			  sid_string_dbg(state->sid), nt_errstr(status)));
-		return status;
-	}
-	if (is_null_sid(state->sid)) {
-		return NT_STATUS_NONE_MAPPED;
-	}
-	sid_to_fstring(response->data.sid.sid, state->sid);
-	response->data.sid.type = SID_NAME_USER;
-	return NT_STATUS_OK;
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index 7030423..9ec11f9 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -944,7 +944,6 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/winbindd_lookupsid.c
                  winbindd/winbindd_lookupsids.c
                  winbindd/winbindd_lookupname.c
-                 winbindd/winbindd_uid_to_sid.c
                  winbindd/winbindd_sids_to_xids.c
                  winbindd/winbindd_xids_to_sids.c
                  winbindd/winbindd_allocate_uid.c
-- 
1.7.9.5



More information about the samba-technical mailing list