diff options
author | Volker Lendecke <vl@samba.org> | 2019-02-26 15:10:21 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2019-03-12 11:25:43 +0000 |
commit | 4fd495159d183fa9fd2e74bb74893a842e8cbcad (patch) | |
tree | 43220b8f0801607d38ef9ab3f65c8bd95cd9fdad | |
parent | e8bb1f65cd12f3243e5b965e1e9951567cd3ed48 (diff) | |
download | samba-4fd495159d183fa9fd2e74bb74893a842e8cbcad.tar.gz |
passdb: Introduce xid_to_sid
This explicitly avoids the legacy_[ug]id_to_sid calls, which create
long-term cache entries to S-1-22-x-y if anthing fails. We can't do
this, because this will turn temporary winbind communication failures
into long-term problems: A short hickup in winbind_uid_to_sid will
create a mapping to S-1-22-1-uid for a week. It should be up to the
lower layers to do the caching.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13813
(cherry picked from commit 92f27ebb14c0c18b1d0fd49544ad851aeb14781c)
-rw-r--r-- | source3/passdb/lookup_sid.c | 74 | ||||
-rw-r--r-- | source3/passdb/lookup_sid.h | 1 |
2 files changed, 75 insertions, 0 deletions
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index eeaf2b720a7..1cf3a7ddb87 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -1337,6 +1337,80 @@ void gid_to_sid(struct dom_sid *psid, gid_t gid) return; } +void xid_to_sid(struct dom_sid *psid, const struct unixid *xid) +{ + bool expired = true; + bool ret; + struct dom_sid_buf buf; + + SMB_ASSERT(xid->type == ID_TYPE_UID || xid->type == ID_TYPE_GID); + + *psid = (struct dom_sid) {0}; + + ret = idmap_cache_find_xid2sid(xid, psid, &expired); + if (ret && !expired) { + DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n", + xid->type == ID_TYPE_UID ? 'U' : 'G', + xid->id, + dom_sid_str_buf(psid, &buf)); + goto done; + } + + ret = winbind_xid_to_sid(psid, xid); + if (ret) { + /* + * winbind can return an explicit negative mapping + * here. It's up to winbind to prime the cache either + * positively or negatively, don't mess with the cache + * here. + */ + DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n", + xid->type == ID_TYPE_UID ? 'U' : 'G', + xid->id, + dom_sid_str_buf(psid, &buf)); + goto done; + } + + { + /* + * Make a copy, pdb_id_to_sid might want to turn + * xid->type into ID_TYPE_BOTH, which we ignore here. + */ + struct unixid rw_xid = *xid; + + become_root(); + ret = pdb_id_to_sid(&rw_xid, psid); + unbecome_root(); + } + + if (ret) { + DBG_DEBUG("%cID %"PRIu32" -> %s from passdb\n", + xid->type == ID_TYPE_UID ? 'U' : 'G', + xid->id, + dom_sid_str_buf(psid, &buf)); + goto done; + } + +done: + if (is_null_sid(psid)) { + /* + * Nobody found anything: Return S-1-22-xx-yy. Don't + * store that in caches, this is up to the layers + * beneath us. + */ + if (xid->type == ID_TYPE_UID) { + uid_to_unix_users_sid(xid->id, psid); + } else { + gid_to_unix_groups_sid(xid->id, psid); + } + + DBG_DEBUG("%cID %"PRIu32" -> %s fallback\n", + xid->type == ID_TYPE_UID ? 'U' : 'G', + xid->id, + dom_sid_str_buf(psid, &buf)); + } +} + bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids, struct unixid *ids) { diff --git a/source3/passdb/lookup_sid.h b/source3/passdb/lookup_sid.h index 8b5edf6bcb8..8a21cca2a4d 100644 --- a/source3/passdb/lookup_sid.h +++ b/source3/passdb/lookup_sid.h @@ -83,6 +83,7 @@ bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, enum lsa_SidType *ret_type); void uid_to_sid(struct dom_sid *psid, uid_t uid); void gid_to_sid(struct dom_sid *psid, gid_t gid); +void xid_to_sid(struct dom_sid *psid, const struct unixid *xid); bool sid_to_uid(const struct dom_sid *psid, uid_t *puid); bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid); bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids, |