Find when password expires with ldapsearch
Asked Answered
B

2

7

Is there a way to determine when an LDAP password is set to expire with ldapsearch? I haven't been able to see anything in man pages that would allow me to get this information.

I see warning messages in /var/log/secure that warn of when a password is expiring so I know this information is available somehow, just not sure how.

Bulbil answered 1/12, 2017 at 1:59 Comment(0)
S
3

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.

Shoplifter answered 12/7, 2021 at 10:33 Comment(0)
I
2

You would have to:

  • discover the applicable password policy
  • get its pwdMaxAge value and
  • if non-zero, add it to the entry's pwdChangedTime value, which yields the expiration date and time.

You can't do all that with a single search. You would need two, or three if you're using per-entry policies, and you also need a means of finding the default policy entry, which is in the configuration, not necessarily in the DIT at all. If pwdMaxAge is zero or absent, passwords don't expire.

The password-policy overlay can deliver response controls containing warnings of impending expiration of the current user's password when binding. Is that what you're really looking for?

Intergrade answered 2/12, 2017 at 23:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.