[Bug 1215355] AUDIT-0: himmelblau: review of PAM module pam_himmelblau.so
https://bugzilla.suse.com/show_bug.cgi?id=1215355 https://bugzilla.suse.com/show_bug.cgi?id=1215355#c13 William Brown <william.brown@suse.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Flags|needinfo?(william.brown@sus | |e.com) | --- Comment #13 from William Brown <william.brown@suse.com> --- Sorry didn't realise I was the blocker here!
The cleartext password is passed around a lot in the Rust program as well as in the Python parts so clearing it reliably from memory is out of the question - which is otherwise a hardening measure that some PAM module attempt to achieve.
It looks like the msal package passes the cleartext password on to the third party servers e.g. in msal/oauth2cli/oauth2.py:182 `_obtainToken()`. This means it should be avoided passing on passwords for accounts that aren't supposed to be authenticated this way, most notably root, of course. Do you have logic in place that prevents that?
`process_etc_passwd_group` in the daemon collects local users/groups and loads them into the cache nxset, which is meant to reject auth for local user/group names. William, I'm looking over the nxset check though, and it looks like it doesn't happen until after attempting to auth (in the resolver code)? I'm pretty sure I've seen the opposite behavior though, so can you comment on this William?
To trace this out, let's assume we're doing a pam flow. This starts in pam_account_authenticate which then immediately tries to get the users token (information token here, not auth token). This is done with pam_account_authenticate_init which immediately calls get_cached_usertoken. This calls dbtxn.get_account(). If the user is in the DB, then we return the info. If they aren't found, we check the nxcache. So lets be clear here, if the user is part of the nxset (aka a local account or id) they can not be part of the db cache, and they won't be in the nxcache. So this will always return None. At this point we also don't know if the name given to us by the requestor (such as "admin") will actually resolve differently into the user token. Kanidm allows this where you can login with "william" but it will resolve and render to "william@idm.suse.com". So we have to proceed with the auth here because we don't know the final state of the users id yet. The auth session then starts and we step with the pam module collecting credentials and components with pam_account_authenticate_step until we get to AuthResult::Success back from the provider in that function. At that point we now have the users fully resolved identity in the token returned to us by the provider. This is where we check the nxset to see if there is an identity collision, of the id of the user as it would be *resolved* on the system. If there is a collision, we return a pam denied. So to summarise: * local system users can't be in the nxcache or the dbcache * we can't check the nxset until the auth completes because we don't know the final name/gid/uid of the account until auth completes * if the user has a name/gid/uid conflict, we are checking the *remote* provider credentials, not the local /etc/shadow credentials, so this is not somehow exposing attacks again local users. * the nxset contains all local account names and uid/gids to ensure that there are no ways for a remote user to "claim" being a local system account. * The nxset is watched with inotify to ensure any live changes to the system are immediately reflected in the resolver Hope that helps :) -- You are receiving this mail because: You are on the CC list for the bug.
participants (1)
-
bugzilla_noreply@suse.com