summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2002-07-30 09:26:44 +0000
committerAndrew Bartlett <abartlet@samba.org>2002-07-30 09:26:44 +0000
commit02cb8d63bcdf3c55f56d69f17bc905b1047cc573 (patch)
tree2e49e20d7547010b08248c44b8a9de0ea0d2763f
parent01d9beba6cf2882dc30445b68b3ae54d3bb17679 (diff)
downloadsamba-02cb8d63bcdf3c55f56d69f17bc905b1047cc573.tar.gz
samba-02cb8d63bcdf3c55f56d69f17bc905b1047cc573.tar.xz
samba-02cb8d63bcdf3c55f56d69f17bc905b1047cc573.zip
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)
-rw-r--r--source3/passdb/passdb.c93
-rw-r--r--source3/smbd/uid.c74
2 files changed, 92 insertions, 75 deletions
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;