#3546 oddity in kcm
Closed: Invalid 6 years ago Opened 6 years ago by hedrick.

I'm testing KCM in sssd 1.15.2-50.el7_4.2, centos 7.4.

If I set KRB5CCNAME to KCM: and do kswitch, klist shows the current selected cache. However if I set it to KCM:1003 or KCM:1003: it shows a specific cache with a null suffix, even if it's not current.

If KCM:1003 doesn't exist, but KCM:1003:1192 does, KCM:1003 shows as nonexistent.

This is going to cause problems for NFS. I believe NFS uses the default from krb5.conf to find credentials for a user. With KEYRING, it can use KEYRING:UID: to find the current primary cache for UID. But KCM:UID won't do that.

Furthermore, as root I can't see someone else's KCM. At least "klist KCM:1003:1192" says no cache found even though as user 1003 it's there.

I strongly recommend using the same approach that KEYRING does, with KCM:1003 being the whole collection and not a specific cache.


For NFS, what I'd really like is something like KCM:1003:hedrick, which would use a cache in the KCM collection with hedrick as principal. The KEYRING semantics doesn't really work either, since the currently select cache in a collection isn't necessarily the right one for NFS.

Why do you need KCM:UID? I don't think that works (as was explained to me in https://github.com/krb5/krb5/pull/557#issuecomment-254834623), I think krb5.conf should just specify "KCM:"

On (16/10/17 18:26), Charles Hedrick wrote:

Furthermore, as root I can't see someone else's KCM. At least "klist KCM:1003:1192" says no cache found even though as user 1003 it's there.

Root can do anything. So root can switch UID to sb else and see default UID
in such way. We know about this and it is tracked in different ticket
https://pagure.io/SSSD/sssd/issue/3376.

NFS mostly works now. gssd does a setresuid to change to the user's UID. So KCM: will give a cache for the user.

The problem is that it may not be the right one. Suppose I'm an administrator. I've done "kinit admin" to do administrative work. Since KCM is a collection, I now have two caches, one for me and one for admin. But admin is the currently active one. If the kernel needs to reevaluate an NFS context (either because the ticket just expired or because I'm running gssd with a timeout option, which is most likely case at Rutgers) it will call out to gssd. Gssd will change to my uid, and use KCM:. That will access my current cache. That will be the cache for admin. It will now try to set my NFS session using that cache. That will fail.

I need a way to get gssd to explicitly get a cache out of the collection for my primary principal, even if it's not the currently active one. To avoid modifying gssd, I'd probably use whatever syntax you specify in gssproxy.conf as a credstore, since gssd calls gssproxy before doing its own evaluation.

[Since the same issue exists with KEYRING, what I currently do is add a pam module that copies the credentials into /var/lib/gssproxy/clients/krb5cc_%U, where gssproxy will see them. That way NFS access is independent of whatever cache in the collection happens to be currently active. I'd like to get rid of that pam mechanism.]

Let me give you another manifestation of this issue. I'm currently logged in as hedrick. KRB5CCNAME is set to KEYRING:persistent:1003. Let's suppose I need to do something as admin with IPA. I kinit as hedrick.admin. kinit is smart enough to add a new cache to the collection and make it primary. Because KRB5CCNAME is set to the collection, the new cache is now used.

Suppose I need to do something as root. I sudo. But my environment variables are preserved. So I still have KEYRING:persistent:1003, which is the collection. I still get the primary of that collection, which is hedrick.admin.

Now suppose I'm using KCM. When I become root, KCM: now refers to root's collection. That's not what I want. But I can't set it to KCM:1003, because then it's ambiguous whether that's the whole collection or a specific cache with that name.

You may say I should kinit again as root. But that has other problems. Suppose my colleague is also doing something as root. We're now sharing root's KCM:. He won't be happy If I change the primary collection for root to be hedrick.admin. It' much cleaner to use KCM:1003 even as root. But in that case you have to distinguish between collection and cache. KCM:1003 needs to be 1003's collection, and the caches all need their own suffix.

I.e. it should work like KEYRING.

On (26/10/17 16:22), Charles Hedrick wrote:

Now suppose I'm using KCM. When I become root, KCM: now refers to root's collection. That's not what I want. But I can't set it to KCM:1003, because then it's ambiguous whether that's the whole collection or a specific cache with that name.

ATM root does not have a direct access to users KCM.
https://pagure.io/SSSD/sssd/issue/3376

LS

On (26/10/17 15:31), Charles Hedrick wrote:

NFS mostly works now. gssd does a setresuid to change to the user's UID. So KCM: will give a cache for the user.

The problem is that it may not be the right one. Suppose I'm an administrator. I've done "kinit admin" to do administrative work. Since KCM is a collection, I now have two caches, one for me and one for admin. But admin is the currently active one. If the kernel needs to reevaluate an NFS context (either because the ticket just expired or because I'm running gssd with a timeout option, which is most likely case at Rutgers) it will call out to gssd. Gssd will change to my uid, and use KCM:. That will access my current cache. That will be the cache for admin. It will now try to set my NFS session using that cache. That will fail.

I need a way to get gssd to explicitly get a cache out of the collection for my primary principal, even if it's not the currently active one.

I would say it is a fishy implementation in gssd.

I use two different principals in KCM and firefox always use correct one.
But @simo might knot it better :-)

LS

As far as I know, Firefox will use your current principal. That's presumably the one you want. You can have multiple principals and switch between then using kswitch. As far as I know that works fine.

gssd has a problem that can't easily be solved by the implementation. It doesn't need a cache for your current principal. It needs a cache for your primary principal. I.e. username@domain. This is a problem with KEYRING as well. There's no syntax gssd can use to get a cache for your primary principal.

What it could do is check the whole collection looking for a cache for the specific principal it needs. However it's going through gssapi, which complicates that. I'm going to file a bug against gssd. There appears to be an option to GSSAPI that will search the collection.

On (06/11/17 15:23), Charles Hedrick wrote:

hedrick added a new comment to an issue you are following:
As far as I know, Firefox will use your current principal. That's presumably the one you want. You can have multiple principals and switch between then using kswitch. As far as I know that works fine.

If you mean "current principal" == "default principal" which you can see in
output of klist. Then Firefox can use any principal in my ccache collection.

sh$ klist
Ticket cache: KCM:1000:91818
Default principal: lslebodn@EXAMPLE.COM

Valid starting       Expires              Service principal
11/06/2017 09:40:31  11/06/2017 19:39:49  HTTP/saml.example.com@EXAMPLE.COM
11/06/2017 09:39:49  11/06/2017 19:39:49  krbtgt/EXAMPLE.COM@EXAMPLE.COM
11/06/2017 09:40:07  11/06/2017 19:39:49  imap/mail.example.com@EXAMPLE.COM

sh$ klist -l
Principal name                 Cache name
--------------                 ----------
lslebodn@EXAMPLE.COM           KCM:1000:91818
lslebodn@FEDORAPROJECT.ORG     KCM:1000:27785

sh$ echo $KRB5CCNAME

sh$ echo $?
0

And I do not use kswitch

gssd has a problem that can't easily be solved by the implementation. It doesn't need a cache for your current principal. It needs a cache for your primary principal. I.e. username@domain. This is a problem with KEYRING as well. There's no syntax gssd can use to get a cache for your primary principal.

I cannot see a reason why gssd should try only primary/default principal from
ccache collection. That's purpose of collection to store more principals there.

What it could do is check the whole collection looking for a cache for the specific principal it needs. However it's going through gssapi, which complicates that. I'm going to file a bug against gssd. There appears to be an option to GSSAPI that will search the collection.

:-)

Just a note: when using plain Kerberos API, only default principal in the default ccache in the ccache collection can be used. When GSSAPI is used, whole ccache collection is considered in order to find the principal from the same realm as the target service (if possible). If it is not possible to find such a principal, a default principal from the default ccache in the ccache collection is used to obtain the cross-realm ticket and further a ticket to the target service.

So the borderline is what API is used: plain Kerberos calls or GSSAPI.

On (06/11/17 15:55), Alexander Bokovoy wrote:

Just a note: when using plain Kerberos API, only default principal in the default ccache in the ccache collection can be used. When GSSAPI is used, whole ccache collection is considered in order to find the principal from the same realm as the target service (if possible). If it is not possible to find such a principal, a default principal from the default ccache in the ccache collection is used to obtain the cross-realm ticket and further a ticket to the target service.

So the borderline is what API is used: plain Kerberos calls or GSSAPI.

If you can achieve it with GSSAPI then you can do the same with plain Kerberos
API.

LS

Lukas, you need to be careful in what you are suggesting. Plain krb5 does not have autoselection logic in the ccache collections. You can enumerate ccaches in the collection from the application side and find a suitable ccache for a principal from the target service's realm. With GSSAPI it is done automatically and transparently. With plain krb5 it is not done by MIT krb5 for you (as an application).

None of the applications I know supports an automatic finding of a suitable ccache in the collection using plain krb5 API.

On (06/11/17 19:57), Alexander Bokovoy wrote:

Lukas, you need to be careful in what you are suggesting.

A) I didn't suggest anything
B) libgssapi_krb5.so uses just plain krb5 calls. So if you can achieve
something with GSSAPI than you can achieve the same with krb5.
I've never mention that it will be just with one function or that
both ways would be super simple

LS

Actually I looked further into rpc.gssd, and found that it uses GSSAPI, but in the wrong way. Rather than telling it what principal it wants, it gets the default principal and fails if it's the wrong one.

I agree that this would be easy to do in raw Kerberos, but I doubt that it would be a good idea to change rpc.gssd to use raw kerberos. Currently it's using gssproxy, which allows all the features of gssproxy, including things like constrained delegation.

I'll report this as a bug once the nfs-utils bugzilla allows new registrations. Currently it fails.

Actually I looked further into rpc.gssd, and found that it uses GSSAPI, but in the wrong way. Rather than telling it what principal it wants, it gets the default principal and fails if it's the wrong one.

it should work with GSSAPI https://pagure.io/SSSD/sssd/issue/3546#comment-477341. Implementation with krb5 would be much more complicated and step back.

@hedrick rpc.gssd uses GSSAPI the right way for waht it wants to do.
You want the ability to have NFS deal with sessions, but that is simply not implemented in the kernel nfs client, so it is not possible.

The rule is that the nfs client will use the default credentials for the user id that is trying to access the nfs mount point.

As an admin/user you need to know that and act accordingly.
In future it may be possible that NFS will grow a way to deal with sessions and even peek in to user env variables to figure out what the user wants, but that is not how the nfs client works now.

I've modified krb5 in new-ish versions to select principal based on hostname of target service - that is, for machines at foo.bar.fedoraproject.org, a principal for FEDORAPROJECT.ORG will be used if it exists, regardless of the default value. For applications using GSSAPI, this should remove the need for users to ever kswitch (unless they have multiple principals in the same realm).

GSSAPI doesn't present a way to walk the entries in a ccache collection - somewhat intentionally. The idea is to either take a default (with some additional heuristics, like the above paragraph), or to explicitly use a requested principal. ccaches almost don't exist in the GSSAPI abstraction, even (except in the extensions, but those are rarely needed).

@hedrick rpc.gssd uses GSSAPI the right way for waht it wants to do.
You want the ability to have NFS deal with sessions, but that is simply not implemented in the kernel nfs client, so it is not possible.

Well, yes, I'd like that. But I think one could improve it from what it's currently doing. the problem is that the default principal for the current user is being defined in a way that works out to the currently selected cc for the current collection. If I have cc's for both hedrick and hedrick.admin, I could end up with hedrick.admin, which won't work.

I don't think we need session support to do better. The NFS system knows only that a certain uid wants to access files. What we need is the best principal for that uid. But the only one that can actually work is the username associated with that uid, in the default domain. In any real NFS system, the server isn't going to do anything useful with hedrick.admin or any other alternative principal I may currently be using.

I agree that this won't work if I'm sudo'ed to root. If the authorization session in the kernel was associated with my session rather than my UID we could make that work. But the infrastructure doesn't seem to exist to do that. But at least if I'm running with my own uid, it should be mapped to my username, and then GSSAPI should be told to look for that principal.

What I'm currently doing is adding a pam module that at login copies the cc generated by the login into /var/lib/gssproxy/clients/krb5cc_%U, where it's picked up by gssproxy. That makes my NFS access independent of what I'm doing in my session.

That works, but seems like an unnecessary complication.

Looking at comments from @rharwood and @simo there's nothing that needs fixing anymore. I'm closing the ticket, please reopen if you disagree.

Metadata Update from @jhrozek:
- Issue close_status updated to: Invalid
- Issue status updated to: Closed (was: Open)

6 years ago

SSSD is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in SSSD's github repository.

This issue has been cloned to Github and is available here:
- https://github.com/SSSD/sssd/issues/4572

If you want to receive further updates on the issue, please navigate to the github issue
and click on subscribe button.

Thank you for understanding. We apologize for all inconvenience.

Login to comment on this ticket.

Metadata