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

Rework krb5cc handling logic #699

Merged
merged 5 commits into from
May 24, 2023
Merged

Rework krb5cc handling logic #699

merged 5 commits into from
May 24, 2023

Conversation

GabrielNagy
Copy link
Collaborator

Following the Heimdal issues surfaced after the samba 4.16.0 release we have to rethink the krb5cc handling logic with the following in mind:

  • we can no longer use symlinks as Kerberos tickets
  • the ticket has to be owned by the running user (in our case root)

This is not related to a change in samba itself, but to the Kerberos implementation vendored in samba (Heimdal Kerberos). Between samba 4.15.0 and 4.16.0 there has been a massive update in the vendored code, pulling in around 10 years worth of changes. Among these changes we were able to find information confirming the 2 issues above, and we concluded they are not considered to be bugs in the upstream implementation (and related issue).

Another important thing to note is that the issues above do not manifest if samba is compiled and linked against the MIT Kerberos library. However, MIT Kerberos appears to still be considered experimental (as of today), and neither Ubuntu or other distros are compiling samba with MIT Kerberos.

As such, we have to work around these "issues" within adsys. Instead of tracking the ticket's lifetime using a symlink, we rely on the following approach:

  • still track original ticket with a symlink
  • copy the ticket as a root-owned ticket
  • track refresh with timestamps on the symlink itself.

Symlinks will remain stored under KRB5CACHEDIR, whereas the actual copies will reside under KRB5CACHEDIR/tickets.

Closes UDENG-289

@GabrielNagy GabrielNagy force-pushed the krb5cc-symlink-handling branch 3 times, most recently from 7da1eeb to 5cb1f6c Compare May 16, 2023 12:21
@GabrielNagy GabrielNagy marked this pull request as ready for review May 16, 2023 12:47
@GabrielNagy GabrielNagy requested a review from a team as a code owner May 16, 2023 12:47
Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Looks very nice, well done! I have some suggestions that I feel like should be attended, but otherwise: amazing work!

internal/ad/ad.go Outdated Show resolved Hide resolved
internal/ad/ad.go Outdated Show resolved Hide resolved
internal/ad/ad.go Outdated Show resolved Hide resolved
internal/ad/ad.go Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

Codecov Report

Merging #699 (326decb) into main (18c04e1) will decrease coverage by 0.16%.
The diff coverage is 62.50%.

@@            Coverage Diff             @@
##             main     #699      +/-   ##
==========================================
- Coverage   84.73%   84.57%   -0.16%     
==========================================
  Files          75       75              
  Lines        8177     8229      +52     
==========================================
+ Hits         6929     6960      +31     
- Misses        936      950      +14     
- Partials      312      319       +7     
Impacted Files Coverage Δ
internal/ad/ad.go 86.82% <62.50%> (-3.80%) ⬇️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Looks great! Well done for spotting and fixing it!

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.

Nice work! It’s always almost a deception when you see how much the investigation took compared to the "fix" (or rather workaround here). Well done!

I have one small request to make the whole logic more understandable in the future (I think, as an admin, I open the cache and see directly what is in use).

However, I wonder about the coverage. Codecov is not really helpful as it doesn’t show up the file diff change. Do you think that some tests in ad_test.go could be added to trigger some uncovered tests and not only relying on the integration tests to cover it?

(I’m thinking in particular about a test with ticket, ad, get it, then updating the ticket, ad away, -> copy was refreshed)

internal/ad/ad.go Outdated Show resolved Hide resolved
internal/ad/ad.go Show resolved Hide resolved
@GabrielNagy GabrielNagy force-pushed the krb5cc-symlink-handling branch 2 times, most recently from 54583e2 to fd98e17 Compare May 23, 2023 15:46
@GabrielNagy
Copy link
Collaborator Author

@didrocks sorry for the aggresive force-pushing 😊 the only changes are in the first and last commit (which is newly added).

@didrocks
Copy link
Member

@didrocks sorry for the aggresive force-pushing blush the only changes are in the first and last commit (which is newly added).

I was on the starting block to complain, but now that you apologized… :p

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.

I’m not sure I’m fully following the logic here (in addition to the comment I mentioned).

I don’t see the symlink to be reused anywhere after being created. The idea is that any "all policy updates" (so, without explicit env variable to get the ticket), should get the real ticket location from the symlink and assess if a copy refresh is in order? I may be missing it completely, but I even reopened the file to see if there is any hidden logic I’m missing.

If I am correct, it means that we are missing a test to setup something for a given user, then, modifying ticket and ask for a refresh without pointing to that user in particular, and check that the copy has been refreshed.

internal/ad/ad_test.go Show resolved Hide resolved
internal/ad/ad.go Show resolved Hide resolved
@GabrielNagy
Copy link
Collaborator Author

I don’t see the symlink to be reused anywhere after being created. The idea is that any "all policy updates" (so, without explicit env variable to get the ticket), should get the real ticket location from the symlink and assess if a copy refresh is in order? I may be missing it completely, but I even reopened the file to see if there is any hidden logic I’m missing.

That's a very good observation which I totally missed, thanks for that. I've now updated the implementation to attempt the copy even if an explicit krb5ccname is not passed and validated the behavior with a package test.

@didrocks
Copy link
Member

That's a very good observation which I totally missed, thanks for that. I've now updated the implementation to attempt the copy even if an explicit krb5ccname is not passed and validated the behavior with a package test.

No worry, I think that shows we should have an automated test for this behavior in the ad package, wdyt?

@GabrielNagy
Copy link
Collaborator Author

I agree, that's why I added one :P. Let me know if this is what you had in mind.

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.

Excellent, one last comment on the test name, then feel free to merge :)

Woow, good to see this merged, especially with, in the end, some improvements with the symlink checked :) Well done!

cmd/adsysd/integration_tests/adsysctl_policy_test.go Outdated Show resolved Hide resolved
Following the Heimdal issues surfaced after the samba 4.16.0 release we
have to rethink the krb5cc handling logic with the following in mind:
- we can no longer use symlinks as Kerberos tickets
- the ticket has to be owned by the running user (in our case root)

This is not related to a change in samba itself, but to the Kerberos
implementation vendored in samba (Heimdal Kerberos). Between samba
4.15.0 and 4.16.0 there has been a massive update in the vendored code,
pulling in around 10 years worth of changes[1]. Among these changes we
were able to find information confirming the 2 issues above, and we
concluded they are not considered to be bugs in the upstream
implementation[2] (and related issue [3]).

Another important thing to note is that the issues above do not manifest
if samba is compiled and linked against the MIT Kerberos library.
However, MIT Kerberos appears to still be considered experimental (as of
today), and neither Ubuntu or other distros are compiling samba with MIT
Kerberos.

As such, we have to work around these "issues" within adsys. Instead of
tracking the ticket's lifetime using a symlink, we rely on the following
approach:

* still track original ticket with a symlink
* copy the ticket as a root-owned ticket
* track refresh with timestamps on the symlink itself.

Ticket copies will be stored under KRB5CACHEDIR, whereas symlinks will
reside under KRB5CACHEDIR/tracking.

Closes UDENG-289

[1] samba-team/samba@40b65c8
[2] heimdal/heimdal@2a56548
[3] heimdal/heimdal#306
I believe that with the previous commit we've uncovered a small bug in
the krb5cc symlink logic. More specifically, in these tests we were
creating symlinks to a nonexistent path (ccache_OFFLINE) due to the sssd
configuration.

Because the presence of the source file wasn't enforced in
`ensureKrb5CCName` (filepath.Abs doesn't ensure the path actually
exists), this went unnoticed until now. This was only a problem in the
offline tests which didn't go to our samdb mock, which would have caught
the dangling symlink issue.

Now that we do the additonal copy action the failure becomes visible.
The fix is simple, we just have to create the cached sssd ticket using
the appropriate domain name.
Employ a write to temp & rename workflow to ensure we're not left in a
broken state if the write fails midway.
When checking for active users, symlinks are now followed, and users
with dangling symlinks will now be silently ignored.
When upgrading from a previous version of the package it's highly likely
to have the previous krb5cc structure in /var/run/krb5cc, with symlinks
at the top level. We need to make sure we overwrite previous symlinks
with the hard copy in this case.
@GabrielNagy GabrielNagy merged commit ba00458 into main May 24, 2023
5 checks passed
@GabrielNagy GabrielNagy deleted the krb5cc-symlink-handling branch May 24, 2023 12:29
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.

None yet

4 participants