[PATCH] winbind cleanups

Jeremy Allison jra at samba.org
Tue Feb 23 00:02:20 UTC 2016


On Fri, Feb 19, 2016 at 01:25:33PM +0100, Volker Lendecke wrote:
> On Fri, Feb 19, 2016 at 12:46:52PM +0100, Michael Adam wrote:
> > Doesn't this hunk belong into a different patch?
> 
> True, thanks. New patchset attached.
> 
> > Is that by chance the bug that you mentioned above?
> 
> No, that was a different one. Trivial cut&paste that I'm too lazy to
> dig up here. Diff the 2 patchsets if you're really interested :-)
> 
> Volker

I know Ralph has already pushed this but I wanted
to read it just to make sure I kept understanding
of what was going on inside winbindd.

This is some *seriously* nice code ! Thanks !

Congratulations Volker, very clean way to update
and migrate a subsystem.

Cheers,

	Jeremy.

> 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

> From a576fee0683bc1ddc28cfd0f831dd40a12509be6 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;
> -- 
> 2.1.4
> 
> 
> From 50383d070ba805f3aab65b74378a38aa336a65d9 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;
> +}
> -- 
> 2.1.4
> 
> 
> From 5c0370ad50e58add7b1c05f164f404e72487696a 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;
>  }
> -- 
> 2.1.4
> 
> 
> From 8d6d0a4ab751472ea0b20b5734eeb82315a1aedf 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;
> -- 
> 2.1.4
> 
> 
> From befb9b19c728a1e374e2769d1376b9fdc7a9634b 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
> -- 
> 2.1.4
> 
> 
> From 649333914a0beb573e6b433958be39e73d3539ab 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;
> +}
> -- 
> 2.1.4
> 
> 
> From 3c60e041aedba977433655d42bb7b9780a280182 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
> -- 
> 2.1.4
> 
> 
> From 90514c159173dff7ce6d7d3d5387f7682bed1d5f 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
> -- 
> 2.1.4
> 
> 
> From e1a6417e99ab9c972346c862f728e62ff59c5a6f 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");
> -- 
> 2.1.4
> 
> 
> From 34bad26b97bf04e212c27107677c78e3bd3a71d6 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;
>  }
> -- 
> 2.1.4
> 
> 
> From 3b0f6fac0b19e8d9ef975a599f67e95cb886a6cb 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;
> -- 
> 2.1.4
> 
> 
> From 0e3a7a0738a0a8b779deefb9b01658e35caf645e 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
> -- 
> 2.1.4
> 
> 
> From 0224ae6f253b3de8e93afef5308a468db5a7f0e1 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;
>  }
> -- 
> 2.1.4
> 
> 
> From f3ca2e30edce87831ed250cbb0acd2de0ac4e10f 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;
>  	}
>  
> -- 
> 2.1.4
> 
> 
> From bfcc716828d81d4e0d65ed901e5b078ef0a2f88e 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
> -- 
> 2.1.4
> 
> 
> From 42fa663cb76eff17745645ef2e514ca8b9ab640b 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..6735d3d 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.uid;
> +		wbc_status = WBC_ERR_SUCCESS;
> +	} else {
> +		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
> +	}
>  
>   done:
>  	return wbc_status;
> -- 
> 2.1.4
> 
> 
> From 1b2a98dc6f6b924edcc462cc30393cb5063d6dda 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, 12 insertions(+), 19 deletions(-)
> 
> diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
> index 6735d3d..5cd082b 100644
> --- a/nsswitch/libwbclient/wbc_idmap.c
> +++ b/nsswitch/libwbclient/wbc_idmap.c
> @@ -123,32 +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);
> -
> -	*pgid = response.data.gid;
> +	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_GID) || (xid.type == WBC_ID_TYPE_BOTH)) {
> +		*pgid = xid.id.gid;
> +		wbc_status = WBC_ERR_SUCCESS;
> +	} else {
> +		wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
> +	}
>  
>   done:
>  	return wbc_status;
> -- 
> 2.1.4
> 
> 
> From 973621e25794570c1be087f27d4cfe2407391b5e 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
> -- 
> 2.1.4
> 
> 
> From 6f6a01feb6d7f9108e34586b030e26fa5239703d 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
> -- 
> 2.1.4
> 
> 
> From f9d86b699883795cf8d47abb766542642d57f103 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 5cd082b..26613be 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;
> -- 
> 2.1.4
> 
> 
> From bd2beb5ed5ff254258ca04325ff152912ca2000d 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 26613be..f61efb9 100644
> --- a/nsswitch/libwbclient/wbc_idmap.c
> +++ b/nsswitch/libwbclient/wbc_idmap.c
> @@ -160,33 +160,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;
> -- 
> 2.1.4
> 
> 
> From e44c6cefd06115381f6d5dad03d5c228b090a8f5 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
> -- 
> 2.1.4
> 
> 
> From 4242cb65002039e75624392558010641f1b3acf6 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;
>  		}
>  
> -- 
> 2.1.4
> 
> 
> From 398866adb6f083ae2bc794aa66f9c3499491dab8 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
> -- 
> 2.1.4
> 
> 
> From 11a80c6d9aac1faf3d2910e2547e80c19e069184 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;
>  }
> -- 
> 2.1.4
> 
> 
> From 365518fcfc0af9364a6cbcf0b5283d0d1deaf362 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
> -- 
> 2.1.4
> 




More information about the samba-technical mailing list