Have a look at this thread too on serverfault. However, I've found an amazing resource out there: checkLdapPwdExpiration.sh that might come very helpful for you.
Here below a shortened version of such amazing script, that works for my configuration
#!/bin/sh
MY_LDAP_HOSTURI="ldap://localhost:389"
MY_LDAP_ROOTDN="cn=Manager,dc=example,dc=com"
MY_LDAP_ROOTPW="qwerty"
MY_LDAP_DEFAULTPWDPOLICYDN="ou=Policies,dc=example,dc=com"
MY_LDAP_SEARCHBASE="ou=users,dc=example,dc=com"
MY_LDAP_SEARCHFILTER="(&(uid=*)(objectClass=inetOrgPerson))"
MY_LDAP_SEARCHSCOPE="one"
MY_LDAP_SEARCHBIN="/usr/bin/ldapsearch"
MY_LDAP_NAME_ATTR=cn
MY_LDAP_LOGIN_ATTR=uid
MY_GAWK_BIN="/usr/bin/gawk"
# Retrieves date in seconds.
# This function could take one parameter, a time returned by the command
# `date +"%Y %m %d %H %M %S"`. Without parameter, it returns GMT time.
getTimeInSeconds() {
date=0
if [ "$1" ]; then
date=`TZ=UTC ${MY_GAWK_BIN} 'BEGIN { \
if (ARGC == 2) { \
print mktime(ARGV[1]) \
} \
exit 0 }' "$1"`
else
now=`date +"%Y %m %d %H %M %S" -u`
date=`getTimeInSeconds "$now"`
fi
echo ${date}
}
## Variables initialization
tmp_dir="/tmp/$$.checkldap.tmp" ; result_file="${tmp_dir}/res.tmp.1" ; buffer_file="${tmp_dir}/buf.tmp.1"
ldap_param="-x -LLL -H ${MY_LDAP_HOSTURI}" ; mkdir ${tmp_dir}
[ ${MY_LDAP_ROOTDN} ] && ldap_param="${ldap_param} -D ${MY_LDAP_ROOTDN} -w ${MY_LDAP_ROOTPW}"
## Performs global search
${MY_LDAP_SEARCHBIN} ${ldap_param} -s ${MY_LDAP_SEARCHSCOPE} \
-b "${MY_LDAP_SEARCHBASE}" "${MY_LDAP_SEARCHFILTER}" \
"dn" | grep -iE '^dn:' > ${result_file}
while read dnStr # Loops on results
do
[ ! "${dnStr}" ] && continue # Do not use blank lines
dn=`echo ${dnStr} | cut -d : -f 2` # Process ldap search
${MY_LDAP_SEARCHBIN} ${ldap_param} -s base -b "${dn}" \
${MY_LDAP_NAME_ATTR} ${MY_LDAP_LOGIN_ATTR} pwdChangedTime pwdPolicySubentry \
> ${buffer_file}
login=`grep -w "${MY_LDAP_LOGIN_ATTR}:" ${buffer_file} | cut -d : -f 2 \
| sed "s/^ *//;s/ *$//"`
name=`grep -w "${MY_LDAP_NAME_ATTR}:" ${buffer_file} | cut -d : -f 2\
| sed "s/^ *//;s/ *$//"`
pwdChangedTime=`grep -w "pwdChangedTime:" ${buffer_file} \
| cut -d : -f 2 | cut -c 1-15 | sed "s/^ *//;s/ *$//"`
pwdPolicySubentry=`grep -w "pwdPolicySubentry:" ${buffer_file} \
| cut -d : -f 2 | sed "s/^ *//;s/ *$//"`
[ ! "${pwdChangedTime}" ] && continue
[ ! "${pwdPolicySubentry}" -a ! "${MY_LDAP_DEFAULTPWDPOLICYDN}" ] && continue
# Retrieves user policy pwdMaxAge and pwdExpireWarning attributes
ldap_search="${MY_LDAP_SEARCHBIN} ${ldap_param} -s base"
if [ "${pwdPolicySubentry}" ]; then
ldap_search="${ldap_search} -b ${pwdPolicySubentry}"
else
ldap_search="${ldap_search} -b ${MY_LDAP_DEFAULTPWDPOLICYDN}"
fi
ldap_search="$ldap_search pwdMaxAge pwdExpireWarning pwdMinLength pwdInHistory"
pwdMaxAge=`${ldap_search} | grep -w "pwdMaxAge:" | cut -d : -f 2 \
| sed "s/^ *//;s/ *$//"`
pwdExpireWarning=`${ldap_search} | grep -w "pwdExpireWarning:" | cut -d : -f 2 \
| sed "s/^ *//;s/ *$//"`
pwdMinLength=`${ldap_search} | grep -w "pwdMinLength:" | cut -d : -f 2 \
| sed "s/^ *//;s/ *$//"`
pwdInHistory=`${ldap_search} | grep -w "pwdInHistory:" | cut -d : -f 2 \
| sed "s/^ *//;s/ *$//"`
[ ! "${pwdMaxAge}" ] && continue
# Retrieves time difference between today and last change.
if [ "${pwdChangedTime}" ]; then
s=`echo ${pwdChangedTime} | cut -c 13-14`
m=`echo ${pwdChangedTime} | cut -c 11-12`
h=`echo ${pwdChangedTime} | cut -c 9-10`
d=`echo ${pwdChangedTime} | cut -c 7-8`
M=`echo ${pwdChangedTime} | cut -c 5-6`
y=`echo ${pwdChangedTime} | cut -c 1-4`
currentTime=`getTimeInSeconds`
pwdChangedTime=`getTimeInSeconds "$y $M $d $h $m $s"`
diffTime=`expr ${currentTime} - ${pwdChangedTime}`
fi
expireTime=`expr ${pwdChangedTime} + ${pwdMaxAge}`
expireTimeMail=`date -d @$expireTime "+%s"` ; now=`date +%s`
expireDays=`echo $(( (${expireTimeMail} - ${now} )/(60*60*24) ))`
if [ ${currentTime} -gt ${expireTime} ]; then
echo "Password expired for: ${login}" ; continue
else
echo "Password will expire for: ${login} in ${expireDays} days" ; continue
fi
done < ${result_file} ; rm -rf ${tmp_dir} ; exit 0
NB: it may occurs that new password policies are not enforced immediately and you might need to wait for a password change for them to be effective.