#3029 Create krb5 credential cache in pam "session" (instead of "auth")
Closed: Invalid Opened by thomasweissschuhamadeus.

Environment

SSSD Version::
1.13.4-1ubuntu1 (Ubuntu 16.04)
Auth Backend::
krb5
Kerberos Cache::
FILE:/run/user/%{uid}/krb5cc

= Observation =

When logging the user does not receive a valid kerberos credential cache with
their principal credentials. There is no credential cache.

The problem is, that after the auth phase of pam_sss.so is run, which saves the
user credentials to the cache, the session phase of pam_systemd.so runs.
pam_system.so mount a tmpfs over /run/user/$UID if this is the first running
login session of this user (it gets removed after the last logout).
So the created cache is shadowed by this mount.

Possible solution

Create a temporary cache to save the credentials in the auth phase and move them
to the final location during the session phase.

Background

We use this location because we want predictable cache names (the samba of cups
backend has to find the cache) and we don't want to be vulnerable to
precreation/symlink attacks.
This is a perfect fit for /run/user/$UID.

Alternatives

  • Run pam_systemd.so session before pam_sss.so auth:

pam_systemd.so does more than creating this directory, resulting in
unexpected execution of programs

  • Create a custom pam module:

This would have to reimplement the logic of pam_systemd.so

  • Split pam_systemd.so into a pre auth step:

Allocating persistent resources before the authentication succeeded feels
like a suboptimal solution.
There may also be other pam modules around that are necessary for the
availability of the credential cache (pam_mkhome.so ...)


This is a valid concern. Several years ago, we tried to move to a DIR cache but reverted precisely because of this reason. In recent RHEL releases, we store they ccache in kernel keyring and in longer-term (maybe in a year?) we would like to make SSSD a KCM provider. I wonder if it was OK for Ubuntu to do the same, use the keyring ccache for now and migrate to KCM when it's ready?

thomasweissschuhamadeus commented

FYI: I am not affiliated with Ubuntu, just an admin deploying SSSD on Ubuntu.

I tried this but then printing stopped working. We use samba for printing which in turn uses kerberos from Heimdal which seems to not support kernel keyrings. Using the FILE keyring as described in the ticket works fine.

Mixing components that use different Kerberos implementations can lead to different inconsistencies.

I'm not sure that title is correct.
We cannot create ccache in pam "session" phase because we do not have a pasword there. Password is available only in "auth" phase.

One possibility of "creating session" in advance is with loginctl.
You might try to enable-linger for such user.
I didn't try it. @see man loginctl -> enable-linger

cc: => lslebodn

thomasweissschuhamadeus commented

@lslebodn

I was thinking about something like:

  • auth phase

    • sssd
      • read password
      • instruct kerberos library to use /var/cache/sssd/krb5cc_%{uid} (only an example), only accessible by root/sssd
      • authenticate against kerberos infrastructure
  • session phase

    • systemd
      • mount /run/user/%{uid}
    • sssd
      • copy/merge /var/cache/sssd/krb5cc_%{uid} with /run/user/%{uid}/krb5cc

I can't really precreate sessions because I don't know in advance which users
will login to the machine.

I just noticed that another possibility would be to have a systemwide directory
which is owned by sssd which holds the credential caches for all users. It
would work like the files in /tmp without the need for filename
randomization.
But if for some reason sssd did not create a cache the users themselves won't be
able to do so...

Replying to [comment:5 thomasweissschuhamadeus]:

@lslebodn

I was thinking about something like:

  • auth phase
  • sssd

    • read password
    • instruct kerberos library to use /var/cache/sssd/krb5cc_%{uid} (only an example), only accessible by root/sssd
    • authenticate against kerberos infrastructure
  • session phase

  • systemd
    • mount /run/user/%{uid}
  • sssd
    • copy/merge /var/cache/sssd/krb5cc_%{uid} with /run/user/%{uid}/krb5cc

I do not like an idea with moving ccache file in session phase. It assume that ccache template is not randomized and that session phase will be every time executed after auth phase.

It could happen that some pam services would not call session phase after auth and there will be two tickets for the same users. One in /var/something and another in /run/user. Then sssd would not know know which ticket should be renewed.

In theory, sssd might decide based on cached value in sssd cache. But it would be just a complication.

But if you have an idea we will be glad to review patches.

I can't really precreate sessions because I don't know in advance which users
will login to the machine.

I just noticed that another possibility would be to have a systemwide directory
which is owned by sssd which holds the credential caches for all users. It
would work like the files in /tmp without the need for filename
randomization.
But if for some reason sssd did not create a cache the users themselves won't be
able to do so...
I do not think it's good idea but it might be a reasonable workaround for you.

But there are more workaorunds.

  • use enable-linger (complicated for administrator)
  • login twice; sssd will be able to create ccache with the 2nd login because systemd already created session + directory ( complicated for user )
  • use samba with MIT so you can use keyring ccache. But IIRC patches are only in samba master and not in 4.4 => you will need to compile samba yourself. There are already some packages for fedora[1]. I am not sure about ubuntu. You might ask on samba-technical mailing list.

[1] https://copr.fedorainfracloud.org/coprs/asn/samba_ad_dc/

thomasweissschuhamadeus commented

Replying to [comment:6 lslebodn]:

I do not like an idea with moving ccache file in session phase. It assume that ccache template is not randomized and that session phase will be every time executed after auth phase.

It the final destination could still be randomized? For the temporary location
randomization should not matter, as no one except sssd itself can read (and of
course write) it.

It could happen that some pam services would not call session phase after auth and there will be two tickets for the same users. One in /var/something and another in /run/user. Then sssd would not know know which ticket should be renewed.

This is of course a valid concern. I personally would be fine with requiring
users to let sssd run both phases, but I understand if this is not practicable
in general.

Another way would be a configuration option for the pam plugin which enables
the delayed creation of the cache.

Or sssd does it both ways, writing to a temporary cache, moving this to the
final location and in the session phase doing it again (just an idea).

In theory, sssd might decide based on cached value in sssd cache. But it would be just a complication.

I totally admit this is quite messy and probably not worth it.

But if you have an idea we will be glad to review patches.

I can't really precreate sessions because I don't know in advance which users
will login to the machine.

I just noticed that another possibility would be to have a systemwide directory
which is owned by sssd which holds the credential caches for all users. It
would work like the files in /tmp without the need for filename
randomization.
But if for some reason sssd did not create a cache the users themselves won't be
able to do so...
I do not think it's good idea but it might be a reasonable workaround for you.

But there are more workaorunds.
* use enable-linger (complicated for administrator)

I don't really understand this point, as I don't know which user in particular
is going to login.

  • login twice; sssd will be able to create ccache with the 2nd login because systemd already created session + directory ( complicated for user )

This is our current "solution".

  • use samba with MIT so you can use keyring ccache. But IIRC patches are only in samba master and not in 4.4 => you will need to compile samba yourself. There are already some packages for fedora[1]. I am not sure about ubuntu. You might ask on samba-technical mailing list.

Hm, this sounds more like a last resort.

[1] https://copr.fedorainfracloud.org/coprs/asn/samba_ad_dc/

I'm sorry, but I don't think changing sssd is a good systematic way forward. With the current code, DIR cache can be used as well (although it's not well tested, there is code in SSSD that precreates the DIR cache if it doesn't exist). MIT-Kerberos platforms can already use the KEYRING cache same as RHEL and Fedora do. And for the future, we want to implement the KCM provider in SSSD.

All in all, I don't think adding more kludges for FILE ccache is the way forward for the SSSD upstream.

resolution: => wontfix
status: new => closed

thomasweissschuhamadeus commented

Replying to [comment:8 jhrozek]:

I'm sorry, but I don't think changing sssd is a good systematic way forward. With the current code, DIR cache can be used as well (although it's not well tested, there is code in SSSD that precreates the DIR cache if it doesn't exist).

The DIR cache would not resolve the problem with the lost ticket of the auth phase wouln't it?
Creating an empty ticket cache would not be the problem as that would be easily implementable with a simple custom pam module.

Replying to [comment:9 thomasweissschuhamadeus]:

Replying to [comment:8 jhrozek]:

I'm sorry, but I don't think changing sssd is a good systematic way forward. With the current code, DIR cache can be used as well (although it's not well tested, there is code in SSSD that precreates the DIR cache if it doesn't exist).

The DIR cache would not resolve the problem with the lost ticket of the auth phase wouln't it?
Creating an empty ticket cache would not be the problem as that would be easily implementable with a simple custom pam module.
Actually, problem is somewhere else.
As Jakub already mentioned sssd can create directories for ccache. I tried to find out why sssd did not create if for template /run/user/%{uid}/krb5cc. But sssd did create the directory in auth phase and ticket there.
However, it looks like systemd-logind purge this directory in session phase and created new one.

You can verify it with different temlpate which systemd-logind will not remove.
e.g. default_ccache_name = FILE:/run/user/%{username}/krb5cc

Disadvantage is that ccache will not be removed after closing session.

thomasweissschuhamadeus commented

Replying to [comment:10 lslebodn]:

Replying to [comment:9 thomasweissschuhamadeus]:

Replying to [comment:8 jhrozek]:

I'm sorry, but I don't think changing sssd is a good systematic way forward. With the current code, DIR cache can be used as well (although it's not well tested, there is code in SSSD that precreates the DIR cache if it doesn't exist).

The DIR cache would not resolve the problem with the lost ticket of the auth phase wouln't it?
Creating an empty ticket cache would not be the problem as that would be easily implementable with a simple custom pam module.
Actually, problem is somewhere else.
As Jakub already mentioned sssd can create directories for ccache. I tried to find out why sssd did not create if for template /run/user/%{uid}/krb5cc. But sssd did create the directory in auth phase and ticket there.
However, it looks like systemd-logind purge this directory in session phase and created new one.

The directory is not purged but shadowed by a tmpfs mount of systemd (this is mentioned in my original bugreport).
This tmpfs is an expected feature.
You can manually unmount the tmpfs and the credential cache will be visible again.

You can verify it with different temlpate which systemd-logind will not remove.
e.g. default_ccache_name = FILE:/run/user/%{username}/krb5cc

Disadvantage is that ccache will not be removed after closing session.

My explicit goal was to use the directory managed by systemd.

Replying to [comment:11 thomasweissschuhamadeus]:
problem as that would be easily implementable with a simple custom pam module.

Actually, problem is somewhere else.
As Jakub already mentioned sssd can create directories for ccache. I tried to find out why sssd did not create if for template /run/user/%{uid}/krb5cc. But sssd did create the directory in auth phase and ticket there.
However, it looks like systemd-logind purge this directory in session phase and created new one.

The directory is not purged but shadowed by a tmpfs mount of systemd (this is mentioned in my original bugreport).
This tmpfs is an expected feature.
You can manually unmount the tmpfs and the credential cache will be visible again.

I'm sorry I somehow missed that in this long ticket.

Then you should file a RFE for systemd to copy
files from the user run directory into tmpfs.
logind is program which hides and then removes ccache
after closing session.
So it should be handled there and not in sssd

Replying to [comment:12 lslebodn]:

Replying to [comment:11 thomasweissschuhamadeus]:
problem as that would be easily implementable with a simple custom pam module.

Actually, problem is somewhere else.
As Jakub already mentioned sssd can create directories for ccache. I tried to find out why sssd did not create if for template /run/user/%{uid}/krb5cc. But sssd did create the directory in auth phase and ticket there.
However, it looks like systemd-logind purge this directory in session phase and created new one.

The directory is not purged but shadowed by a tmpfs mount of systemd (this is mentioned in my original bugreport).
This tmpfs is an expected feature.
You can manually unmount the tmpfs and the credential cache will be visible again.

I'm sorry I somehow missed that in this long ticket.

Then you should file a RFE for systemd to copy
files from the user run directory into tmpfs.
logind is program which hides and then removes ccache
after closing session.
So it should be handled there and not in sssd

BTW the same problem would be with pam_krb5. That's another reason to not special case it in sssd.

Metadata Update from @thomasweissschuhamadeus:
- Issue set to the milestone: NEEDS_TRIAGE

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/4067

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.

Metadata