On 04/22/2015 11:09 AM, Sumit Bose wrote:
On Tue, Apr 21, 2015 at 03:39:11PM +0200, Pavel Reichl wrote:
> Hello,
>
> I have prepared wiki page with proposal how to implement the feature from the
subject.
>
>
https://fedorahosted.org/sssd/wiki/DesignDocs/CachedAuthentication
>
> For your convenience I paste the content here.
Hi Pavel,
thank you for taking care of this, please find comments in-line.
bye,
Sumit
Thank you very much for comments, I'll update the page, but please see
the responses inline first.
> Thanks!
>
> = Authenticate against cache in SSSD =
>
> Related ticket(s):
> *
https://fedorahosted.org/sssd/ticket/1807
>
> === Problem statement ===
> SSSD should allow cache authentication instead of authenticating directly against
network server every time. Authenticating against the network many times can cause
excessive application latency.
>
> === Use cases ===
> In environments with tens of thousands of users log in process may become
inappropriately long, when servers are running under high workload (e.g. during classes,
when may users log in simultaneously).
>
> === Overview of the solution ===
> Add new domain option `cached_authentication_timeout` describing how long can be
cached credentials used for cached authentication before on-line authentication must be
performed. Update PAM responder functionality for forwarding requests to domains by
checking if request can be served from cache and if so execute same code branch as for
off-line authentication instead of contacting the domain.
>
> === Implementation details ===
>
> * extend ''struct pam_auth_req''
> * add new field `use_cached_auth` (default value is false)
> * extend ''pam_dom_forwarder()''
> * obtain value of domain option `cached_authentication_timeout`
I think you can add a new element to pam_ctx for this like we currently
do this e.g. with id_timeout.
Yes, it will be better than parsing the value every
time from confdb,
although as Jakub stated I intend to set this value per domain so
sss_domain_info will be changed instead of pam_ctx.
Please check if cached_authentication_timeout is not larger than
offline_credentials_expiration (given in days) and use the smaller of
the two.
Sure, I wanted just to document behavior but this is better.
> * do not forward request to domain if
> * domain uses cached credentials and
> * `cached_authentication_timeout` is greater than 0 and
> * last online log in of user who is being authenticated is not stale (<
''now()'' - `cached_authentication_timeout`) and
> * PAM request can be handled from cache (PAM command is SSS_PAM_AUTHENTICATE or
SSS_PAM_ACCT_MGMT)
I think for SSS_PAM_ACCT_MGMT you have to forward the request to the
backends because otherwise you skip access control completely. Even if
offline the access control validation is done in the backends and we do
not save a result to the cache mainly because there might no be a single
result. E.g. access control might depend on the service and just knowing
that access was granted for service A does not help to determine if
access for service B should be granted as well. Nevertheless the backend
might have added sufficient information to the cache to do the
evaluation for service B even if offline.
Understood, thanks for explaining.
To speed up access control as well we could add a flag like
'may_use_cached_data' in the request to the backend which tells the
backend the cached data can be used for the evaluation. But I think this
would be a different RFE. The one at hand should only handle
SSS_PAM_AUTHENTICATE.
OK, I'll file a ticket and we can defer it on Thursday.
:-)
> * then set `use_cached_auth` to true
> * call ''pam_reply()''
> * extend ''pam_reply()''
> * extend condition for entering into block processing case when pam_status is
PAM_AUTHINFO_UNAVAIL even for `use_cached_auth` being true
> * while in this block and if PAM command is SSS_PAM_AUTHENTICATE then set
`use_cached_auth` to false to avoid cyclic recursion call of
''pam_reply()'' which is subsequently called from
''pam_handle_cached_login()''.
> * introduce function ''sysdb_get_user_lastlogin()''
> * returning time of last online performed log in for given user
but only if pam_verbosity is high enough
Sorry, I think I badly described this.
sysdb_get_user_lastlogin() would
be used just to obtain value of last online login from sysdb while
deciding in pam_dom_forwarder() whether authentication can be served
from cache or BE must be contacted. No output to console should happen
here.
> === Configuration changes ===
> A new domain option `cached_authentication_timeout` will be added. The value of this
option is time period for which cached authentication can be used. After this period is
exceeded on-line authentication must be performed. The default value would be 0, which
implies that this feature is by default disabled.
>
> === How To Test ===
> 1. set `cached_authentication_timeout` in sssd.conf to some non-null value (e.g.
120)
> 1. erase SSSD caches and restart SSSD
> 1. log in as user from domain which stores credentials and then log out and log in
again. The second log in should use cached credentials. Output should by similar to this,
especially note the line starting with: '''Authenticated with cached
credentials'''
> {{{
> devel@dev $ su john
> Password:
> john@dev $ exit
> devel@dev $ su john
> Password:
> Authenticated with cached credentials, your cached password will expire at: Wed 22
Apr 2015 08:47:29 AM EDT.
as mentioned above I think this message should not be send by default
because it might irritate the user.
Yes, I will update design page that
pam_verbosity must be set to see
this. (I don't intend to add any console output)
> john@dev $
> }}}
> 1. for the `cached_authentication_timeout` seconds since the 1st log in all
subsequent log in attempts (for the same user) should be served from cache and domain
should not be contacted, this can be verified by changing password at server.
> 1. after passing more than `cached_authentication_timeout` seconds since the 1st log
in an on-line log in should be performed and new password must be used.
I wonder what should happen after a local password change. We save the
hash of the new password to the cache but I think we do not change the
last online auth time here. Shall we do cached authentication with the
new password immediately here or shall we go to the backend at least
once to make sure the backend knows about the new password. I think I
would prefer the latter.
I think we should definitely do online log in next time
user try to log
in. Question is how?
1) I'm worried that if SYSDB_LAST_ONLINE_AUTH was set to 0 after local
password change we would disable not even cached log in but even off
line log in.
2) I could introduce SYSDB_LAST_ONLINE_AUTH_WITH_CURRENT_TOKEN that
would behave as SYSDB_LAST_ONLINE_AUTH but could be set to 0 as proposed
in 1)
Please add test with wrong password as well to check if
offline_failed_login_attempts and offline_failed_login_delay are
respected here as well (I have not doubt about this because the same
code patch will be used but better be on the save side and be able to
detect regression early).
Sure.
As an alternative we might want to send the request to the backend if
cached authentication fails. This would cover the case where the user
changed the password on the server and tries to login in to a system
where the cached_authentication_timeout is not expired yet with the new
password.
Yes, I agree that we must do that.
1) We could just set SYSDB_LAST_ONLINE_AUTH (or
SYSDB_LAST_ONLINE_AUTH_WITH_CURRENT_TOKEN) to 0 and require on line log
in next time.
2) Try online log in immediately. I suppose this is preferred because it
provides better user experience.
> === Authors ===
> * Pavel Reichl <preichl(a)redhat.com>
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel(a)lists.fedorahosted.org
>
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
_______________________________________________
sssd-devel mailing list
sssd-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel