[PATCH] Restructure winbind xids2sids
Jeremy Allison
jra at samba.org
Wed Mar 30 00:03:19 UTC 2016
On Mon, Mar 28, 2016 at 09:22:53PM +0200, Volker Lendecke wrote:
> Hi!
>
> This is a patchset that passes down the xids2sids operation from the
> winbind frontend to the idmap backends.
>
> Review appreciated!
OK, spent a lot of time going through it (sorry for
the initial mistake on the talloc heirarchy).
Took me a while to spot the clever bit of
wb_xids2sids_send()
|
--> wb_xids2sids_dom_send()
|
---> wb_xids2sids_done()
which can then re-call wb_xids2sids_dom_send()
|
--> wb_xids2sids_done()
to deal with the rest of the (unanswered) domain xid's
without recursion and using multiple tevent reqs.
Really nice work !!!!
Reviewed-by: Jeremy Allison <jra at samba.org>
> --
> 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 e0111e47a0481cd5f5b25ab467c487c708b72abc Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Mon, 22 Feb 2016 17:03:43 +0100
> Subject: [PATCH 1/8] idmap: Factor out lp_scan_idmap_domains()
>
> This simplifies idmap_found_domain_backend() by moving the regex magic
> somewhere else. Also, this routine will be useful soon somewhere else, thus
> make it non-static to idmap.c.
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/idmap.c | 125 +++++++++++++++++++++++++-------------
> source3/winbindd/winbindd_proto.h | 3 +
> 2 files changed, 87 insertions(+), 41 deletions(-)
>
> diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
> index 7eb7e58..7b4ed4f 100644
> --- a/source3/winbindd/idmap.c
> +++ b/source3/winbindd/idmap.c
> @@ -70,13 +70,71 @@ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
> const char *domainname,
> const char *modulename,
> bool check_range);
> -static bool idmap_found_domain_backend(
> +
> +struct lp_scan_idmap_domains_state {
> + bool (*fn)(const char *domname, void *private_data);
> + void *private_data;
> +};
> +
> +static bool lp_scan_idmap_found_domain(
> const char *string, regmatch_t matches[], void *private_data);
>
> +bool lp_scan_idmap_domains(bool (*fn)(const char *domname,
> + void *private_data),
> + void *private_data)
> +{
> + struct lp_scan_idmap_domains_state state = {
> + .fn = fn, .private_data = private_data };
> + int ret;
> +
> + ret = lp_wi_scan_global_parametrics(
> + "idmapconfig\\(.*\\):backend", 2,
> + lp_scan_idmap_found_domain, &state);
> + if (ret != 0) {
> + DBG_WARNING("wi_scan_global_parametrics returned %d\n", ret);
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static bool lp_scan_idmap_found_domain(
> + const char *string, regmatch_t matches[], void *private_data)
> +{
> + bool ok;
> +
> + if (matches[1].rm_so == -1) {
> + DBG_WARNING("Found match, but no name??\n");
> + return false;
> + }
> + if (matches[1].rm_eo <= matches[1].rm_so) {
> + DBG_WARNING("Invalid match\n");
> + return false;
> + }
> +
> + {
> + struct lp_scan_idmap_domains_state *state = private_data;
> + regoff_t len = matches[1].rm_eo - matches[1].rm_so;
> + char domname[len+1];
> +
> + memcpy(domname, string + matches[1].rm_so, len);
> + domname[len] = '\0';
> +
> + DBG_DEBUG("Found idmap domain \"%s\"\n", domname);
> +
> + ok = state->fn(domname, state->private_data);
> + }
> +
> + return ok;
> +}
> +
> +static bool idmap_found_domain_backend(const char *domname,
> + void *private_data);
> +
> static bool idmap_init(void)
> {
> static bool initialized;
> - int ret;
> + bool ok;
>
> if (initialized) {
> return true;
> @@ -109,11 +167,9 @@ static bool idmap_init(void)
> return false;
> }
>
> - ret = lp_wi_scan_global_parametrics(
> - "idmapconfig\\(.*\\):backend", 2,
> - idmap_found_domain_backend, NULL);
> - if (ret != 0) {
> - DBG_WARNING("wi_scan_global_parametrics returned %d\n", ret);
> + ok = lp_scan_idmap_domains(idmap_found_domain_backend, NULL);
> + if (!ok) {
> + DBG_WARNING("lp_scan_idmap_domains failed\n");
> return false;
> }
>
> @@ -161,46 +217,33 @@ bool domain_has_idmap_config(const char *domname)
> return false;
> }
>
> -static bool idmap_found_domain_backend(
> - const char *string, regmatch_t matches[], void *private_data)
> +static bool idmap_found_domain_backend(const char *domname,
> + void *private_data)
> {
> - if (matches[1].rm_so == -1) {
> - DBG_WARNING("Found match, but no name??\n");
> - return false;
> - }
> -
> - {
> - struct idmap_domain *dom, **tmp;
> - regoff_t len = matches[1].rm_eo - matches[1].rm_so;
> - char domname[len+1];
> + struct idmap_domain *dom, **tmp;
>
> - memcpy(domname, string + matches[1].rm_so, len);
> - domname[len] = '\0';
> + DBG_DEBUG("Found idmap domain \"%s\"\n", domname);
>
> - DBG_DEBUG("Found idmap domain \"%s\"\n", domname);
> -
> - if (strcmp(domname, "*") == 0) {
> - return false;
> - }
> + if (strcmp(domname, "*") == 0) {
> + return false;
> + }
>
> - dom = idmap_init_named_domain(idmap_domains, domname);
> - if (dom == NULL) {
> - DBG_NOTICE("Could not init idmap domain %s\n",
> - domname);
> - return false;
> - }
> + dom = idmap_init_named_domain(idmap_domains, domname);
> + if (dom == NULL) {
> + DBG_NOTICE("Could not init idmap domain %s\n", domname);
> + return false;
> + }
>
> - tmp = talloc_realloc(idmap_domains, idmap_domains,
> - struct idmap_domain *, num_domains + 1);
> - if (tmp == NULL) {
> - DBG_WARNING("talloc_realloc failed\n");
> - TALLOC_FREE(dom);
> - return false;
> - }
> - idmap_domains = tmp;
> - idmap_domains[num_domains] = dom;
> - num_domains += 1;
> + tmp = talloc_realloc(idmap_domains, idmap_domains,
> + struct idmap_domain *, num_domains + 1);
> + if (tmp == NULL) {
> + DBG_WARNING("talloc_realloc failed\n");
> + TALLOC_FREE(dom);
> + return false;
> }
> + idmap_domains = tmp;
> + idmap_domains[num_domains] = dom;
> + num_domains += 1;
>
> return false;
> }
> diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
> index 12629ff..7c9a924 100644
> --- a/source3/winbindd/winbindd_proto.h
> +++ b/source3/winbindd/winbindd_proto.h
> @@ -331,6 +331,9 @@ struct winbindd_child *idmap_child(void);
> struct idmap_domain *idmap_find_domain_with_sid(const char *domname,
> const struct dom_sid *sid);
> bool domain_has_idmap_config(const char *domname);
> +bool lp_scan_idmap_domains(bool (*fn)(const char *domname,
> + void *private_data),
> + void *private_data);
>
> /* The following definitions come from winbindd/winbindd_locator.c */
>
> --
> 2.1.4
>
>
> From d56c969b2216a44e2f3bc000acedcf56952752e4 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 4 Mar 2016 14:23:51 +0100
> Subject: [PATCH 2/8] winbind: Introduce id_map_ptrs_init
>
> This simplifies _wbint_Sids2UnixIDs a bit and will be re-used in _wbint_UnixIDs2Sids
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/idmap_proto.h | 2 ++
> source3/winbindd/idmap_util.c | 31 +++++++++++++++++++++++++++++++
> source3/winbindd/winbindd_dual_srv.c | 33 ++++++++-------------------------
> 3 files changed, 41 insertions(+), 25 deletions(-)
>
> diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h
> index a12e5b4..0e124cd 100644
> --- a/source3/winbindd/idmap_proto.h
> +++ b/source3/winbindd/idmap_proto.h
> @@ -59,6 +59,8 @@ struct id_map *idmap_find_map_by_sid(struct id_map **maps, struct dom_sid *sid);
> char *idmap_fetch_secret(const char *backend, const char *domain,
> const char *identity);
>
> +struct id_map **id_map_ptrs_init(TALLOC_CTX *mem_ctx, size_t num_ids);
> +
> /* max number of ids requested per LDAP batch query */
> #define IDMAP_LDAP_MAX_IDS 30
>
> diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c
> index f90565f..7591530 100644
> --- a/source3/winbindd/idmap_util.c
> +++ b/source3/winbindd/idmap_util.c
> @@ -238,3 +238,34 @@ char *idmap_fetch_secret(const char *backend, const char *domain,
>
> return ret;
> }
> +
> +struct id_map **id_map_ptrs_init(TALLOC_CTX *mem_ctx, size_t num_ids)
> +{
> + struct id_map **ptrs;
> + struct id_map *maps;
> + struct dom_sid *sids;
> + size_t i;
> +
> + ptrs = talloc_array(mem_ctx, struct id_map *, num_ids+1);
> + if (ptrs == NULL) {
> + return NULL;
> + }
> + maps = talloc_array(ptrs, struct id_map, num_ids);
> + if (maps == NULL) {
> + TALLOC_FREE(ptrs);
> + return NULL;
> + }
> + sids = talloc_zero_array(ptrs, struct dom_sid, num_ids);
> + if (sids == NULL) {
> + TALLOC_FREE(ptrs);
> + return NULL;
> + }
> +
> + for (i=0; i<num_ids; i++) {
> + maps[i] = (struct id_map) { .sid = &sids[i] };
> + ptrs[i] = &maps[i];
> + }
> + ptrs[num_ids] = NULL;
> +
> + return ptrs;
> +}
> diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
> index e42dce5..7c415e6 100644
> --- a/source3/winbindd/winbindd_dual_srv.c
> +++ b/source3/winbindd/winbindd_dual_srv.c
> @@ -127,9 +127,7 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
> 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;
> struct idmap_domain *dom;
> NTSTATUS status = NT_STATUS_NO_MEMORY;
>
> @@ -157,18 +155,10 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
> return NT_STATUS_OK;
> }
>
> - 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);
> + id_map_ptrs = id_map_ptrs_init(talloc_tos(), num_ids);
> if (id_map_ptrs == NULL) {
> goto nomem;
> }
> - sids = talloc_array(talloc_tos(), struct dom_sid, num_ids);
> - if (sids == NULL) {
> - goto nomem;
> - }
>
> /*
> * Convert the input data into a list of id_map structs
> @@ -177,18 +167,12 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
> */
>
> for (i=0; i<num_ids; i++) {
> + struct id_map *m = id_map_ptrs[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];
> + sid_compose(m->sid, d->sid, ids[i].rid);
> + m->status = ID_UNKNOWN;
> + m->xid = (struct unixid) { .type = ids[i].type };
> }
> - id_map_ptrs[num_ids] = NULL;
>
> status = dom->methods->sids_to_unixids(dom, id_map_ptrs);
>
> @@ -203,9 +187,10 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
> */
>
> for (i=0; i<num_ids; i++) {
> + struct id_map *m = id_map_ptrs[i];
>
> - if (id_maps[i].status == ID_MAPPED) {
> - ids[i].xid = id_maps[i].xid;
> + if (m->status == ID_MAPPED) {
> + ids[i].xid = m->xid;
> } else {
> ids[i].xid.id = UINT32_MAX;
> ids[i].xid.type = ID_TYPE_NOT_SPECIFIED;
> @@ -216,9 +201,7 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
> nomem:
> status = NT_STATUS_NO_MEMORY;
> done:
> - TALLOC_FREE(id_maps);
> TALLOC_FREE(id_map_ptrs);
> - TALLOC_FREE(sids);
> return status;
> }
>
> --
> 2.1.4
>
>
> From ad082278a1378ff25599877734d276c7714e76b8 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 1 Mar 2016 14:34:26 +0100
> Subject: [PATCH 3/8] winbind: Do per-domain xids2sids calls
>
> This prepares the equivalent of 2b1dd01934b657a for xids2sids.
>
> Collecting sids2xids per domain is a bit easier: SIDs carry their own domain
> prefix. For the reverse, we need to scan the configuration for all the idmap
> range definitions.
>
> It has a separate effect: It enables overlapping idmap ranges. The per-domain
> calls are done whenever a range matches. If the idmap child finds a successful
> xid2sid mapping, this will be collected as one result. This means that every
> range definition can contribute mappings.
>
> If there are two rfc2307 sfu domains with overlapping ranges, the domains will
> be queried one after the other for a specific mapping. If the defined ranges
> overlap, the admin has to make sure that there are no conflicts, because in the
> current code "the first writer wins", and the code does not specify an order
> (yet).
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/wb_xids2sids.c | 280 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 270 insertions(+), 10 deletions(-)
>
> diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
> index 6c3f0f6..7328f1e 100644
> --- a/source3/winbindd/wb_xids2sids.c
> +++ b/source3/winbindd/wb_xids2sids.c
> @@ -23,8 +23,244 @@
> #include "idmap_cache.h"
> #include "librpc/gen_ndr/ndr_winbind_c.h"
>
> +struct wb_xids2sids_dom_map {
> + unsigned low_id;
> + unsigned high_id;
> + const char *name;
> +};
> +
> +/*
> + * Map idmap ranges to domain names, taken from smb.conf. This is
> + * stored in the parent winbind and used to assemble xid2sid calls
> + * into per-idmap-domain chunks.
> + */
> +static struct wb_xids2sids_dom_map *dom_maps;
> +
> +static bool wb_xids2sids_add_dom(const char *domname,
> + void *private_data)
> +{
> + struct wb_xids2sids_dom_map *map = NULL;
> + size_t num_maps = talloc_array_length(dom_maps);
> + size_t i;
> + char *config_option;
> + const char *range;
> + unsigned low_id, high_id;
> + int ret;
> +
> + config_option = talloc_asprintf(
> + talloc_tos(), "idmap config %s", domname);
> + if (config_option == NULL) {
> + return false;
> + }
> + range = lp_parm_const_string(-1, config_option, "range", NULL);
> + TALLOC_FREE(config_option);
> +
> + if (range == NULL) {
> + DBG_DEBUG("No range for domain %s found\n", domname);
> + return false;
> + }
> +
> + ret = sscanf(range, "%u - %u", &low_id, &high_id);
> + if (ret != 2) {
> + DBG_DEBUG("Invalid range spec \"%s\" for domain %s\n",
> + range, domname);
> + return false;
> + }
> +
> + if (low_id > high_id) {
> + DBG_DEBUG("Invalid range %u - %u for domain %s\n",
> + low_id, high_id, domname);
> + return false;
> + }
> +
> + for (i=0; i<num_maps; i++) {
> + if (strequal(domname, dom_maps[i].name)) {
> + map = &dom_maps[i];
> + break;
> + }
> + }
> +
> + if (map == NULL) {
> + struct wb_xids2sids_dom_map *tmp;
> + char *name;
> +
> + name = talloc_strdup(talloc_tos(), domname);
> + if (name == NULL) {
> + DBG_DEBUG("talloc failed\n");
> + return false;
> + }
> +
> + tmp = talloc_realloc(
> + NULL, dom_maps, struct wb_xids2sids_dom_map,
> + num_maps+1);
> + if (tmp == NULL) {
> + TALLOC_FREE(name);
> + return false;
> + }
> + dom_maps = tmp;
> +
> + map = &dom_maps[num_maps];
> + map->name = talloc_move(dom_maps, &name);
> + }
> +
> + map->low_id = low_id;
> + map->high_id = high_id;
> +
> + return false;
> +}
> +
> +static void wb_xids2sids_init_dom_maps(void)
> +{
> + if (dom_maps != NULL) {
> + return;
> + }
> +
> + /*
> + * Put the passdb idmap domain first. We always need to try
> + * there first.
> + */
> +
> + dom_maps = talloc_array(NULL, struct wb_xids2sids_dom_map, 1);
> + if (dom_maps == NULL) {
> + return;
> + }
> + dom_maps[0].low_id = 0;
> + dom_maps[0].high_id = UINT_MAX;
> + dom_maps[0].name = talloc_strdup(dom_maps, get_global_sam_name());
> + if (dom_maps[0].name == NULL) {
> + TALLOC_FREE(dom_maps);
> + return;
> + }
> +
> + lp_scan_idmap_domains(wb_xids2sids_add_dom, NULL);
> +}
> +
> +struct wb_xids2sids_dom_state {
> + struct unixid *all_xids;
> + size_t num_all_xids;
> + struct dom_sid *all_sids;
> + struct wb_xids2sids_dom_map *dom_map;
> +
> + size_t num_dom_xids;
> + struct unixid *dom_xids;
> + struct dom_sid *dom_sids;
> +};
> +
> +static void wb_xids2sids_dom_done(struct tevent_req *subreq);
> +
> +static struct tevent_req *wb_xids2sids_dom_send(
> + TALLOC_CTX *mem_ctx, struct tevent_context *ev,
> + struct wb_xids2sids_dom_map *dom_map,
> + struct unixid *xids, size_t num_xids, struct dom_sid *sids)
> +{
> + struct tevent_req *req, *subreq;
> + struct wb_xids2sids_dom_state *state;
> + struct winbindd_child *child;
> + size_t i;
> +
> + req = tevent_req_create(mem_ctx, &state,
> + struct wb_xids2sids_dom_state);
> + if (req == NULL) {
> + return NULL;
> + }
> + state->all_xids = xids;
> + state->num_all_xids = num_xids;
> + state->all_sids = sids;
> + state->dom_map = dom_map;
> +
> + state->dom_xids = talloc_array(state, struct unixid, num_xids);
> + if (tevent_req_nomem(state->dom_xids, req)) {
> + return tevent_req_post(req, ev);
> + }
> + state->dom_sids = talloc_array(state, struct dom_sid, num_xids);
> + if (tevent_req_nomem(state->dom_sids, req)) {
> + return tevent_req_post(req, ev);
> + }
> +
> + for (i=0; i<num_xids; i++) {
> + struct unixid id = state->all_xids[i];
> +
> + if ((id.id < dom_map->low_id) || (id.id > dom_map->high_id)) {
> + /* out of range */
> + continue;
> + }
> + if (!is_null_sid(&state->all_sids[i])) {
> + /* already mapped */
> + continue;
> + }
> +
> + state->dom_xids[state->num_dom_xids++] = id;
> + }
> +
> + if (state->num_dom_xids == 0) {
> + tevent_req_done(req);
> + return tevent_req_post(req, ev);
> + }
> +
> + child = idmap_child();
> + subreq = dcerpc_wbint_UnixIDs2Sids_send(
> + state, ev, child->binding_handle,
> + state->num_dom_xids, state->dom_xids, state->dom_sids);
> + if (tevent_req_nomem(subreq, req)) {
> + return tevent_req_post(req, ev);
> + }
> + tevent_req_set_callback(subreq, wb_xids2sids_dom_done, req);
> + return req;
> +}
> +
> +static void wb_xids2sids_dom_done(struct tevent_req *subreq)
> +{
> + struct tevent_req *req = tevent_req_callback_data(
> + subreq, struct tevent_req);
> + struct wb_xids2sids_dom_state *state = tevent_req_data(
> + req, struct wb_xids2sids_dom_state);
> + struct wb_xids2sids_dom_map *dom_map = state->dom_map;
> + NTSTATUS status, result;
> + size_t i;
> + size_t dom_sid_idx;
> +
> + status = dcerpc_wbint_UnixIDs2Sids_recv(subreq, state, &result);
> + TALLOC_FREE(subreq);
> + if (tevent_req_nterror(req, status)) {
> + return;
> + }
> + if (!NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) &&
> + tevent_req_nterror(req, result)) {
> + return;
> + }
> +
> + dom_sid_idx = 0;
> +
> + for (i=0; i<state->num_all_xids; i++) {
> + struct unixid id = state->all_xids[i];
> +
> + if ((id.id < dom_map->low_id) || (id.id > dom_map->high_id)) {
> + /* out of range */
> + continue;
> + }
> + if (!is_null_sid(&state->all_sids[i])) {
> + /* already mapped */
> + continue;
> + }
> +
> + sid_copy(&state->all_sids[i], &state->dom_sids[dom_sid_idx++]);
> + }
> +
> + tevent_req_done(req);
> +}
> +
> +static NTSTATUS wb_xids2sids_dom_recv(struct tevent_req *req)
> +{
> + return tevent_req_simple_recv_ntstatus(req);
> +}
> +
> struct wb_xids2sids_state {
> + struct tevent_context *ev;
> + struct unixid *xids;
> + size_t num_xids;
> struct dom_sid *sids;
> +
> + size_t dom_idx;
> };
>
> static void wb_xids2sids_done(struct tevent_req *subreq);
> @@ -36,23 +272,33 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
> {
> struct tevent_req *req, *subreq;
> struct wb_xids2sids_state *state;
> - struct winbindd_child *child;
> + size_t num_domains;
>
> req = tevent_req_create(mem_ctx, &state,
> struct wb_xids2sids_state);
> if (req == NULL) {
> return NULL;
> }
> + state->ev = ev;
> + state->xids = xids;
> + state->num_xids = num_xids;
>
> - state->sids = talloc_array(state, struct dom_sid, num_xids);
> + state->sids = talloc_zero_array(state, struct dom_sid, num_xids);
> if (tevent_req_nomem(state->sids, req)) {
> return tevent_req_post(req, ev);
> }
>
> - child = idmap_child();
> + wb_xids2sids_init_dom_maps();
> + num_domains = talloc_array_length(dom_maps);
>
> - subreq = dcerpc_wbint_UnixIDs2Sids_send(
> - state, ev, child->binding_handle, num_xids, xids, state->sids);
> + if (num_domains == 0) {
> + tevent_req_done(req);
> + return tevent_req_post(req, ev);
> + }
> +
> + subreq = wb_xids2sids_dom_send(
> + state, state->ev, &dom_maps[state->dom_idx],
> + state->xids, state->num_xids, state->sids);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> }
> @@ -66,15 +312,29 @@ static void wb_xids2sids_done(struct tevent_req *subreq)
> subreq, struct tevent_req);
> struct wb_xids2sids_state *state = tevent_req_data(
> req, struct wb_xids2sids_state);
> - NTSTATUS status, result;
> + size_t num_domains = talloc_array_length(dom_maps);
> + NTSTATUS status;
>
> - status = dcerpc_wbint_UnixIDs2Sids_recv(subreq, state, &result);
> + status = wb_xids2sids_dom_recv(subreq);
> TALLOC_FREE(subreq);
> - if (any_nt_status_not_ok(status, result, &status)) {
> - tevent_req_nterror(req, status);
> + if (tevent_req_nterror(req, status)) {
> return;
> }
> - tevent_req_done(req);
> +
> + state->dom_idx += 1;
> +
> + if (state->dom_idx >= num_domains) {
> + tevent_req_done(req);
> + return;
> + }
> +
> + subreq = wb_xids2sids_dom_send(
> + state, state->ev, &dom_maps[state->dom_idx],
> + state->xids, state->num_xids, state->sids);
> + if (tevent_req_nomem(subreq, req)) {
> + return;
> + }
> + tevent_req_set_callback(subreq, wb_xids2sids_done, req);
> }
>
> NTSTATUS wb_xids2sids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
> --
> 2.1.4
>
>
> From 38af381db173569f6b0878801ec632560b508291 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 4 Mar 2016 15:03:08 +0100
> Subject: [PATCH 4/8] winbind: Add idmap_backend_unixids_to_sids
>
> This is the plural version of idmap_backends_unixid_to_sid that expects all ids
> to come from the same idmap domain. The singular version walks the domain list
> itself, this one expects the domain name to be passed to it.
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/idmap.c | 31 +++++++++++++++++++++++++++++++
> source3/winbindd/idmap_proto.h | 2 ++
> 2 files changed, 33 insertions(+)
>
> diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
> index 7b4ed4f..0ff35ca 100644
> --- a/source3/winbindd/idmap.c
> +++ b/source3/winbindd/idmap.c
> @@ -25,6 +25,7 @@
> #include "winbindd.h"
> #include "idmap.h"
> #include "lib/util_sid_passdb.h"
> +#include "libcli/security/dom_sid.h"
> #include "passdb.h"
>
> #undef DBGC_CLASS
> @@ -587,6 +588,36 @@ NTSTATUS idmap_allocate_gid(struct unixid *id)
> return idmap_allocate_unixid(id);
> }
>
> +NTSTATUS idmap_backend_unixids_to_sids(struct id_map **maps,
> + const char *domain_name)
> +{
> + struct idmap_domain *dom = NULL;
> + NTSTATUS status;
> + bool ok;
> +
> + ok = idmap_init();
> + if (!ok) {
> + return NT_STATUS_NONE_MAPPED;
> + }
> +
> + if (strequal(domain_name, get_global_sam_name())) {
> + dom = passdb_idmap_domain;
> + }
> + if (dom == NULL) {
> + dom = idmap_find_domain(domain_name);
> + }
> + if (dom == NULL) {
> + return NT_STATUS_NONE_MAPPED;
> + }
> +
> + status = dom->methods->unixids_to_sids(dom, maps);
> +
> + DBG_DEBUG("unixid_to_sids for domain %s returned %s\n",
> + domain_name, nt_errstr(status));
> +
> + return status;
> +}
> +
> NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id)
> {
> struct idmap_domain *dom;
> diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h
> index 0e124cd..78a5c41 100644
> --- a/source3/winbindd/idmap_proto.h
> +++ b/source3/winbindd/idmap_proto.h
> @@ -35,6 +35,8 @@ void idmap_close(void);
> NTSTATUS idmap_allocate_uid(struct unixid *id);
> NTSTATUS idmap_allocate_gid(struct unixid *id);
> NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id);
> +NTSTATUS idmap_backend_unixids_to_sids(struct id_map **maps,
> + const char *domain_name);
>
> /* The following definitions come from winbindd/idmap_nss.c */
>
> --
> 2.1.4
>
>
> From 746d4fb8b0ea9db309d0391f617e28de6eb96a48 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 16 Mar 2016 15:25:35 +0100
> Subject: [PATCH 5/8] winbind: Pass down the domain name to xids2sids
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> librpc/idl/winbind.idl | 1 +
> source3/winbindd/wb_xids2sids.c | 2 +-
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl
> index b1aed30..60c875b 100644
> --- a/librpc/idl/winbind.idl
> +++ b/librpc/idl/winbind.idl
> @@ -57,6 +57,7 @@ interface winbind
> );
>
> NTSTATUS wbint_UnixIDs2Sids(
> + [in,string,charset(UTF8)] char *domain_name,
> [in] uint32 num_ids,
> [in] unixid xids[num_ids],
> [out] dom_sid sids[num_ids]
> diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
> index 7328f1e..77372f7 100644
> --- a/source3/winbindd/wb_xids2sids.c
> +++ b/source3/winbindd/wb_xids2sids.c
> @@ -199,7 +199,7 @@ static struct tevent_req *wb_xids2sids_dom_send(
>
> child = idmap_child();
> subreq = dcerpc_wbint_UnixIDs2Sids_send(
> - state, ev, child->binding_handle,
> + state, ev, child->binding_handle, dom_map->name,
> state->num_dom_xids, state->dom_xids, state->dom_sids);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> --
> 2.1.4
>
>
> From 21d0bf81b529280aa5ce1c726ea70b0cbeac79a7 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 4 Mar 2016 15:45:24 +0100
> Subject: [PATCH 6/8] winbind: Use plural xids2sids in _wbint_UnixIDs2Sids
>
> We've had plural xid2sid idmap backends for a while. Start using
> them.
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/winbindd_dual_srv.c | 38 +++++++++++++++++++-----------------
> 1 file changed, 20 insertions(+), 18 deletions(-)
>
> diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
> index 7c415e6..fb65e9d 100644
> --- a/source3/winbindd/winbindd_dual_srv.c
> +++ b/source3/winbindd/winbindd_dual_srv.c
> @@ -208,30 +208,32 @@ done:
> NTSTATUS _wbint_UnixIDs2Sids(struct pipes_struct *p,
> struct wbint_UnixIDs2Sids *r)
> {
> + struct id_map **maps;
> + NTSTATUS status;
> uint32_t i;
>
> + maps = id_map_ptrs_init(talloc_tos(), r->in.num_ids);
> + if (maps == NULL) {
> + return NT_STATUS_NO_MEMORY;
> + }
> +
> 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;
> - }
> + maps[i]->status = ID_UNKNOWN;
> + maps[i]->xid = r->in.xids[i];
> + }
>
> - if (!NT_STATUS_IS_OK(status)) {
> - *sid = (struct dom_sid) {0};
> - }
> + status = idmap_backend_unixids_to_sids(maps, r->in.domain_name);
> + if (!NT_STATUS_IS_OK(status)) {
> + TALLOC_FREE(maps);
> + return status;
> }
>
> + for (i=0; i<r->in.num_ids; i++) {
> + sid_copy(&r->out.sids[i], maps[i]->sid);
> + }
> +
> + TALLOC_FREE(maps);
> +
> return NT_STATUS_OK;
> }
>
> --
> 2.1.4
>
>
> From 20841ddd11d46b2a4bb7ef9c4e0297512ac29563 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 16 Mar 2016 15:33:48 +0100
> Subject: [PATCH 7/8] winbind: Remove unused idmap_[ug]id_to_sid
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/winbindd/idmap_proto.h | 2 -
> source3/winbindd/idmap_util.c | 126 -----------------------------------------
> 2 files changed, 128 deletions(-)
>
> diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h
> index 78a5c41..c690d27 100644
> --- a/source3/winbindd/idmap_proto.h
> +++ b/source3/winbindd/idmap_proto.h
> @@ -52,8 +52,6 @@ NTSTATUS idmap_tdb_init(void);
>
> /* The following definitions come from winbindd/idmap_util.c */
>
> -NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid);
> -NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid);
> bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom);
> struct id_map *idmap_find_map_by_id(struct id_map **maps, enum id_type type,
> uint32_t id);
> diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c
> index 7591530..3da39e8 100644
> --- a/source3/winbindd/idmap_util.c
> +++ b/source3/winbindd/idmap_util.c
> @@ -29,132 +29,6 @@
> #undef DBGC_CLASS
> #define DBGC_CLASS DBGC_IDMAP
>
> -/*****************************************************************
> - Returns the SID mapped to the given UID.
> - If mapping is not possible returns an error.
> -*****************************************************************/
> -
> -NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid)
> -{
> - NTSTATUS ret;
> - struct id_map map;
> - bool expired;
> -
> - DEBUG(10, ("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid));
> -
> - if (winbindd_use_idmap_cache()
> - && idmap_cache_find_uid2sid(uid, sid, &expired)) {
> - DEBUG(10, ("idmap_cache_find_uid2sid found %u%s\n",
> - (unsigned int)uid,
> - expired ? " (expired)": ""));
> - if (expired && idmap_is_online()) {
> - DEBUG(10, ("revalidating expired entry\n"));
> - goto backend;
> - }
> - if (is_null_sid(sid)) {
> - DEBUG(10, ("Returning negative cache entry\n"));
> - return NT_STATUS_NONE_MAPPED;
> - }
> - DEBUG(10, ("Returning positive cache entry\n"));
> - return NT_STATUS_OK;
> - }
> -
> -backend:
> - ZERO_STRUCT(map);
> - map.sid = sid;
> - map.xid.type = ID_TYPE_UID;
> - map.xid.id = uid;
> -
> - ret = idmap_backends_unixid_to_sid(&map);
> - if ( ! NT_STATUS_IS_OK(ret)) {
> - DEBUG(10, ("error mapping uid [%lu]: %s\n", (unsigned long)uid,
> - nt_errstr(ret)));
> - map.status = ID_UNMAPPED;
> - }
> -
> - if (map.status != ID_MAPPED) {
> - if (winbindd_use_idmap_cache()) {
> - struct dom_sid null_sid;
> - struct unixid id;
> - id.type = ID_TYPE_UID;
> - id.id = uid;
> - ZERO_STRUCT(null_sid);
> - idmap_cache_set_sid2unixid(&null_sid, &id);
> - }
> - DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
> - return NT_STATUS_NONE_MAPPED;
> - }
> -
> - if (winbindd_use_idmap_cache()) {
> - idmap_cache_set_sid2unixid(sid, &map.xid);
> - }
> -
> - return NT_STATUS_OK;
> -}
> -
> -/*****************************************************************
> - Returns SID mapped to the given GID.
> - If mapping is not possible returns an error.
> -*****************************************************************/
> -
> -NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid)
> -{
> - NTSTATUS ret;
> - struct id_map map;
> - bool expired;
> -
> - DEBUG(10, ("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid));
> -
> - if (winbindd_use_idmap_cache()
> - && idmap_cache_find_gid2sid(gid, sid, &expired)) {
> - DEBUG(10, ("idmap_cache_find_gid2sid found %u%s\n",
> - (unsigned int)gid,
> - expired ? " (expired)": ""));
> - if (expired && idmap_is_online()) {
> - DEBUG(10, ("revalidating expired entry\n"));
> - goto backend;
> - }
> - if (is_null_sid(sid)) {
> - DEBUG(10, ("Returning negative cache entry\n"));
> - return NT_STATUS_NONE_MAPPED;
> - }
> - DEBUG(10, ("Returning positive cache entry\n"));
> - return NT_STATUS_OK;
> - }
> -
> -backend:
> - ZERO_STRUCT(map);
> - map.sid = sid;
> - map.xid.type = ID_TYPE_GID;
> - map.xid.id = gid;
> -
> - ret = idmap_backends_unixid_to_sid(&map);
> - if ( ! NT_STATUS_IS_OK(ret)) {
> - DEBUG(10, ("error mapping gid [%lu]: %s\n", (unsigned long)gid,
> - nt_errstr(ret)));
> - map.status = ID_UNMAPPED;
> - }
> -
> - if (map.status != ID_MAPPED) {
> - if (winbindd_use_idmap_cache()) {
> - struct dom_sid null_sid;
> - struct unixid id;
> - id.type = ID_TYPE_GID;
> - id.id = gid;
> - ZERO_STRUCT(null_sid);
> - idmap_cache_set_sid2unixid(&null_sid, &id);
> - }
> - DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
> - return NT_STATUS_NONE_MAPPED;
> - }
> -
> - if (winbindd_use_idmap_cache()) {
> - idmap_cache_set_sid2unixid(sid, &map.xid);
> - }
> -
> - return NT_STATUS_OK;
> -}
> -
> /**
> * check whether a given unix id is inside the filter range of an idmap domain
> */
> --
> 2.1.4
>
>
> From 3a2c0371f52be96c79f198bc22f9055a8caac111 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 16 Mar 2016 15:35:51 +0100
> Subject: [PATCH 8/8] winbind: Remove unused idmap_backends_unixid_to_sid
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/torture/test_idmap_tdb_common.c | 5 ----
> source3/winbindd/idmap.c | 46 ---------------------------------
> source3/winbindd/idmap_proto.h | 1 -
> 3 files changed, 52 deletions(-)
>
> diff --git a/source3/torture/test_idmap_tdb_common.c b/source3/torture/test_idmap_tdb_common.c
> index dd736ad..897d217 100644
> --- a/source3/torture/test_idmap_tdb_common.c
> +++ b/source3/torture/test_idmap_tdb_common.c
> @@ -62,11 +62,6 @@ bool idmap_is_online(void)
> return true;
> }
>
> -NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id)
> -{
> - return NT_STATUS_OK;
> -}
> -
> static bool open_db(struct idmap_tdb_common_context *ctx)
> {
> NTSTATUS status;
> diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
> index 0ff35ca..84834f1 100644
> --- a/source3/winbindd/idmap.c
> +++ b/source3/winbindd/idmap.c
> @@ -617,49 +617,3 @@ NTSTATUS idmap_backend_unixids_to_sids(struct id_map **maps,
>
> return status;
> }
> -
> -NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id)
> -{
> - struct idmap_domain *dom;
> - struct id_map *maps[2];
> - bool ok;
> - int i;
> -
> - ok = idmap_init();
> - if (!ok) {
> - return NT_STATUS_NONE_MAPPED;
> - }
> -
> - DEBUG(10, ("idmap_backend_unixid_to_sid: xid = %d (type %d)\n",
> - id->xid.id, id->xid.type));
> -
> - maps[0] = id;
> - maps[1] = NULL;
> -
> - /*
> - * Always give passdb a chance first
> - */
> -
> - dom = passdb_idmap_domain;
> - if ((dom != NULL)
> - && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))
> - && id->status == ID_MAPPED) {
> - return NT_STATUS_OK;
> - }
> -
> - dom = default_idmap_domain;
> -
> - for (i=0; i<num_domains; i++) {
> - if ((id->xid.id >= idmap_domains[i]->low_id) &&
> - (id->xid.id <= idmap_domains[i]->high_id)) {
> - dom = idmap_domains[i];
> - break;
> - }
> - }
> -
> - if (dom == NULL) {
> - return NT_STATUS_NONE_MAPPED;
> - }
> -
> - return dom->methods->unixids_to_sids(dom, maps);
> -}
> diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h
> index c690d27..ea96d72 100644
> --- a/source3/winbindd/idmap_proto.h
> +++ b/source3/winbindd/idmap_proto.h
> @@ -34,7 +34,6 @@ NTSTATUS smb_register_idmap(int version, const char *name,
> void idmap_close(void);
> NTSTATUS idmap_allocate_uid(struct unixid *id);
> NTSTATUS idmap_allocate_gid(struct unixid *id);
> -NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id);
> NTSTATUS idmap_backend_unixids_to_sids(struct id_map **maps,
> const char *domain_name);
>
> --
> 2.1.4
>
More information about the samba-technical
mailing list