r13545: A patch which I think it's time has come. VOlker, we can talk about
authorGerald Carter <jerry@samba.org>
Fri, 17 Feb 2006 19:07:58 +0000 (19:07 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 17 Feb 2006 19:07:58 +0000 (19:07 +0000)
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.

source/passdb/passdb.c
source/passdb/pdb_get_set.c
source/passdb/pdb_interface.c

index 2b1da6ecce739610ff55c0082f0de5504f052266..a50afb6bb869e040aef93a6a8dce8335b786a5eb 100644 (file)
@@ -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;
 }
index 71fb36e0d5e8a382db02a112781764622d7345ca..046e658d2bc0673ec2157e13e666bdcdfc7ad749 100644 (file)
@@ -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)));
index c8917b935646097b6c4688c10fadedf4e9c49fd9..f42ff3a72539e2e44da4f6ea4d8061f297a02eea 100644 (file)
@@ -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;
        }