Forum OpenACS Q&A: Password expiration

Posted by Claudio Pasolini on
I'm trying to enable the password expiration management on a fresh oacs-5-9-1 install, setting the kernel parameter PasswordExpirationDays to 60.

To be sure I also set the AllowPersistentLoginP and DefaultPersistentLoginP to 0, then I logged out and set the password_changed_date on the users table one year in the past.

I restarted the server and after logging in I was correctly asked to change my password and to log in with the new password, but after logging in I wasked to change my password again.

If I restart the server I can log in without problem and so I suspect this is a caching problem.

The following are the relevant software versions:

Database: PostgreSQL 13.4 (Debian 13.4-3) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.3.0-8) 10.3.0, 64-bit
Server: 4.99.19 (NaviServer)
Tcl: 8.6.10
XOTcl: 2.3.0
Tdom: 0.9.1
libthread: /usr/local/ns/lib/thread2.8.6/
Tcllib: /usr/local/ns/lib/tcllib1.20
acs-kernel: 2017-08-06, 5.9.2d2
xotcl-core: 2017-08-06, 5.9.1

Thanks in advance for any suggestion.

Claudio Pasolini

2: Re: Password expiration (response to 1)
Posted by Claudio Pasolini on
Well, probably nobody is using the password expiration feature, but if anyone was interested the loop login/password-change is caused by the proc acs_user::get using util_memoize to get the user data.

This is useful to avoid repeatedly reading the users table, but when during login the proc auth::check_local_account_status compares the password_age_days with PasswordExpirationDays it uses the cached value and leads to a loop.

The proc auth::check_local_account_status is the only point where the password age is checked and is only used during the login and so I simply reread password_age_days:

set password_age_days [db_string reread " select trunc(date_part('epoch', age(password_changed_date))/(60*60*24)) from users where user_id = :user_id"]

3: Re: Password expiration (response to 1)
Posted by Gustaf Neumann on

Dear Claudio,

One reason for not getting immediate feedback is that you are asking a question about an old release, that we have not around anymore in action. Many things have changed in the user management in 5.10 (Antonio cleaned up much of this, the usage of util_memoize was greatly reduced for scalability reasons).

The second reason is that you are directly modifying a value in the database, which causes very likely cache inconsistency. This is no usage scenario of the system. The proper call after changing user data in the DB is to issue

  acs_user::flush_user_info -user_id $user_id

In case you want to support this kind of direct updates to the DB for user_ids in your system, you might consider adding this line toauth::check_local_account_status or auth::get_local_account_status, that's better than duplicating this logic.

4: Re: Password expiration (response to 1)
Posted by Claudio Pasolini on
Thank you Gustaf,

I missed acs_user::flush_user_info -user_id $user_id.

Actually I didn't change the database, but I simply added one line to auth::check_local_account_status rereading password_age_days from the users table.