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.