Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pam_setcred fails when KRB5CCNAME=KEYRING:user:name #14

Closed
ppkarwasz opened this issue Nov 3, 2019 · 6 comments
Closed

pam_setcred fails when KRB5CCNAME=KEYRING:user:name #14

ppkarwasz opened this issue Nov 3, 2019 · 6 comments

Comments

@ppkarwasz
Copy link

Using credential caches of type KEYRING (MIT Kerberos) has several issues:

  • KEYRING:persistent:uidnumber should work as expected. I didn't test, because standard Debian kernels do not have persistent keyrings.
  • KEYRING:session:name does not always copy credentials. This issue is IMHO entirely due to some applications calling _pam_open_session and pam_setcred in reversed order and the limitations of pam_keyinit.so (cf. pam_keyinit lacks pam_sm_setcred linux-pam/linux-pam#149)
  • KEYRING:user:name may attach the credentials to the wrong keyring if the PAM application is not currently running with the user's credentials.

The last issue concerns pam_krb5.so. I see several solutions, but I don't know if they are acceptable:

  1. A setreuid()/setgeuid() call before calling krb5_cc_resolve. The module pam_keyinit.so does it without wondering about multi-threading, but the comments in pamk5_setcred tell me this solution would be discarded.
  2. Do the same as above, but using syscalls instead of libc, since they do not synchronize between threads.
  3. Wait for the application to open the user session before copying the credentials.

If you point me in the right direction I might provide a patch.

@rra
Copy link
Owner

rra commented Nov 3, 2019

One piece of information missing from this bug report is what PAM application you're having this problem with. Is this login, sshd, sudo, or something else? I'd like to understand the sequence of PAM calls and changes to UID.

If I understand the issue properly, pam_krb5.so picks up the wrong keyring because at that point in your PAM initialization stack, the code is still running as some user other than the target user, and thus picks up the wrong user keyring. Is that right?

Calling pam_setcred before pam_open_session is correct and what applications are supposed to do. Is the problem with session keyrings that the session keyring is not set up at pam_setcred time, but is then set up when pam_open_session is called?

If this is the case, then both of your problems seem to be that pam_setcred is too early to set up the ticket cache and you want to defer the setup to pam_open_session, even if the application calls pam_setcred. If so, it would be easy to add a new module option that says to ignore pam_setcred when called without flags, so that the initialization doesn't happen until pam_open_session.

@ppkarwasz
Copy link
Author

I am having problems with gdm3. Other applications I tested (e.g. login) reverse the order in which they call those functions and they end up OK. I have some logs that pam_krb5.so and pam_keyinit.so provide, though they only show that pam_keyinit.so starts with uid=0 and gid=1000.

Looking at the code of gdm3 there are only two setuids: one guarded by THE_MAN_PAGE_ISNT_LYING (undefined in the default compilation?) before pam_setcred and one after pam_open_session. Both cannot help pam_krb5.so.

Disclaimer: using KEYRING:user:name as my credential cache is rather theoretical. I think KEYRING:session:name would be a better choice on those machines, where I need more than a principal, but I like to explore all possibilities.

@rra
Copy link
Owner

rra commented Nov 3, 2019

It sounds like there may be no way to make the user keyring work if it doesn't setuid until after it's finished with PAM, so I'll focus on what's causing problems with the session keyring. You say "reverse the order" and you said that sometimes the cache wasn't "copied" -- I assume what you mean by that is that when called in one order, you end up with an initialized keyring ticket cache with valid credentials, and with the other order, you don't. Do you end up with no keyring ticket cache at all? And could you be more specific about what order works and what order does not?

@rra
Copy link
Owner

rra commented Nov 3, 2019

I think what may be happening is that if pam_setcred is called before a session keyring has been created and before the UID has been changed, you're getting the behavior described in the user-session-keyring man page: a session keyring is created for the current UID (which isn't the user), and then pam_krb5.so is storing the credentials in that keyring. That keyring will then become invisible after the UID change.

If that's the case, the fix is to ensure a session keyring is explicitly created before running pam_setcred in pam_krb5.so, since it will then be inherited across change of UID.

@ppkarwasz
Copy link
Author

Yes, with a session keyring that's exactly what is happening (I posted a fix to linux-pam/linux-pam#149):

  • during pam_setcred the session keyring is not ready yet, so pam_krb5.so copies the credentials to root's user-session-keyring or gdm's session keyring,

  • during pam_open_session pam_keyinit.so creates a new session keyring and probably unlinks the previous one,

  • I end up with:

    piotr@bialykiel:~$ keyctl show -x @s
    Keyring
    0x205f652a --alswrv 1000 1000 keyring: _ses
    0x1ac9fc98 --alswrv 1000 65534 _ keyring: _uid.1000
    0x1ae0e992 --alswrv 1000 1000 _ keyring: _krb_kerberos
    0x0b77b686 --alswrv 1000 1000 _ user: krb_ccache:primary

with no credentials.

So summarising:

  • the best way to fix the user keyring issue is to post a bug report on the affected PAM applications, since they should decide when to setuid,
  • for the session ring it is pam_keyinit.so problem.

@rra
Copy link
Owner

rra commented Nov 3, 2019

I think that's right. The root of the problem for the session keyring is that pam_keyinit.so doesn't implement pam_setcred (which admittedly is kind of irritating to do for a non-authentication module).

One can make a counter-argument that pam_krb5.so should only create a persistent ticket cache during pam_open_session, not during pam_setcred. Unfortunately, while that should work in a world in which all PAM applications followed the documentation, I ran into applications that never open a session but still expect to have Kerberos tickets, hence the current behavior of doing this in pam_setcred. It's probably too late to change this behavior now, although I'd be open to making it an option.

All of this stuff is sadly rather underspecified and there are a lot of broken applications out there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants