winbindd: track whether a result from xid2sid was coming from the cache
authorRalph Boehme <slow@samba.org>
Fri, 22 Feb 2019 10:00:00 +0000 (11:00 +0100)
committerKarolin Seeger <kseeger@samba.org>
Mon, 4 Mar 2019 10:37:55 +0000 (10:37 +0000)
This is needed in preparation of moving the step to update the idmap
cache from the per-idmap-domain callback wb_xids2sids_dom_done() to the
top-level callback wb_xids2sids_done().

Currently the sequence of action is:

* check cache, if not found:
  * ask backends
  * cache result from backend
* return results

Iow, if we got something from the cache, we don't write the cache.

The next commit defers updating the cache to the top-level callback, so
the sequence becomes

* check cache, if not found:
  * ask backends
* cache results
* return results

This has two problems:

* it needlessly writes to the cache what we just got from it

* it possibly overwrites the ID_TYPE_BOTH for a SID-to-xid mapping in
  the following case:

  - existing ID_TYPE_BOTH mapping in the cache, eg:

    IDMAP/SID2XID/S-1-5-21-2180672342-2513613279-2566592647-512 -> Value: 3000000:B

  - someone calls wb_xids2sids_send() with xid.id=3000000,xid.type=ID_TYPE_GID

  - cache lookup with idmap_cache_find_gid2sid() succeeds

  - when caching results we'd call idmap_cache_set_sid2unixid() with the
    callers xid.type=ID_TYPE_GID, so idmap_cache_set_sid2unixid() will
    overwrite the SID-to-xid mapping with ID_TYPE_GID

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13802

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
(cherry picked from commit 62f54229fced20102e11ad1da02faef45c2a7c2e)

source3/winbindd/wb_xids2sids.c

index d769328a15e3083108ba55446362a5e3fc63f264..dcbbe8d510d51bdad315ac1cb195f276b4566fc2 100644 (file)
@@ -429,6 +429,7 @@ struct wb_xids2sids_state {
        struct unixid *xids;
        size_t num_xids;
        struct dom_sid *sids;
+       bool *cached;
 
        size_t dom_idx;
 };
@@ -463,6 +464,11 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
+       state->cached = talloc_zero_array(state, bool, num_xids);
+       if (tevent_req_nomem(state->cached, req)) {
+               return tevent_req_post(req, ev);
+       }
+
        if (winbindd_use_idmap_cache()) {
                uint32_t i;
 
@@ -485,6 +491,7 @@ struct tevent_req *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
 
                        if (ok && !expired) {
                                sid_copy(&state->sids[i], &sid);
+                               state->cached[i] = true;
                        }
                }
        }