summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2019-02-26 15:10:21 +0100
committerKarolin Seeger <kseeger@samba.org>2019-03-12 11:25:43 +0000
commit4fd495159d183fa9fd2e74bb74893a842e8cbcad (patch)
tree43220b8f0801607d38ef9ab3f65c8bd95cd9fdad
parente8bb1f65cd12f3243e5b965e1e9951567cd3ed48 (diff)
downloadsamba-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.c74
-rw-r--r--source3/passdb/lookup_sid.h1
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,