diff options
-rw-r--r-- | source3/sam/idmap_util.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/source3/sam/idmap_util.c b/source3/sam/idmap_util.c new file mode 100644 index 0000000000..fd44938989 --- /dev/null +++ b/source3/sam/idmap_util.c @@ -0,0 +1,189 @@ +/* + Unix SMB/CIFS implementation. + ID Mapping + Copyright (C) Simo Sorce 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +/***************************************************************** + *THE CANONICAL* convert uid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) +{ + unid_t id; + + DEBUG(10,("uid_to_sid: uid = [%d]\n", uid)); + + id.uid = uid; + if (NT_STATUS_IS_OK(idmap_get_sid_from_id(psid, id, ID_USERID))) { + DEBUG(10, ("uid_to_sid: sid = [%s]\n", sid_string_static(psid))); + return psid; + } + + /* If mapping is not found in idmap try with traditional method, + then stores the result in idmap. + We may add a switch in future to allow smooth migrations to + idmap-only db ---Simo */ + + sid_copy(psid, get_global_sam_sid()); + sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); + + DEBUG(10,("uid_to_sid: algorithmic %u -> %s\n", (unsigned int)uid, sid_string_static(psid))); + + return psid; + +} + +/***************************************************************** + *THE CANONICAL* convert gid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) +{ + GROUP_MAP map; + unid_t id; + + DEBUG(10,("gid_to_sid: gid = [%d]\n", gid)); + + id.gid = gid; + if (NT_STATUS_IS_OK(idmap_get_sid_from_id(psid, id, ID_GROUPID))) { + DEBUG(10, ("gid_to_sid: sid = [%s]\n", sid_string_static(psid))); + return psid; + } + + /* If mapping is not found in idmap try with traditional method, + then stores the result in idmap. + We may add a switch in future to allow smooth migrations to + idmap-only db ---Simo */ + + if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { + sid_copy(psid, &map.sid); + } else { + sid_copy(psid, get_global_sam_sid()); + sid_append_rid(psid, pdb_gid_to_group_rid(gid)); + } + + DEBUG(10,("gid_to_sid: algorithmic %u -> %s\n", (unsigned int)gid, sid_string_static(psid))); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert SID to uid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. sidtype is set by this function. +*****************************************************************/ + +BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +{ + unid_t id; + int type; + + DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(psid))); + + *sidtype = SID_NAME_USER; + + type = ID_USERID; + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, psid))) { + DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid)); + *puid = id.uid; + return True; + } + + if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { + BOOL result; + uint32 rid; + + DEBUG(10,("sid_to_uid: sid is local [%s]\n", sid_string_static(get_global_sam_sid()))); + + if (!sid_peek_rid(psid, &rid)) { + DEBUG(0, ("sid_to_uid: Error extracting RID from SID\n!")); + return False; + } + if (!pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_uid: RID %u is *NOT* a user\n", (unsigned)rid)); + return False; + } + *puid = fallback_pdb_user_rid_to_uid(rid); + return True; + } + return False; +} + +/***************************************************************** + *THE CANONICAL* convert SID to gid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +{ + unid_t id; + int type; + + DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(psid))); + + *sidtype = SID_NAME_ALIAS; + + type = ID_GROUPID; + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, psid))) { + DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid)); + *pgid = id.gid; + return True; + } + + if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { + GROUP_MAP map; + BOOL result; + + if (pdb_getgrsid(&map, *psid, MAPPING_WITHOUT_PRIV)) { + /* the SID is in the mapping table but not mapped */ + if (map.gid==(gid_t)-1) + return False; + + *pgid = map.gid; + *sidtype = map.sid_name_use; + return True; + } else { + uint32 rid; + + if (!sid_peek_rid(psid, &rid)) { + DEBUG(0, ("sid_to_gid: Error extracting RID from SID\n!")); + return False; + } + if (pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_gid: RID %u is *NOT* a group\n", (unsigned)rid)); + return False; + } + *pgid = pdb_group_rid_to_gid(rid); + *sidtype = SID_NAME_ALIAS; + } + } + + return False; +} + |