From 02cb8d63bcdf3c55f56d69f17bc905b1047cc573 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Jul 2002 09:26:44 +0000 Subject: Update a pile of Samba's SID lookup code to ensure: - That we never call winbind recursivly - That we never use an 'algorithmic' RID when we have a fixed uid or gid mapping in either the passdb or the group mapping db. Also, remove restrictions that say 'this domain only'. If we have a mapping configured, allow it to be returned. If we later decide certian mappings are invalid, then we sould put that in the code that actually does the map. Allow 'sid->name' transtations on the fixed 'well known' groups for NT, even if they are not represented by Unix groups yet. Andrew Bartlett (This used to be commit d5bafb224337e393420c2ce9c0a787405314713c) --- source3/passdb/passdb.c | 93 ++++++++++++++++++++++++++++--------------------- source3/smbd/uid.c | 74 ++++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 75 deletions(-) (limited to 'source3') diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 3f1425e240..1c33fda39d 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -719,15 +719,9 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi /* check if it's a mapped group */ if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { - if (map.gid!=-1) { - /* yes it's a mapped group to a valid unix group */ - sid_copy(&local_sid, &map.sid); - *psid_name_use = map.sid_name_use; - } - else { - /* it's a correct name but not mapped so it points to nothing*/ - return False; - } + /* yes it's a mapped group */ + sid_copy(&local_sid, &map.sid); + *psid_name_use = map.sid_name_use; } else { /* it's not a mapped group */ grp = getgrnam(user); @@ -807,23 +801,11 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) { - DOM_SID dom_sid; - uint32 rid; fstring str; SAM_ACCOUNT *sam_user = NULL; *name_type = SID_NAME_UNKNOWN; - sid_copy(&dom_sid, psid); - sid_split_rid(&dom_sid, &rid); - - /* - * We can only convert to a uid if this is our local - * Domain SID (ie. we are the controling authority). - */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) - return False; - if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) return False; @@ -835,12 +817,38 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) } DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), (unsigned int)*puid, pdb_get_username(sam_user))); - } else { - DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid))); pdb_free_sam(&sam_user); + } else { + + DOM_SID dom_sid; + uint32 rid; + GROUP_MAP map; + + pdb_free_sam(&sam_user); + + if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { + DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid))); + /* It's a group, not a user... */ + return False; + } + + sid_copy(&dom_sid, psid); + if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) { + DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid))); + return False; + } + + if (!pdb_rid_is_user(rid)) { + DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becous it is a group\n", sid_to_string(str, psid))); + return False; + } + + *puid = fallback_pdb_user_rid_to_uid(rid); + + DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", + sid_to_string(str, psid), (signed long int)(*puid))); return False; } - pdb_free_sam(&sam_user); *name_type = SID_NAME_USER; @@ -873,16 +881,11 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) { - DOM_SID dom_sid; - uint32 rid; fstring str; GROUP_MAP map; *name_type = SID_NAME_UNKNOWN; - sid_copy(&dom_sid, psid); - sid_split_rid(&dom_sid, &rid); - /* * We can only convert to a gid if this is our local * Domain SID (ie. we are the controling authority). @@ -890,35 +893,45 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) * Or in the Builtin SID too. JFM, 11/30/2001 */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) - return False; - if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ if (map.gid==-1) return False; - if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){ - DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n", - sid_string_static(&map.sid))); - return False; - } *pgid = map.gid; *name_type = map.sid_name_use; - DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid), + DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", + sid_to_string( str, psid), map.nt_name, (unsigned int)*pgid)); } else { - if (pdb_rid_is_user(rid)) + uint32 rid; + SAM_ACCOUNT *sam_user = NULL; + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) + return False; + + if (pdb_getsampwsid(sam_user, psid)) { return False; + pdb_free_sam(&sam_user); + } + + pdb_free_sam(&sam_user); + + if (!sid_peek_rid(psid, &rid)) { + DEBUG(2, ("sid_peek_rid failed! what kind of sid is this? '%s'\n", sid_to_string(str, psid))); + return False; + } + if (pdb_rid_is_user(rid)) + return False; + *pgid = pdb_group_rid_to_gid(rid); *name_type = SID_NAME_ALIAS; DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid), (unsigned int)*pgid)); } - + return True; } diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2dcef54a5b..bf609e62e6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -440,44 +440,43 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N extern pstring global_myname; extern fstring global_myworkgroup; fstring sid; - BOOL ret = False; + BOOL local_lookup = False; *name_type = SID_NAME_UNKNOWN; /* If we are looking up a domain user, make sure it is for the local machine only */ - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: + if (strequal(global_myname, domain)) { + local_lookup = True; + } else if (lp_server_role() == ROLE_DOMAIN_PDC || + lp_server_role() == ROLE_DOMAIN_PDC) { if (strequal(domain, global_myworkgroup)) { - ret = local_lookup_name(name, psid, name_type); - } - /* No break is deliberate here. JRA. */ - default: - if (ret) { - } else if (strequal(global_myname, domain)) { - ret = local_lookup_name(name, psid, name_type); - } else { - DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); + local_lookup = True; } } - - if (ret) { - DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", - domain, name, sid_to_string(sid,psid), - sid_type_lookup(*name_type), (unsigned int)*name_type)); - return True; - } else if (winbind_lookup_name(domain, name, psid, name_type)) { - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; + if (local_lookup) { + if (local_lookup_name(name, psid, name_type)) { + DEBUG(10, + ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", + domain, name, sid_to_string(sid,psid), + sid_type_lookup(*name_type), (unsigned int)*name_type)); + return True; + } + } else { + /* Remote */ + if (winbind_lookup_name(domain, name, psid, name_type)) { + + DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid, psid), + (unsigned int)*name_type)); + return True; + } } - - DEBUG(10, ("lookup_name: winbind and local lookups for [%s]\\[%s] failed\n", domain, name)); + + DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", + local_lookup ? "local" : "winbind", domain, name)); return False; } @@ -680,16 +679,21 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) * First we must look up the name and decide if this is a group sid. */ + /* if we know its local then don't try winbindd */ + if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { + BOOL result; + become_root(); + result = local_sid_to_gid(pgid, psid, sidtype); + unbecome_root(); + return result; + } + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - if (!local_sid_to_gid(pgid, psid, sidtype)) { - /* this was probably a foreign sid - assume its a group rid - and continue */ - name_type = SID_NAME_DOM_GRP; - } else { - return True; - } + /* this was probably a foreign sid - assume its a group rid + and continue */ + name_type = SID_NAME_DOM_GRP; } /* @@ -700,7 +704,7 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); - return local_sid_to_gid(pgid, psid, sidtype); + return False; } *sidtype = name_type; -- cgit