Many operating systems allow you to set maximum password age. After it is reached, user gets the message like “Your password has expired and must be changed”. For instance, in case of Windows 7 you can set maximum password age in the following way:
1. Run “secpol.msc”
2. In the left pane, expand “Account Policies”, and click on “Password Policy”. Edit the values in the right pane.
3. Make sure that user account has password expiration enabled: run lusrmgr.msc, find the required user account, click proiperties, ensure that “Password never expires” is uchecked.
(see
http://www.sevenforums.com/tutorials/7539-local-users-groups-manager-open.html,
http://www.sevenforums.com/tutorials/73210-password-expiration-enable-disable.html for details).
The post describes the API that allows you to find password expiration date for a specified user account.
1.
Windows: use
NetUserGetInfo function. For a given domain controller name, user name and information level it returns user information. In our case we need information level 2 (and probably higher). In this case information is returned in
USER_INFO_2 which has a field called
usri2_password_age (the number of seconds that have elapsed since the password was last changed).
Now check the
NetUserModalsGet fuction. For a given domain controller name it returns global information about users (see struct
USER_MODALS_INFO_0, which has a
usrmod0_max_passwd_age member). Now just subtract
usri2_password_age from
usrmod0_max_passwd_age and divide by 60*60*24 (the number of seconds in a day) to get count of days left.
To get the domain contoller you may use
NetGetAnyDCName fuction (for instance, call
NetGetAnyDCName(null, L“MYDOMAIN”, &controller) to get the domain controller of MYDOMAIN).
All of the functions mentioned above allocate memory, so do not forget to free it using the NetApiBufferFree function.
Samples can be found in MSDN.
2.
Linux and
Solaris provide a set of shadow fuctions (
#include <shadow.h>).
We are interested in
getspnam function.
For a given user name It returns a pointer to
struct spwd. Interesting members are
sp_lstchg (days since Jan 1, 1970 password was last changed) and
sp_max (days after which password must be changed). So (
spwd.sp_lstchg + spwd.sp_max) is a date when user’s password must be changed.
More information is available in manual.
3.
AIX. I haven’t found a reliable way to find password expiration date. A possible solution is to call
passwdexpired function. For a given user name it returns a character string like “Your password will expire: Wed Nov 2 10:30:35 EDT 2011”. Now it is possible to parse the string. However I am not sure in the format of message and hence I dislike this solution.
If you know any way to get the password expiration date, please let me know!