SMB logon should tolerate idmap problems
There are cases where SMB logon fails because idmap can't translate some SIDs to Unix UID or GID values (i.e. "foreign" SIDs). Currently, the SMB server fails the logon in such cases, but it would be better to simply report the SIDs that could not be mapped and let the logon continue with the subset of IDs that we were able to map.
Steps to Reproduce:
Unclear. This was seen at a customer that had some SIDs that idmap could not map to GIDs.
Logon should work.
Logon fails for some users.
Updated by Gordon Ross 5 months ago
On the customer system where this was observed, they have a very complicated AD environment which (among other things) has an incomplete set of AD schema extensions for Unix-compatible user and group IDs. That means only some users and groups have the "uidNumber" or "gidNumber" attribute, and most have no such attributes.
With the above described AD environment, lookup to get a Unix GID for some groups will fail. Normally that's OK, but in our logon code path that can cause logon to fail. Here's how:
We successfully authenticate the user and have a valid smb_token_t containing (among other things) a list of SIDs for the groups in which this user is a member. Then (in smbd) smb_logon calls smb_token_setup_common, and smb_token_sids2ids.
In smb_token_sids2ids, we try to get UIDs or GIDs for every SID.
Summarizing this function: (without most error checking for brevity)
// allocate... flags = SMB_IDMAP_SID2ID; stat = smb_idmap_batch_create(&sib, nmaps, flags) // put all the questions in the batch request stat = smb_token_idmap(token, &sib); // run the request stat = smb_idmap_batch_getmappings(&sib); smb_idmap_batch_destroy(&sib);
In the customer's AD environment, smb_idmap_batch_getmapping returns an error because a few (some 19 of the 250 or so) SIDs could not be mapped to GIDs.
That causes an error return from smb_token_sids2ids, after which we fail the logon.
Updated by Gordon Ross 5 months ago
The proposed fix is to add a flag new flag (SMB_IDMAP_SKIP_ERRS) to the set supported by smb_idmap_batch_getmappings to tell it to "keep going" when some SIDs cannot be mapped to IDs. Note that we get the individual mapping status for each SID-to-ID mapping request, and we get the ID "nobody" as a place-holder result in the result slots when there are failures. We will also log (to the system log) the SIDs that could not be mapped.
The logon code path (smb_token_sids2ids) will pass the new flag SMB_IDMAP_SKIP_ERRS to the smb_idmap_batch_getmappings call, and deal with the possibility that some SIDs may not have been maped. (The caller already handles the case where one or more SIDs map to the uninteresting ID "nobody").
Note that smb_idmap_batch_getmappings is also used in other places, but as those do not pass the new flag, the behavior of those calls remains unchanged.
There were some problems in the "shim" that the SMB server uses to call the idmap service where we did not keep around the domain part of SIDs for which we're requesting mappings. That was OK for the idmap requests, which copy that information, but was inadequate for logging those SIDs when the mapping request fail. There are minor changes required in that idmap "shim" so that we still have the domain SID when we want to log a message about some SID that idmap fails to map.
We tested the proposed fix (just keep going with a subset of UIDs and GIDs when there are some SIDs that can't be mapped). The user that was having problems was able to access the share without problems after this fix. At the same time, we found 19 (very useful) messages in the system log about SIDs that could not be mapped.
Updated by Electric Monk 5 months ago
- Status changed from In Progress to Closed
- % Done changed from 0 to 100
commit a73d9d5e9942f30f383f0bde4010c873549868e5 Author: Gordon Ross <firstname.lastname@example.org> Date: 2019-06-01T16:44:37.000Z 10992 SMB logon should tolerate idmap problems Reviewed by: Matt Barden <email@example.com> Reviewed by: Joyce McIntosh <firstname.lastname@example.org> Reviewed by: Yuri Pankov <email@example.com> Approved by: Richard Lowe <firstname.lastname@example.org>