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

Homed update policy: user changing own settings #31153

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

AdrianVovk
Copy link
Contributor

@AdrianVovk AdrianVovk commented Jan 31, 2024

Rework of #30109 to deal with changes in #30840 and discussed changes to behavior

Depends on and includes #30840

@AdrianVovk
Copy link
Contributor Author

AdrianVovk commented Jan 31, 2024

I mapped out all the ways user_record_authenticate gets called:

  • Activate -> home_activate -> (check host record)
  • Activate -> home_activate -> home_activate_luks -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Activate -> home_activate -> home_activate_luks -> home_auto_grow_luks -> home_resize_luks -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Activate -> home_activate -> ... -> home_refresh -> home_load_embedded_identity -> (check ~/.identity)
  • Update -> home_update -> (check host record)
  • Update -> home_update -> home_setup -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Update -> home_update -> home_load_embedded_identity
  • ChangePassword -> home_passwd -> home_load_embedded_identity
  • ChangePassword -> home_passwd -> home_setup -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Resize -> home_resize -> (check host record)
  • Resize -> home_resize -> home_resize_luks -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Fixate -> home_insepct -> (check host record)
  • Fixate -> home_inspect -> home_setup -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Fixate -> home_inspect -> home_load_embedded_identity
  • Authenticate -> home_inspect -> (check host record)
  • Authenticate -> home_inspect -> home_setup -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Authenticate -> home_inspect -> home_load_embedded_identity
  • Unlock -> home_unlock -> (check host record)
  • Deactivate -> home_deactivate -> home_auto_shrink_luks -> home_resize_luks -> home_setup_luks -> luks_validate_home_record -> (check LUKS embedded record)
  • Acquire can also trigger Activate, Fixate, Authenticate or Unlock depending on what state the home is in

@AdrianVovk
Copy link
Contributor Author

AdrianVovk commented Jan 31, 2024

Part of what we discussed with @poettering is changing user_record_authenticate to always look into the kernel keyring and just use that key if it's available. Ultimately this would mean that user_record_authenticate will pass whenever the user is active and unlocked. So given all the code paths above, I want to break down why this is OK. Here we try to keep in mind the motivation for doing all these authentication checks: We never want to be in a situation where the user can unlock a home directory with an out-of-date password, even as we travel between hosts.

  • All code paths in response to Activate: the user must be inactive, and thus we don't have their key in the keyring and thus user_record_authenticate actually performs authentication
  • Update
    • If the key is available in the keyring, then the user must be active. But Activating the user already verified their password against the embedded records. So this should be safe. In this case, we skip all 3 checks.
    • If the key isn't available in the keyring, then the user must be inactive or locked:
      • If the user is locked, we don't permit updates at all and error before even starting homework. Thus the user must be inactive.
      • If we're performing an offline update, we skip the user_record_authenticate and don't even look at the embedded records. So we skip all 3 checks. But then the user will inevitably need to be Activated, which will perform all 3 checks as mentioned above.
      • If we're performing an online update, then we call user_record_authenticate which will actually perform the authentication (since the key isn't in the keyring!). So we do all 3 checks in this case.
  • ChangePassword
    • I think for this one we shouldn't ever load the key from the keyring just to be paranoid
    • Thus user_record_authenticate always performs the full authentication check
  • Resize: Very similar reasoning to Update, except we don't have an offline mode. Thus either the user is active and already verified via Activate, or they're inactive and we perform all three checks.
  • Fixate: An unfixated user can never be active, and thus we can never have their key in the keyring. So, we perform all 3 checks.
  • Authenticate: This is like ChangePassword. We shouldn't ever load the key from the keyring. The whole point of this method is to enforce authentication
  • Unlock: the user's key won't be in keyring, thus user_record_authenticate actually performs authentication
  • Deactivate: The keyring things are only used to auto-shrink the home area, so the logic from Resize applies. Loading the keys from the keyring to facilitate resize is also just status-quo...
  • Acquire: this just triggers the other methods depending on the state of the home, so anything we say about those should apply to Acquire

So all this said, what is the practical conclusion?

  • home_activate shouldn't bother trying to load from the keyring, because it will never find anything
  • home_update should load from the keyring every time
  • home_passwd shouldn't load from the keyring, to force password re-entry
  • home_resize should load from the keyring every time
  • home_inspect shouldn't load from the keyring. In Fixate's case, it'll never find anything so it shouldn't bother, an in Authenticate's case we don't want it to load from the keyring
  • home_unlock shouldn't bother
  • home_deactivate should always load from the keyring so that the eventual resize can work

@AdrianVovk AdrianVovk force-pushed the homed-update-policy-v2 branch 9 times, most recently from e3ae848 to a65fd3d Compare February 2, 2024 20:13
@AdrianVovk AdrianVovk marked this pull request as ready for review February 2, 2024 22:18
@github-actions github-actions bot added the please-review PR is ready for (re-)review by a maintainer label Feb 2, 2024
src/basic/hashmap.c Outdated Show resolved Hide resolved
@poettering
Copy link
Member

btw, i'd split PRs up a lot more aggressively. If they can stand on their own reasonably I think single-commit PRs are great, too, even. Everything you already got in will make the remainder smaller, and the rebase mess will be reduced.


/* Reuse the array. */
FOREACH_ARRAY(e, entries, n)
*e = (void*) (*e)->key;
Copy link
Member

Choose a reason for hiding this comment

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

I think I already reviewed this in another PR: the reuse of the array with a specific but different type is not OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This MR is stacked on top of #30840

Is there something specific I'm supposed to do so that you don't accidentally review the same things twice over?

@github-actions github-actions bot added please-review PR is ready for (re-)review by a maintainer and removed needs-rebase labels Mar 11, 2024
@bluca bluca removed the rc-blocker 🚧 PRs and Issues tagged this way are blocking the upcoming rc release! label Mar 19, 2024
@bluca bluca modified the milestones: v256, v257 Mar 19, 2024
@poettering
Copy link
Member

conceptually still looks good to me, added some more review points, but the most impotant thing is that the list of editable fields should be itsefl a field on the recrod, as discussed.

@poettering poettering added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed please-review PR is ready for (re-)review by a maintainer labels Apr 24, 2024
@github-actions github-actions bot added please-review PR is ready for (re-)review by a maintainer and removed reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels Apr 24, 2024
Allows the system administrator to configure what fields the user is
allowed to edit about themself, along with hard-coded defaults.
This allows an unprivileged user that is active at the console to change
the fields that are in the selfModifiable allowlists (introduced in a
previous commit) without authenticating as a system administrator.

Administrators can disable this behavior per-user by setting the
relevant selfModifiable allowlists, or system-wide by changing the
policy of the org.freedesktop.home1.update-home-by-owner Polkit action.
Copy link

Important

An -rc1 tag has been created and a release is being prepared, so please note that PRs introducing new features and APIs will be held back until the new version has been released.

is allowed to edit.

`selfModifiablePrivileged` → Similar to `selfMoidifiableFields`, but it lists fields in
the `privileged` section that the user is allowed to edit.
Copy link
Member

Choose a reason for hiding this comment

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

why keep this separate from "regular" and "perMachine"? i mean, we'd be really stupid if we'd introduce fields in one section that would exist (or if existance then with different meaning) in the other. Hence I think it should be fine to throw them in the same bin here and keep one list of json fields.

Copy link
Member

Choose a reason for hiding this comment

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

Moidfiable → Modifiable (here and above)

* user to give themselves some unfair advantage over other users on
* a given system.
*/
static const char *safe_fields[] = {
Copy link
Member

Choose a reason for hiding this comment

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

static const char *const safe_fields[] = {

}

const char **user_record_self_modifiable_blobs(UserRecord *h) {
static const char *safe_blobs[] = {
Copy link
Member

Choose a reason for hiding this comment

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

as above

@@ -431,6 +435,10 @@ uint64_t user_record_capability_bounding_set(UserRecord *h);
uint64_t user_record_capability_ambient_set(UserRecord *h);
int user_record_languages(UserRecord *h, char ***ret);

const char **user_record_self_modifiable_fields(UserRecord *h);
const char **user_record_self_modifiable_blobs(UserRecord *h);
const char **user_record_self_modifiable_privileged(UserRecord *h);
Copy link
Member

Choose a reason for hiding this comment

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

please output them in the calls in user-record-show.c

@@ -423,7 +423,7 @@ int bus_home_update_record(
Hashmap *blobs,
uint64_t flags,
sd_bus_error *error) {
int r;
int r, safe;
Copy link
Member

Choose a reason for hiding this comment

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

maybe rename "safe" → "relax_access"?

log_warning_errno(safe, "Failed to determine if changes to user record are safe, assuming not: %m");
safe = false;
} else if (safe) {
safe = bus_home_client_is_trusted(h, message);
Copy link
Member

Choose a reason for hiding this comment

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

this of course is slightly skewed here. Because if the client is root this will cause us to use the org.freedesktop.home1.update-home-by-owner PK action, which is of course strictly speaking weird because root is not really the "owner" of such accounts...

hence, either fix this (i.e. add a "bool strict" param to bus_home_client_is_trusted() or so? or at least add a comment explaining why the sloppiness here doesn't matter too much

@poettering
Copy link
Member

looks good, just some minor things

@poettering poettering added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed please-review PR is ready for (re-)review by a maintainer labels Apr 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

3 participants