On Wed, 2012-05-23 at 03:52 -0400, Geoffrey Thomas wrote:
On Wed, 23 May 2012, Jakub Hrozek wrote:
- If the answer to the above is true, how does SSSD resolve conflicts between two domains which have entries that claim the same UID? I understand that the max_id/min_id functionality is intended to address this partially, but does SSSD do any further sanity checks, such as refusing information from remote domains that exist in local domains?
I think the multi domain support in SSSD would help your use case. When the SSSD is configured with multiple domains, it queries them in the order they are defined in the config file and the first match is always[*] returned.
So provided that a given UID exists in both local and remote domains, the NSS responder would search the local domain first, if the UID was found there, the remote domain would not be even checked.
Hi Jakub, thanks for your reply.
I think this case is a little more subtle than your answer is referring to; namely, how does SSSD handle a lookup for a username in a remote domain that conflicts with a UID from a local domain?
I think we need to get some terminology straight first. There are two kinds of "local" users. There are those users that appear in /etc/passwd and then there are those that can appear in an SSSD domain using the LOCAL provider. They are very different animals.
I'm working under the assumption that when you speak of "local domains" here, you're talking about /etc/passwd. If this is wrong, please correct me.
For instance, if an LDAP server replies to a passwd-style query with
cn: geofft uidNumber: 0
it should not result in a passwd entry of "geofft:*:0:..." being returned. While for the specific case of 0 this is handled by min_id, it applies equally well to any local account on the system; if I have a local user account with UID 1000 or 20000 or whatever, I wouldn't want a remote account to be able to use that UID on my local system.
Ok, let's talk a little bit about the nsswitch interface here. That may clear things up a bit.
Nsswitch ordering is handled by /etc/nsswitch.conf. In most situations, you will have the following specified in that file: passwd: files sss
This means that any lookup calling 'getpwnam()' or 'getpwuid()' will first check to see if it exists in the files map (aka /etc/passwd). If it does, it will return that value and that will be that.
Let's work with the following sample data. (We'll use LDAP as the SSSD domain name, for simplicity) In /etc/passwd: username 'geofft' with UID 2000 in LDAP: username 'geofft' with UID 3000 in LDAP: username 'imposter' with UID 2000
So if you have user 'geofft' in /etc/passwd and also in LDAP, you will get back the information from /etc/passwd for getpwnam("geofft"). So you will get back UID 2000.
If you call getpwnam("geofft@LDAP"), you will bypass the /etc/passwd file and get back UID 3000
If you call getpwuid(2000), you will get back user 'geofft' from /etc/passwd
If you call getpwuid(3000), you will get back user 'geofft' from LDAP
- Additionally, users may come with groups, and it is bad if remote domains can spoof ownership in local groups. Is there anyway to lock this down?
The current SSSD version would not resolve local memberships in a remote group, it would only query the same remote domain. See also https://fedorahosted.org/sssd/ticket/1020
Maybe we're not understanding SSSD's model right, but we're curious about (purported) remote memberships in a local group. As above, if a remote user claims in its group list (the return of getgrouplist(3)) to be in a local group like bin or disk or sudo, I wouldn't want that to be respected on my local machine. Again, minimum gids go partway to solving this, but I wouldn't want a remote user who claims to be in gid 1000 or group geofft to be able to access group-readable files I write, etc.
This cannot happen. Similar to the /etc/passwd example I described above, lookups for a particular group name or GID would stop at /etc/group if the name or GID matched there first. It would not take ANY group membership information for groups in /etc/group from LDAP. If you wanted to add a remote user to a local group, you would need to add that user's name to /etc/group manually.
The one catch is the user's primary group ID. Most of the time, this would be set to a user private group for security reasons, but it's theoretically possible that an LDAP user could have it set to be e.g. 10 ('wheel' on RHEL). In this case, the local system WILL honor it.
That said, I think maybe we want to add an option to filter out certain values for primary group ID in order to avoid this issue. It's a valid concern. Please file an RFE at https://fedorahosted.org/sssd (you can get an account from https://admin.fedoraproject.org/accounts if you do not have one).
Local memberships in a remote group seem acceptable security-wise; a local system administrator can decide that it's fine for a user account to be in whatever the remote server says a group is. But a remote server should not be able to inject users into local groups.
- It is frequently useful for applications running on the system to be able to identify nonlocal users as opposed to local users; we had a nsswitch module which identified nonlocal users and added them to their own group. Does this functionality exist in SSSD? (It's also convenient to have another group which contains local users.)
SSSD does not currently have any such functionality. I'd be interested to see how this module works, as I have a feeling it would be broken by recent changes glibc made to the initgroups interface.
I can't think of a nice way of doing this short of ID value checks or querying the local database directly.
Is it not possible for the domain lookup to insert an identifier for that domain in the returned group list on getgrouplist(3)/getgroups(3)? If I create two local groups, say, "local_users" and "remote_users", it seems straightforward to add one of those two groups to group lists before returning them to the NSS client.
We *could* munge the initgroups() lookup so that it would report membership in those groups, but we couldn't do the reverse, because as mentioned above we don't have the ability (or want to) to add remote users into local groups (except for the primary group loophole that we should close). So I'm not sure this is a wise move. Doing getgrnam("remote_users") would be unable to provide an actual list of users in the group.
I'm not a huge fan of making changes to memberships that aren't reciprocal.