From 340ab6a256802a22c11b7f707748397249075b65 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 13 Jul 2008 12:07:40 +0200 Subject: idmap rewrite (This used to be commit 30a180f2fce8cf6a3e5548f6bba453272ba70b33) --- source3/winbindd/idmap_util.c | 162 +++++++++++++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 32 deletions(-) (limited to 'source3/winbindd/idmap_util.c') diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 31b9895224..04d12944e2 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -27,28 +27,50 @@ If mapping is not possible returns an error. *****************************************************************/ -NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid) +NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid) { NTSTATUS ret; struct id_map map; + bool expired; DEBUG(10,("uid = [%lu]\n", (unsigned long)uid)); + if (idmap_cache_find_uid2sid(uid, sid, &expired)) { + DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", 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: map.sid = sid; map.xid.type = ID_TYPE_UID; map.xid.id = uid; - ret = idmap_backends_unixid_to_sid(&map); + ret = idmap_backends_unixid_to_sid(domname, &map); if ( ! NT_STATUS_IS_OK(ret)) { DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid)); return ret; } if (map.status != ID_MAPPED) { + struct dom_sid null_sid; + ZERO_STRUCT(null_sid); + idmap_cache_set_sid2uid(&null_sid, uid); DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid)); return NT_STATUS_NONE_MAPPED; } + idmap_cache_set_sid2uid(sid, uid); + return NT_STATUS_OK; } @@ -57,28 +79,50 @@ NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid) If mapping is not possible returns an error. *****************************************************************/ -NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid) +NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid) { NTSTATUS ret; struct id_map map; + bool expired; DEBUG(10,("gid = [%lu]\n", (unsigned long)gid)); + if (idmap_cache_find_uid2sid(gid, sid, &expired)) { + DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", 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: map.sid = sid; map.xid.type = ID_TYPE_GID; map.xid.id = gid; - ret = idmap_backends_unixid_to_sid(&map); + ret = idmap_backends_unixid_to_sid(domname, &map); if ( ! NT_STATUS_IS_OK(ret)) { DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid)); return ret; } if (map.status != ID_MAPPED) { + struct dom_sid null_sid; + ZERO_STRUCT(null_sid); + idmap_cache_set_sid2uid(&null_sid, gid); DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid)); return NT_STATUS_NONE_MAPPED; } + idmap_cache_set_sid2uid(sid, gid); + return NT_STATUS_OK; } @@ -87,34 +131,61 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid) If mapping is not possible or SID maps to a GID returns an error. *****************************************************************/ -NTSTATUS idmap_sid_to_uid(DOM_SID *sid, uid_t *uid) +NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid) { NTSTATUS ret; struct id_map map; + bool expired; DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid))); + if (idmap_cache_find_sid2uid(sid, uid, &expired)) { + DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", + (int)(*uid), expired ? " (expired)": "")); + if (expired && idmap_is_online()) { + DEBUG(10, ("revalidating expired entry\n")); + goto backend; + } + if ((*uid) == -1) { + DEBUG(10, ("Returning negative cache entry\n")); + return NT_STATUS_NONE_MAPPED; + } + DEBUG(10, ("Returning positive cache entry\n")); + return NT_STATUS_OK; + } + +backend: map.sid = sid; map.xid.type = ID_TYPE_UID; - ret = idmap_backends_sid_to_unixid(&map); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(10, ("error mapping sid [%s] to uid\n", - sid_string_dbg(sid))); - return ret; + ret = idmap_backends_sid_to_unixid(dom_name, &map); + + if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) { + if (map.xid.type != ID_TYPE_UID) { + DEBUG(10, ("sid [%s] not mapped to a uid " + "[%u,%u,%u]\n", + sid_string_dbg(sid), + map.status, + map.xid.type, + map.xid.id)); + idmap_cache_set_sid2uid(sid, -1); + return NT_STATUS_NONE_MAPPED; + } + goto done; } - if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_UID)) { - DEBUG(10, ("sid [%s] not mapped to an uid [%u,%u,%u]\n", - sid_string_dbg(sid), - map.status, - map.xid.type, - map.xid.id)); - return NT_STATUS_NONE_MAPPED; - } + ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid); - *uid = map.xid.id; + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(10, ("idmap_new_mapping failed: %s\n", + nt_errstr(ret))); + idmap_cache_set_sid2uid(sid, -1); + return ret; + } +done: + *uid = (uid_t)map.xid.id; + idmap_cache_set_sid2uid(sid, *uid); return NT_STATUS_OK; } @@ -123,32 +194,59 @@ NTSTATUS idmap_sid_to_uid(DOM_SID *sid, uid_t *uid) If mapping is not possible or SID maps to a UID returns an error. *****************************************************************/ -NTSTATUS idmap_sid_to_gid(DOM_SID *sid, gid_t *gid) +NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid) { NTSTATUS ret; struct id_map map; + bool expired; DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid))); + if (idmap_cache_find_sid2gid(sid, gid, &expired)) { + DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", + (int)(*gid), expired ? " (expired)": "")); + if (expired && idmap_is_online()) { + DEBUG(10, ("revalidating expired entry\n")); + goto backend; + } + if ((*gid) == -1) { + DEBUG(10, ("Returning negative cache entry\n")); + return NT_STATUS_NONE_MAPPED; + } + DEBUG(10, ("Returning positive cache entry\n")); + return NT_STATUS_OK; + } + +backend: map.sid = sid; map.xid.type = ID_TYPE_GID; - ret = idmap_backends_sid_to_unixid(&map); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(10, ("error mapping sid [%s] to gid\n", - sid_string_dbg(sid))); - return ret; + ret = idmap_backends_sid_to_unixid(domname, &map); + if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) { + if (map.xid.type != ID_TYPE_GID) { + DEBUG(10, ("sid [%s] not mapped to a gid " + "[%u,%u,%u]\n", + sid_string_dbg(sid), + map.status, + map.xid.type, + map.xid.id)); + idmap_cache_set_sid2gid(sid, -1); + return NT_STATUS_NONE_MAPPED; + } + goto done; } - if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_GID)) { - DEBUG(10, ("sid [%s] not mapped to a gid [%u,%u]\n", - sid_string_dbg(sid), - map.status, - map.xid.type)); - return NT_STATUS_NONE_MAPPED; + ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(10, ("idmap_new_mapping failed: %s\n", + nt_errstr(ret))); + idmap_cache_set_sid2gid(sid, -1); + return ret; } +done: *gid = map.xid.id; - + idmap_cache_set_sid2gid(sid, *gid); return NT_STATUS_OK; } -- cgit