From 671c0098f683510194ae672973b167c0532eeba8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Feb 2006 19:07:58 +0000 Subject: r13545: A patch which I think it's time has come. VOlker, we can talk about this more but it gets around the primary group issue. * don't map a SID to a name from the group mapping code if the map doesn't have a valid gid. This is only an issue in a tdb setup * Always allow S-1-$DOMAIN-513 to resolve (just like Windows) * if we cannot resolve a users primary GID to a SID, then set it to S-1-$DOMAIN-513 * Ignore the primary group SID inside pdb_enum_group_memberships(). Only look at the Unix group membersip. Jeremy, this fixes a fresh install startup for smbd as far as my tests are concerned. (This used to be commit f79f4dc4c58a6172bf69d37469fdd8de05a812df) --- source3/passdb/passdb.c | 22 +++++++++++----- source3/passdb/pdb_get_set.c | 12 ++++++++- source3/passdb/pdb_interface.c | 60 ++++++++++++++++++++++++++---------------- 3 files changed, 64 insertions(+), 30 deletions(-) (limited to 'source3') diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 2b1da6ecce..a50afb6bb8 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -218,6 +218,8 @@ static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd } } + /* we really need to throw away the mapping algorithm here */ + if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { DEBUG(0,("Can't set User SID from RID!\n")); return NT_STATUS_INVALID_PARAMETER; @@ -229,17 +231,23 @@ static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd unbecome_root(); if( ret ) { - if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ + if ( !pdb_set_group_sid(account_data, &map.sid, PDB_SET) ) { DEBUG(0,("Can't set Group SID!\n")); return NT_STATUS_INVALID_PARAMETER; } + + return NT_STATUS_OK; } - else { - if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } + + /* at this point we do not have an explicit mapping for the user's + primary group. We do not want to fall back to the rid mapping + algorithm. Windows standalone servers set the 0x201 rid as the + primary group and LookupSid( S-1...-513 ) returns SERVER\None. + Do something similar. Use the Domain Users RID as a a placeholder. + This is a workaround only. */ + + if ( !pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_USERS, PDB_SET)) + return NT_STATUS_INVALID_PARAMETER; return NT_STATUS_OK; } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 71fb36e0d5..046e658d2b 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -571,10 +571,20 @@ BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag) { + gid_t gid; + if (!sampass || !g_sid) return False; - sid_copy(&sampass->private_u.group_sid, g_sid); + /* if we cannot resolve the SID to gid, then just ignore it and + store DOMAIN_USERS as the primary groupSID */ + + if ( sid_to_gid( g_sid, &gid ) ) { + sid_copy(&sampass->private_u.group_sid, g_sid); + } else { + sid_copy( &sampass->private_u.group_sid, get_global_sam_sid() ); + sid_append_rid( &sampass->private_u.group_sid, DOMAIN_GROUP_RID_USERS ); + } DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", sid_string_static(&sampass->private_u.group_sid))); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index c8917b9356..f42ff3a725 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1498,14 +1498,29 @@ NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods, { size_t i; gid_t gid; + struct passwd *pw; + const char *username = pdb_get_username(user); + +#if 0 + /* Ignore the primary group SID. Honor the real Unix primary group. + The primary group SID is only of real use to Windows clients */ + if (!sid_to_gid(pdb_get_group_sid(user), &gid)) { DEBUG(10, ("sid_to_gid failed\n")); return NT_STATUS_NO_SUCH_USER; } +#else + if ( !(pw = getpwnam_alloc(mem_ctx, username)) ) { + return NT_STATUS_NO_SUCH_USER; + } + + gid = pw->pw_gid; + + TALLOC_FREE( pw ); +#endif - if (!getgroups_unix_user(mem_ctx, pdb_get_username(user), gid, - pp_gids, p_num_groups)) { + if (!getgroups_unix_user(mem_ctx, username, gid, pp_gids, p_num_groups)) { return NT_STATUS_NO_SUCH_USER; } @@ -1581,32 +1596,33 @@ static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, ret = pdb_getgrsid(&map, sid); unbecome_root(); /* END BECOME_ROOT BLOCK */ - - if ( ret ) { - if (map.gid!=(gid_t)-1) { - DEBUG(5,("lookup_global_sam_rid: mapped group %s to " - "gid %u\n", map.nt_name, - (unsigned int)map.gid)); - } else { - DEBUG(5,("lookup_global_sam_rid: mapped group %s to " - "no unix gid. Returning name.\n", - map.nt_name)); - } - + + /* do not resolve SIDs to a name unless there is a valid + gid associated with it */ + + if ( ret && (map.gid != (gid_t)-1) ) { *name = talloc_strdup(mem_ctx, map.nt_name); *psid_name_use = map.sid_name_use; - if (unix_id == NULL) { - return True; + if ( unix_id ) { + unix_id->gid = map.gid; } - if (map.gid == (gid_t)-1) { - DEBUG(5, ("Can't find a unix id for an unmapped " - "group\n")); - return False; - } + return True; + } + + /* Windows will always map RID 513 to something. On a non-domain + controller, this gets mapped to SERVER\None. */ - unix_id->gid = map.gid; + if ( unix_id ) { + DEBUG(5, ("Can't find a unix id for an unmapped group\n")); + return False; + } + + if ( rid == DOMAIN_GROUP_RID_USERS ) { + *name = talloc_strdup(mem_ctx, "None" ); + *psid_name_use = IS_DC ? SID_NAME_DOM_GRP : SID_NAME_ALIAS; + return True; } -- cgit