neil klopfenstein
2005-Jun-02 17:04 UTC
[Samba] Winbindd chokes on W2K users in only one group
Hi there, I've been trying to set up Samba 3.0.14a with Active Directory integration on a network with an ordinary W2k Server PDC. I'm currently having a problem which I'm convinced has nothing to do with my Windows or Samba configuration. The problem only occurs when trying to connect to the Samba server from an authenticated domain account which is only a member of the default 'Domain users' group. When this is the case, the 'make_server_info_from_pw' function returns NT_STATUS_NO_SUCH_USER, incorrectly. Here is an appropriate log fragment (debug = 5): [2005/06/02 12:51:19, 3] libads/ads_ldap.c:ads_sid_to_dn(222) ads sid_to_dn mapped CN=Neil Klopfenstein,CN=Users,DC=geovectra,DC=cl [2005/06/02 12:51:19, 5] libads/ldap_utils.c:ads_do_search_retry(56) Search for (objectclass=*) gave 1 replies [2005/06/02 12:51:19, 3] nsswitch/winbindd_ads.c:lookup_usergroups_alt(463) ads: lookup_usergroups_alt [2005/06/02 12:51:19, 5] libads/ldap_utils.c:ads_do_search_retry(56) Search for (&(member=CN=Neil Klopfenstein,CN=Users,DC=geovectra,DC=cl)(objectClass=group)) gave 0 replies [2005/06/02 12:51:19, 5] nsswitch/winbindd_ads.c:lookup_usergroups_alt(498) lookup_usergroups: No supp groups found [2005/06/02 12:51:19, 4] auth/auth_util.c:add_user_groups(796) get_user_groups_from_local_sam failed [2005/06/02 12:51:19, 5] auth/auth_util.c:free_server_info(1406) attempting to free (and zero) a server_info structure [2005/06/02 12:51:19, 1] smbd/sesssetup.c:reply_spnego_kerberos(265) make_server_info_from_pw failed! [2005/06/02 12:51:19, 3] smbd/error.c:error_packet(105) error string = No such file or directory [2005/06/02 12:51:19, 3] smbd/error.c:error_packet(129) error packet at smbd/sesssetup.c(270) cmd=115 (SMBsesssetupX) NT_STATUS_NO_SUCH_USER If the same user is added to another group, it works fine, though. I'm a little surprised that I have not seen this problem reported anywhere else, so there is probably something else going on. For what it's worth, I am using a Spanish version of Redhat 9, compiling Samba with the 'makerpms.sh' script, and also using the Spanish version of Windows 2000 Server with the most recent service pack. I have experienced this problem in 3.0.13 and 3.0.14a. I didn't try any earlier versions. -- neil klopfenstein
On Thu, Jun 02, 2005 at 01:04:35PM -0400, neil klopfenstein wrote:> I've been trying to set up Samba 3.0.14a with Active Directory > integration on a network with an ordinary W2k Server PDC. I'm currently > having a problem which I'm convinced has nothing to do with my Windows > or Samba configuration. > > The problem only occurs when trying to connect to the Samba server from > an authenticated domain account which is only a member of the default > 'Domain users' group. When this is the case, the > 'make_server_info_from_pw' function returns NT_STATUS_NO_SUCH_USER, > incorrectly. >I get the same behavior, with users completely unable to connect. They are unable to even view the shares on the server. Another symptom of this behavior is that executing "wbinfo -r <user>" with a user that is only a member of a single group (the primary group of the user) results in the error "Could not get groups for user <user>". On any user in multiple groups, this command completes successfully, showing every group the user is a member of, including the user's primary group.> If the same user is added to another group, it works fine, though. > > I have experienced this problem in 3.0.13 and 3.0.14a. I didn't try any > earlier versions.I also had this problem with 3.0.14a and upgrading to 3.0.20rc2 showed the same behavior. At quick glance, the SAMBA_3_0 SVN code appears to have the same problem also. Looking over the code, it appears that the cause of the problem is in the lookup_usergroups_alt function in winbindd_ads.c. This function only gets called when the 'tokenGroups' attribute of the AD user object does not contain any groups. According to the comments in this file, instances where 'tokenGroups' does not contain any groups indicates a "buggy Win2k server". The Active Directory domain controllers are running Windows 2000 SP4 with Active Directory in mixed mode and every user object that I checked has an empty 'tokenGroups' attribute. Instead of getting the user's group membership from the 'tokenGroups' attribute, lookup_usergroups_alt queries AD for any groups that have the user listed in their 'member' attribute. Primary groups memberships however don't appear to be contained in either the 'member' attribute of the group or the 'memberOf' attribute of the user (at least in the case of the Domain Users group). Instead, the RID of the primary group (e.g. 513 for Domain Users) is contained in the 'primaryGroupID' attribute of the user. In the lookup_usergroups_alt function, for cases where the user is not a member of any other groups other than the primary group, the query for any groups with the user as a member returns zero results. Instead of returning just the primary group, lookup_usergroups_alt instead returns no groups. Correcting the logic can easily be done by returning the primary group for this case. Patches for 3.0.14a and SAMBA_3_0 branch included. Is there something uncommon about the above attributes in AD? Do these attributes vary with the different AD versions? Ed Plese -------------- next part -------------- diff -ur samba-3.0.14a/source/nsswitch/winbindd_ads.c samba-3.0.14a-patched/source/nsswitch/winbindd_ads.c --- samba-3.0.14a/source/nsswitch/winbindd_ads.c 2005-04-14 01:14:21.000000000 -0500 +++ samba-3.0.14a-patched/source/nsswitch/winbindd_ads.c 2005-08-17 07:46:54.000000000 -0500 @@ -494,37 +494,37 @@ } count = ads_count_replies(ads, res); - if (count == 0) { - DEBUG(5,("lookup_usergroups: No supp groups found\n")); - - status = ads_ntstatus(rc); - goto done; - } - + + /* always add the primary group to the user_gids list */ (*user_gids) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID *, count + 1); (*user_gids)[0] = primary_group; *num_groups = 1; + + + if (count > 0) { - for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - DOM_SID group_sid; + for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + DOM_SID group_sid; - if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { - DEBUG(1,("No sid for this group ?!?\n")); - continue; - } + if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { + DEBUG(1,("No sid for this group ?!?\n")); + continue; + } - if (sid_equal(&group_sid, primary_group)) continue; + if (sid_equal(&group_sid, primary_group)) continue; - (*user_gids)[*num_groups] = TALLOC_P(mem_ctx, DOM_SID); - if (!(*user_gids)[*num_groups]) { - status = NT_STATUS_NO_MEMORY; - goto done; - } + (*user_gids)[*num_groups] = TALLOC_P(mem_ctx, DOM_SID); + if (!(*user_gids)[*num_groups]) { + status = NT_STATUS_NO_MEMORY; + goto done; + } - sid_copy((*user_gids)[*num_groups], &group_sid); + sid_copy((*user_gids)[*num_groups], &group_sid); - (*num_groups)++; + (*num_groups)++; + + } } -------------- next part -------------- Index: source/nsswitch/winbindd_ads.c ==================================================================--- source/nsswitch/winbindd_ads.c (revision 9355) +++ source/nsswitch/winbindd_ads.c (working copy) @@ -499,28 +499,27 @@ } count = ads_count_replies(ads, res); - if (count == 0) { - DEBUG(5,("lookup_usergroups: No supp groups found\n")); - - status = ads_ntstatus(rc); - goto done; - } *user_sids = NULL; *num_groups = 0; + /* always add the primary group to the sid array */ add_sid_to_array(mem_ctx, primary_group, user_sids, num_groups); - for (msg = ads_first_entry(ads, res); msg; - msg = ads_next_entry(ads, msg)) { - DOM_SID group_sid; + if (count > 0) { + for (msg = ads_first_entry(ads, res); msg; + msg = ads_next_entry(ads, msg)) { + DOM_SID group_sid; - if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { - DEBUG(1,("No sid for this group ?!?\n")); - continue; + if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { + DEBUG(1,("No sid for this group ?!?\n")); + continue; + } + + add_sid_to_array(mem_ctx, &group_sid, user_sids, + num_groups); } - add_sid_to_array(mem_ctx, &group_sid, user_sids, num_groups); } status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;