From 75cace04fdcb672cc6c3c3ec8403206f2b222c50 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 1 May 2003 11:47:48 +0000 Subject: *id_to_*id call reshape to return NTSTATUS errors plus internal fixes 1st stage (This used to be commit 6d036761e565bc93964bb3c939d5b7d78d5778a3) --- source3/sam/idmap.c | 30 -------- source3/sam/idmap_tdb.c | 17 ++++- source3/sam/idmap_util.c | 183 +++++++++++++++++++++++++++++------------------ 3 files changed, 128 insertions(+), 102 deletions(-) (limited to 'source3/sam') diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c index e0634681de..9695e7b764 100644 --- a/source3/sam/idmap.c +++ b/source3/sam/idmap.c @@ -102,35 +102,6 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) lazy_initialize_idmap(); - if (!lp_idmap_only()) { - if (id_type & ID_USERID) { - uid_t low, high; - if (!lp_idmap_uid(&low, &high)) { - DEBUG(0, ("idmap uid range missing or invalid\n")); - DEBUGADD(0, ("idmap will be unable to map SIDs\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (low > id.uid || high < id.uid) { - DEBUG(0, ("uid not in range and idmap only is flase - not storing the mapping\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } else if (id_type & ID_GROUPID) { - gid_t low, high; - if (!lp_idmap_gid(&low, &high)) { - DEBUG(0, ("idmap gid range missing or invalid\n")); - DEBUGADD(0, ("idmap will be unable to map SIDs\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (low > id.gid || high < id.gid) { - DEBUG(0, ("uid not in range and idmap only is flase - not storing the mapping\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } else { - DEBUG(0, ("Wrong ID Type, mapping failed!")); - return NT_STATUS_UNSUCCESSFUL; - } - } - ret = local_map->set_mapping(sid, id, id_type); if (NT_STATUS_IS_ERR(ret)) { DEBUG (0, ("idmap_set_mapping: Error, unable to modify local cache!\n")); @@ -239,4 +210,3 @@ void idmap_status(void) local_map->status(); if (remote_map) remote_map->status(); } - diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index f85d2db086..ab86eaf4eb 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -213,7 +213,7 @@ idok: static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) { - TDB_DATA ksid, kid; + TDB_DATA ksid, kid, data; fstring ksidstr; fstring kidstr; @@ -235,6 +235,20 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) kid.dptr = kidstr; kid.dsize = strlen(kidstr) + 1; + /* *DELETE* prevoius mappings if any. + * This is done both SID and [U|G]ID passed in */ + + data = tdb_fetch(idmap_tdb, ksid); + if (data.dptr) { + tdb_delete(idmap_tdb, data); + tdb_delete(idmap_tdb, ksid); + } + data = tdb_fetch(idmap_tdb, kid); + if (data.dptr) { + tdb_delete(idmap_tdb, data); + tdb_delete(idmap_tdb, kid); + } + if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) { DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb))); return NT_STATUS_UNSUCCESSFUL; @@ -427,4 +441,3 @@ NTSTATUS idmap_reg_tdb(struct idmap_methods **meth) return NT_STATUS_OK; } - diff --git a/source3/sam/idmap_util.c b/source3/sam/idmap_util.c index 3086ee2113..5d089d3baf 100644 --- a/source3/sam/idmap_util.c +++ b/source3/sam/idmap_util.c @@ -112,146 +112,189 @@ BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high) /***************************************************************** *THE CANONICAL* convert uid_t to SID function. - Tries winbind first - then uses local lookup. + check idmap if uid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs Returns SID pointer. *****************************************************************/ -DOM_SID *uid_to_sid(DOM_SID *sid, uid_t uid) +NTSTATUS uid_to_sid(DOM_SID *sid, uid_t uid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; unid_t id; + int flags; DEBUG(10,("uid_to_sid: uid = [%d]\n", uid)); - if (idmap_check_ugid_is_in_free_range(uid)) { - id.uid = uid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_USERID))) { - DEBUG(10, ("uid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); - return NULL; + flags = ID_USERID; + if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(uid)) { + flags |= ID_NOMAP; + } + + id.uid = uid; + if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) { + DEBUG(10, ("uid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); + if (flags & ID_NOMAP) { + sid_copy(sid, get_global_sam_sid()); + sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid)); + + DEBUG(10,("uid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)uid, sid_string_static(sid))); + ret = NT_STATUS_OK; } - } else { - sid_copy(sid, get_global_sam_sid()); - sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid)); - - DEBUG(10,("uid_to_sid: algorithmic %u -> %s\n", (unsigned int)uid, sid_string_static(sid))); } - return sid; - + + return ret; } /***************************************************************** *THE CANONICAL* convert gid_t to SID function. - Tries winbind first - then uses local lookup. + check idmap if gid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs Returns SID pointer. *****************************************************************/ -DOM_SID *gid_to_sid(DOM_SID *sid, gid_t gid) +NTSTATUS gid_to_sid(DOM_SID *sid, gid_t gid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; GROUP_MAP map; unid_t id; + int flags; DEBUG(10,("gid_to_sid: gid = [%d]\n", gid)); - if (idmap_check_ugid_is_in_free_range(gid)) { - id.gid = gid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_GROUPID))) { - DEBUG(10, ("gid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); - return NULL; - } - } else { - if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { - sid_copy(sid, &map.sid); - } else { - sid_copy(sid, get_global_sam_sid()); - sid_append_rid(sid, pdb_gid_to_group_rid(gid)); - } + flags = ID_GROUPID; + if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(gid)) { + flags |= ID_NOMAP; + } + + id.gid = gid; + if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) { + DEBUG(10, ("gid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); + if (flags & ID_NOMAP) { + if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { + sid_copy(sid, &map.sid); + } else { + sid_copy(sid, get_global_sam_sid()); + sid_append_rid(sid, pdb_gid_to_group_rid(gid)); + } - DEBUG(10,("gid_to_sid: algorithmic %u -> %s\n", (unsigned int)gid, sid_string_static(sid))); + DEBUG(10,("gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)gid, sid_string_static(sid))); + ret = NT_STATUS_OK; + } } - return sid; + return ret; } /***************************************************************** *THE CANONICAL* convert SID to uid function. - Tries winbind first - then uses local lookup. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs Returns True if this name is a user sid and the conversion - was done correctly, False if not. sidtype is set by this function. + was done correctly, False if not. *****************************************************************/ -BOOL sid_to_uid(const DOM_SID *sid, uid_t *uid) +NTSTATUS sid_to_uid(const DOM_SID *sid, uid_t *uid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL fallback = False; uint32 rid; unid_t id; - int type; + int flags; DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(sid))); - if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { - if (!idmap_check_rid_is_in_free_range(rid)) { - if (!fallback_pdb_rid_is_user(rid)) { - DEBUG(3, ("sid_to_uid: RID %u is *NOT* a user\n", (unsigned)rid)); - return False; + flags = ID_USERID; + if (!lp_idmap_only()) { + if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + if (!idmap_check_rid_is_in_free_range(rid)) { + flags |= ID_NOMAP; + fallback = True; } - *uid = fallback_pdb_user_rid_to_uid(rid); - return True; } } - type = ID_USERID; - if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) { + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) { DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid)); *uid = id.uid; - return True; + ret = NT_STATUS_OK; + } else if (fallback) { + DEBUG(10,("sid_to_uid: Fall back to algorithmic mapping\n")); + if (!fallback_pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_uid: SID %s is *NOT* a user\n", sid_string_static(sid))); + ret = NT_STATUS_UNSUCCESSFUL; + } else { + *uid = fallback_pdb_user_rid_to_uid(rid); + DEBUG(10,("sid_to_uid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*uid))); + ret = NT_STATUS_OK; + } } - return False; + return ret; } /***************************************************************** *THE CANONICAL* convert SID to gid function. - Tries winbind first - then uses local lookup. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs 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 *sid, gid_t *gid) +NTSTATUS sid_to_gid(const DOM_SID *sid, gid_t *gid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL fallback = False; uint32 rid; unid_t id; - int type; + int flags; DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid))); - if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + flags = ID_GROUPID; + if (!lp_idmap_only()) { + if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + if (!idmap_check_rid_is_in_free_range(rid)) { + flags |= ID_NOMAP; + fallback = True; + } + } + } + + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) { + DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid)); + *gid = id.gid; + ret = NT_STATUS_OK; + } else if (fallback) { GROUP_MAP map; BOOL result; + DEBUG(10,("sid_to_gid: Fall back to algorithmic mapping\n")); + + /* the group mapping code should register mappings in idmap + * and have the following if() eliminated */ if (pdb_getgrsid(&map, *sid, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ - if (map.gid==(gid_t)-1) - return False; - - *gid = map.gid; - return True; + if (map.gid==(gid_t)-1) { + ret = NT_STATUS_UNSUCCESSFUL; + } else { + *gid = map.gid; + ret = NT_STATUS_OK; + } } else { - if (!idmap_check_rid_is_in_free_range(rid)) { - if (fallback_pdb_rid_is_user(rid)) { - DEBUG(3, ("sid_to_gid: RID %u is *NOT* a group\n", (unsigned)rid)); - return False; - } + if (fallback_pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(sid))); + ret = NT_STATUS_UNSUCCESSFUL; + } else { *gid = pdb_group_rid_to_gid(rid); - return True; + DEBUG(10,("sid_to_gid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*gid))); + ret = NT_STATUS_OK; } } } - type = ID_GROUPID; - if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) { - DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid)); - *gid = id.gid; - return True; - } - - return False; + return ret; } - -- cgit