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

feat: infer krb5 ccache from within the PAM module #914

Merged
merged 9 commits into from
Feb 21, 2024

Conversation

GabrielNagy
Copy link
Contributor

This is a follow-up to #903 where the functionality to get the default ticket path from libkrb5 was added.

The simplest and safest way to use the functionality above fom the PAM module is to delegate most of the responsibility to a CLI command written in Go, that can return the ticket path of any given user. Because the PAM module runs as root, we need to de-escalate to the given user (using setuid since libkrb5 treats setuid and seteuid separately, so the latter is not enough).

The CLI command is specialized for usage from within the PAM module to minimize friction. It reads the configuration file to see if the detect_cached_ticket setting is enabled, and avoids returning an error if the ticket path is not present on disk. Thus the PAM module can just execute the command, read its output and silently return if the subprocess exited with 0 and no output was printed.

We block authentication if the subprocess returns an error, or if any buffer-allocation or system calls needed to run and read the output are failing.

On top of this being a fully backwards-compatible change on the account of the opt-in setting, the impact of not having a ticket on disk is minimized since adsys will then treat the user as a non-domain user. There is the risk of the ticket cache on disk being outdated, which will end up failing the adsysctl update operation that happens on login, but ensuring the validity of the existing ticket path pointed to by libkrb5 is the responsibility of the process that generates/renews the ticket, not adsys.

Fixes UDENG-2191

@GabrielNagy GabrielNagy force-pushed the pam-module-infer-krb5cc branch from 72205d1 to 644496e Compare February 16, 2024 11:59
@codecov-commenter
Copy link

codecov-commenter commented Feb 16, 2024

Codecov Report

Attention: 6 lines in your changes are missing coverage. Please review.

Comparison is base (e35ef3a) 87.65% compared to head (2e43d72) 87.63%.
Report is 4 commits behind head on main.

Files Patch % Lines
cmd/adsysd/client/policy.go 84.61% 3 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #914      +/-   ##
==========================================
- Coverage   87.65%   87.63%   -0.02%     
==========================================
  Files          76       76              
  Lines        6713     6755      +42     
==========================================
+ Hits         5884     5920      +36     
- Misses        492      495       +3     
- Partials      337      340       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@GabrielNagy GabrielNagy force-pushed the pam-module-infer-krb5cc branch from 644496e to 88ba693 Compare February 16, 2024 12:07
@GabrielNagy
Copy link
Contributor Author

Attention: 31 lines in your changes are missing coverage. Please review.

This is actually covered as part of the e2e test but there's no easy way to make it reflect in the coverage report 😕.

@GabrielNagy GabrielNagy marked this pull request as ready for review February 16, 2024 12:13
@GabrielNagy GabrielNagy requested a review from a team as a code owner February 16, 2024 12:13
Copy link
Member

@didrocks didrocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C part is perfect. I have a few suggestions and also some others on testing that may not be possible but still worth it IMHO.

This is really great to see, we now have a fallback, while still keeping the existing behaviour without the settings turned on. Well done! :)

e2e/cmd/run_tests/05_test_pam_krb5cc/main.go Outdated Show resolved Hide resolved
internal/ad/krb5.go Show resolved Hide resolved
e2e/scripts/patches/jammy.patch Show resolved Hide resolved
cmd/adsysd/client/policy.go Show resolved Hide resolved
e2e/scripts/first-run.sh Outdated Show resolved Hide resolved
e2e/scripts/provision.sh Show resolved Hide resolved
pam/pam_adsys.c Show resolved Hide resolved
@GabrielNagy GabrielNagy force-pushed the pam-module-infer-krb5cc branch 2 times, most recently from 5200afc to ff397e8 Compare February 17, 2024 12:18
@GabrielNagy GabrielNagy requested a review from didrocks February 17, 2024 12:22
@GabrielNagy GabrielNagy force-pushed the pam-module-infer-krb5cc branch from ff397e8 to f19452f Compare February 17, 2024 12:25
Copy link
Member

@didrocks didrocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that I asked for integration tests, way easier than I envision too! Nice work :)

Just one small changes on the latest commits and then, we can merge!

internal/ad/krb5_test.go Outdated Show resolved Hide resolved
@GabrielNagy GabrielNagy requested a review from didrocks February 21, 2024 10:04
Copy link
Member

@didrocks didrocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect as usual! Be warned, I’m getting used to it :)

This is because cloud-init creates overrides here which happen during
the first run.
In our PAM module we don't want to block authentication if the path
reported by libkrb5 does not exist.

Rather than checking for the primitive fs.ErrNotExist in the caller,
specialize the error in our own API.
Add a debug command under adsysctl policy responsible for returning the
default ccache path for the given user.

This command is intended to be used by the PAM module, thus we are
specializing its edge cases such as:
- configuration option not set: we do not error so PAM can proceed with
  the previous functionality (return PAM_IGNORE)
- ccache reported by libkrb5 not found on disk: we do not error since
  user can be a non-domain user

Other scenarios that can raise errors will be treated as such, and auth
will be denied.
Leverage the previously created CLI command from within the PAM module
to set the KRB5CCNAME variable if found.

Because all checks are handled by the CLI command, we only need to read
its output (if present) and propagate any non-zero exit codes.
As this is a scenario difficult to test at package or integration level,
create an e2e test for it.

In broad terms this does the following:
- perform pubkey authentication to bypass pam_sss, ensuring KRB5CCNAME
  is not set
- manually initialize a ccache in the default path using kinit
- with the detect_cached_setting enabled, ensure KRB5CCNAME is set on
  subsequent logins
- ensure login still works after removing the ccache
This has changed since we migrated our documentation to readthedocs.
We can cover the most common code branches in integration tests, with
the exception of when the command:
- fails to get current user
- fails to call Atoi on the UID
- fails to call Setuid (this is achievable if tests do not run as root
  but I don't think we should complicate the setup too much)
@GabrielNagy GabrielNagy force-pushed the pam-module-infer-krb5cc branch from 29ccfe4 to 2e43d72 Compare February 21, 2024 10:16
@GabrielNagy GabrielNagy merged commit b5de9aa into main Feb 21, 2024
4 checks passed
@GabrielNagy GabrielNagy deleted the pam-module-infer-krb5cc branch February 21, 2024 10:34
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

Successfully merging this pull request may close these issues.

3 participants