Wednesday, December 7, 2011

How to check password expiration date programmatically (Windows, Linux, Solaris, AIX)

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, 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!

No comments:

Post a Comment