#3162 Add DBus call to allow account activation status lookup
Closed: wontfix 4 years ago by pbrezina. Opened 7 years ago by nkinder.

Applications that integrate with SSSD via DBus may need to perform account activation status checks. This is usually done by attempting to authenticate the user, which will fail with a specific status if a user is deactivated. There are cases where we can't authenticate the user because an application does not have a credential for the user that it can present to SSSD.

Consider the case where an IdP such as Keycloak is using SSSD via DBus to authenticate and lookup user identity information. A user may have an OAuth 2.0 refresh token that was issued from Keycloak, which is a long-lived credential designed for later use. When a user (or automation task on their behalf) presents this refresh token to the IdP, we would ideally check if the user has been disabled via SSSD before honoring that refresh token. To do this, we would need something like a DBus cal that can check the account activation status for a specific user.

Different providers store account activation status in varying ways, so SSSD would ideally abstract these details and provide a consistent interface to applications. For example, IdM uses a boolean for it's nsAccountLock attribute for account status, while Active Directory uses a bit-field for it's UserAccountControl attribute.


This sounds like essentially asking for D-Bus AA interface, because what the interface would do is an equivalent of pam account phase, right?

Could the application call pam in the meantime?

Yes, please tell more what exactly should be done laveraging PAM account. The concern is how an application can differentiate that account is there but there was authentication problem or account is there and expired/disabled and there is no account at all. If app tires to authenticate a user the authentication will fail in all three cases without any clarity what was the cause of the problem. For logging into the system it is OK but for logging into an application the actions might be different. If this is an authentication problem then application might do nothing. If the account is disabled/expired application might want to mark the account as such, and if the account is not there (any more) application might want to clean its database from the data related to this account.

Replying to [comment:2 dpal]:

Yes, please tell more what exactly should be done laveraging PAM account.

I believe Jakub is referring to the following PAM function:

#include <security/pam_appl.h>

int pam_acct_mgmt(pam_handle_t *pamh, int flags);

This function is designed to check the status of an account, and it has different return codes for different situations (PAM_ACCT_EXPIRED, PAM_USER_UNKNOWN, etc.). This requires using pam_start first, which is where you specify the user and pam service you want to use, which gives you the authentication handle. What I am not sure of is if this works without performing an actual authentication first (by calling pam_authenticate). Some of the possible return values (like PAM_AUTH_ERR) make we wonder if it will do what we need it to without first performing an authentication.

If you install the pam-devel package, you can find more details in the 'pam_acct_mgmt' man page.

I would like to suggest another approach. Pursue what Jakub suggested is certainly possible, but actually it does not exist on libpam4j. It would require some time to check which changes are necessary to achieve that.

My suggestion, due to time constraints is the following flow:

  1. Admin disables Mary's account
  2. Mary try to login on Keycloak
  3. Libpam4j will raise the following exception:

    org.jvnet.libpam.PAMException: pam_authenticate failed : User account has expired

Which from my perspective is good enough to distingish if user was disabled or not

  1. At Keycloak, we disable that user on the next login attempt.

Pros:

  • Meets the release schedule
  • Admins don't have to manually disable users disabled on IdM server

Cons:

  • The system will only find out if user was disabled or not, at the next login

I'm not saying that this is the best solution, but achievable while we don't have such interface on SSSD.

Does it make any sense?

Replying to [comment:4 abstractj]:

I would like to suggest another approach. Pursue what Jakub suggested is certainly possible, but actually it does not exist on libpam4j. It would require some time to check which changes are necessary to achieve that.

I was concerned that this might be the case.

My suggestion, due to time constraints is the following flow:

  1. Admin disables Mary's account
  2. Mary try to login on Keycloak
  3. Libpam4j will raise the following exception:

{{{
org.jvnet.libpam.PAMException: pam_authenticate failed : User account has expired
}}}

Which from my perspective is good enough to distingish if user was disabled or not

  1. At Keycloak, we disable that user on the next login attempt.

Pros:

  • Meets the release schedule
  • Admins don't have to manually disable users disabled on IdM server

Cons:

  • The system will only find out if user was disabled or not, at the next login

I'm not saying that this is the best solution, but achievable while we don't have such interface on SSSD.

Does it make any sense?

How would you handle the case where the user was re-enabled in the LDAP server? Are you still going to attempt authentication via PAM for a user that is disabled in Keycloak?

Your solution is probably the best you can do for now.

Replying to [comment:5 nkinder]:

Replying to [comment:4 abstractj]:

I would like to suggest another approach. Pursue what Jakub suggested is certainly possible, but actually it does not exist on libpam4j. It would require some time to check which changes are necessary to achieve that.

I was concerned that this might be the case.

My suggestion, due to time constraints is the following flow:

  1. Admin disables Mary's account
  2. Mary try to login on Keycloak
  3. Libpam4j will raise the following exception:

{{{
org.jvnet.libpam.PAMException: pam_authenticate failed : User account has expired
}}}

Which from my perspective is good enough to distingish if user was disabled or not

  1. At Keycloak, we disable that user on the next login attempt.

Pros:

  • Meets the release schedule
  • Admins don't have to manually disable users disabled on IdM server

Cons:

  • The system will only find out if user was disabled or not, at the next login

I'm not saying that this is the best solution, but achievable while we don't have such interface on SSSD.

Does it make any sense?

How would you handle the case where the user was re-enabled in the LDAP server? Are you still going to attempt authentication via PAM for a user that is disabled in Keycloak?

Your solution is probably the best you can do for now.

Hi Natan, for such scenario my idea is to invert the logic. Into other words, the user is always enabled based on her attempts to login. If authentication raises that exception, user is disabled on Keycloak; if succeeds, user will be enabled again.

I believe that this approach might work for now. Although, the best solution is to provide the activation status based on SSSD via DBUS. For example, for user synchronization, my idea won't scale.

Replying to [comment:3 nkinder]:

Replying to [comment:2 dpal]:

Yes, please tell more what exactly should be done laveraging PAM account.

I believe Jakub is referring to the following PAM function:

#include <security/pam_appl.h>

int pam_acct_mgmt(pam_handle_t *pamh, int flags);

This function is designed to check the status of an account, and it has different return codes for different situations (PAM_ACCT_EXPIRED, PAM_USER_UNKNOWN, etc.). This requires using pam_start first, which is where you specify the user and pam service you want to use, which gives you the authentication handle. What I am not sure of is if this works without performing an actual authentication first (by calling pam_authenticate). Some of the possible return values (like PAM_AUTH_ERR) make we wonder if it will do what we need it to without first performing an authentication.

If you install the pam-devel package, you can find more details in the 'pam_acct_mgmt' man page.

I'm sorry this ticket fell off my radar..

Yes, calling pam_acct_mgmt() is certainly possible without authentication. What the user receives is totally up to the module in question, but typically if the user is denied access , code 6 (PAM_PERM_DENIED) is returned.

Replying to [comment:4 abstractj]:

I would like to suggest another approach. Pursue what Jakub suggested is certainly possible, but actually it does not exist on libpam4j.

Hmm, are you saying libpam4j doesn't support the account management checks that wrap pam_acct_mgmt()?

It would require some time to check which changes are necessary to achieve that.

My suggestion, due to time constraints is the following flow:

  1. Admin disables Mary's account
  2. Mary try to login on Keycloak

What PAM calls does Keycloak call when the user authenticates? I think the authentication and access control are a bit orthogonal and I would suggest the application (Keycloak here) would call them both (if applicable for the authentication method, see below for example). The reason is that some situations that prevent access can only be detected during authentication (for example if the password aged too much) and some only during the account phase (for example HBAC access control with IPA or GPO access control with AD).

And having these two separately might make sense as well, because for example if the organization uses only SSH keys to authenticate they might not care about password aging (so password based authentication would fail and it's expected to fail), but they might want GPO or HBAC access control.

I admit I don't know much about how Keycloak authenticates the user, but in general, I would expect the PAM application to call.

  1. Libpam4j will raise the following exception:

{{{
org.jvnet.libpam.PAMException: pam_authenticate failed : User account has expired
}}}

Which from my perspective is good enough to distingish if user was disabled or not

This is fine, but can Keycloak also call pam_acct_mgmt? I suspect since you are already calling a PAM conversation, there is already a call to pam_authenticate, is there not a call to pam_acct_mgmt?

  1. At Keycloak, we disable that user on the next login attempt.

Pros:

  • Meets the release schedule
  • Admins don't have to manually disable users disabled on IdM server

Cons:

  • The system will only find out if user was disabled or not, at the next login

I'm not saying that this is the best solution, but achievable while we don't have such interface on SSSD.

Does it make any sense?

Hi, does this ticket need more answers? If running pam's account control enough after all?

Since there was no response in this ticket, I'm moving it to the deferred queue for the time being. Please comment on the bug if using the pam_acct_mgmt interface does not solve the use-case for some reason.

milestone: NEEDS_TRIAGE => SSSD Deferred

Fields changed

rhbz: => todo

Metadata Update from @nkinder:
- Issue set to the milestone: SSSD Patches welcome

7 years ago

Thank you for taking time to submit this request for SSSD. Unfortunately this issue was not given priority and the team lacks the capacity to work on it at this time.

Given that we are unable to fulfill this request I am closing the issue as wontfix.

If the issue still persist on recent SSSD you can request re-consideration of this decision by reopening this issue. Please provide additional technical details about its importance to you.

Thank you for understanding.

Metadata Update from @pbrezina:
- Issue close_status updated to: wontfix
- Issue status updated to: Closed (was: Open)

4 years ago

SSSD is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in SSSD's github repository.

This issue has been cloned to Github and is available here:
- https://github.com/SSSD/sssd/issues/4195

If you want to receive further updates on the issue, please navigate to the github issue
and click on subscribe button.

Thank you for understanding. We apologize for all inconvenience.

Login to comment on this ticket.

Metadata