{"id":6168,"date":"2020-06-13T21:46:17","date_gmt":"2020-06-13T18:46:17","guid":{"rendered":"https:\/\/kifarunix.com\/?p=6168"},"modified":"2024-03-14T21:19:15","modified_gmt":"2024-03-14T18:19:15","slug":"configure-openldap-password-expiry-email-notification","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/configure-openldap-password-expiry-email-notification\/","title":{"rendered":"Configure OpenLDAP Password Expiry Email Notification"},"content":{"rendered":"\n

In this tutorial, we are going to learn how to configure OpenLDAP password expiry email notification. If you are using identity and authentication clients such as SSSD on your OpenLDAP clients, you might have realized that, everytime you are logging into a system, SSSD displays a number of days before the password expires, that is only if the OpenLDAP password expiration policies have been implemented.<\/p>\n\n\n\n

However, end users are always end users. They will always ignore these notifications. They never like the idea of changing password, :). Therefore, having different means of notifying them and even the system admins themselves about the password expiry is a great idea. This tutorial therefore will provide some basics steps to take to configure OpenLDAP to send out notifications via email to users mailbox informing them about the password expiration.<\/p>\n\n\n\n

In our previous guides, we learnt how to implement OpenLDAP password policies. The link is provided below;<\/p>\n\n\n\n

Implement OpenLDAP Password Policies<\/a><\/p>\n\n\n\n

Similarly, we also covered how users can reset their OpenLDAP passwords by themselves using the OpenLDAP self service password tool;<\/p>\n\n\n\n

Setup LDAP Self Service Password Tool on CentOS 8<\/a><\/p>\n\n\n\n

Send OpenLDAP Password Expiry Notifications via Email<\/h2>\n\n\n\n

While scouring Internet, we came across the LDAP Tool Box (LTB)<\/a>, script that has been written to browse the LDAP directory to look for entries that uses password policy. If the user’s password will expire soon, a mail is sent.<\/p>\n\n\n\n

The script is tested with OpenLDAP (ppolicy overlay). We provided a link to configuring password policies using the ppolicy overlay<\/strong><\/code> above.<\/p>\n\n\n\n

Check LDAP Password Expiration Script<\/h3>\n\n\n\n

We downloaded the script and modified it to suit our OpenLDAP directory settings. It can sent the email notification to users whose account passwords are in warning state and at the same time, sent the statistics to a specific administrator.<\/strong><\/p>\n\n\n\n

Below is the contents of our modified version of the script with comment lines removed.<\/strong><\/p>\n\n\n\n

The original version of the script can be found at the LTB Github LDAP scripts repository<\/a>.<\/p>\n\n\n\n

grep -Ev \"^\\s[#\\;]|^\\s$|^#\" checkLdapPwdExpiration.sh<\/code><\/pre>\n\n\n\n
MY_LDAP_HOSTURI=\"ldapi:\/\/\/\"\nMY_LDAP_DEFAULTPWDPOLICYDN=\"cn=default,ou=pwpolicy,dc=ldapmaster,dc=kifarunix-demo,dc=com\"\nMY_LDAP_SEARCHBASE=\"ou=people,dc=ldapmaster,dc=kifarunix-demo,dc=com\"\nMY_LDAP_SEARCHFILTER=\"(&(uid=*)(objectClass=inetOrgPerson))\"\nMY_LDAP_SEARCHSCOPE=\"one\"\nMY_LDAP_SEARCHBIN=\"\/usr\/bin\/ldapsearch\"\nMY_LDAP_NAME_ATTR=cn\nMY_LDAP_LOGIN_ATTR=uid\nMY_LDAP_MAIL_ATTR=mail\nexport LC_ALL=en_US.UTF-8\nMY_MAIL_BODY=\"Hi %name,\\n\\n \\\n\tYour password will expire in %expireDays days on %expireTimeTZ.\\n\\n \\\n        Visit Kifarunix-demo Self Service Password site, https:\/\/ldap-ssp.kifarunix-demo.com to reset your password.\\n\\n \\\n\tAs a reminder, ensure that your password conforms to the company outlined password policies.\\n\\n \\\n\tKifarunix-demo IT team,\\n\n\tRegards.\"\nEX_MAIL_BODY=\"Hi %name,\\n\\n \\\n\tYour password expired on %expireTimeTZ.\\n\\n \\\n        Kindly contact Kifarunix-demo IT team to help reset the password.\\n\\n \\\n\tKifarunix-demo IT team,\\n\n\tRegards.\"\nMY_MAIL_SUBJECT=\"LDAP Account Password Expiry Status\"\nMY_MAIL_BIN=\"mail\"\nMY_LOG_HEADER=\"`date +\\\"%b %e,%Y %T\\\"`\"\nMY_GAWK_BIN=\"\/usr\/bin\/gawk\"\ngetTimeInSeconds() {\n\tdate=0\n\tos=`uname -s`\n\tif [ \"$1\" ]; then\n\t\tdate=`${MY_GAWK_BIN} 'BEGIN  { \\\n\t\t\tif (ARGC == 2) { \\\n\t\t        \tprint mktime(ARGV[1]) \\\n\t\t\t} \\\n\t\t\texit 0 }' \"$1\"`\n\telse\n\t\tif [ \"${os}\" = \"SunOS\" ]; then\n\t\t\tdate=`\/usr\/bin\/truss \/usr\/bin\/date 2>&1 | nawk -F= \\\n\t\t\t\t'\/^time\\(\\)\/ {gsub(\/ \/,\"\",$2);print $2}'`\n\t\telse\n\t\t\tnow=`date +\"%Y %m %d %H %M %S\" -u`\n\t\t\tdate=`getTimeInSeconds \"$now\"`\n\t\tfi\n\tfi\n\techo ${date}\n}\ntmp_dir=\"\/tmp\/$$.checkldap.tmp\"\nresult_file=\"${tmp_dir}\/res.tmp.1\"\nbuffer_file=\"${tmp_dir}\/buf.tmp.1\"\ntmp_dir_stats=\"\/tmp\/ldap-password-stats\"\nldap_param=\"-Y EXTERNAL -H ${MY_LDAP_HOSTURI} -LLL -Q\"\nnb_users=0\nnb_expired_users=0\nnb_warning_users=0\nif [ -d ${tmp_dir} ]; then\n\techo \"Error : temporary directory exists (${tmp_dir})\"\n\texit 1\nfi\nmkdir ${tmp_dir}\nif [ ${MY_LDAP_ROOTDN} ]; then\n\tldap_param=\"${ldap_param} -D ${MY_LDAP_ROOTDN} -w ${MY_LDAP_ROOTPW}\"\nfi\n${MY_LDAP_SEARCHBIN} ${ldap_param} -s ${MY_LDAP_SEARCHSCOPE} \\\n\t-b \"${MY_LDAP_SEARCHBASE}\" \"${MY_LDAP_SEARCHFILTER}\" \\\n\t\"dn\" > ${result_file}\nwhile read dnStr\ndo\n\tif [ ! \"${dnStr}\" ]; then\n\t\tcontinue\n\tfi\n\tdn=`echo ${dnStr} | cut -d : -f 2`\n\tnb_users=`expr ${nb_users} + 1`\n\t${MY_LDAP_SEARCHBIN} ${ldap_param} -s base -b \"${dn}\" \\\n\t\t${MY_LDAP_NAME_ATTR} ${MY_LDAP_LOGIN_ATTR} ${MY_LDAP_MAIL_ATTR} pwdChangedTime pwdPolicySubentry \\\n\t\t> ${buffer_file}\n\tlogin=`grep -w \"${MY_LDAP_LOGIN_ATTR}:\" ${buffer_file} | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tname=`grep -w \"${MY_LDAP_NAME_ATTR}:\" ${buffer_file} | cut -d : -f 2\\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tmail=`grep -w \"${MY_LDAP_MAIL_ATTR}:\" ${buffer_file} | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tpwdChangedTime=`grep -w \"pwdChangedTime:\" ${buffer_file} \\\n\t\t| cut -d : -f 2 | cut -c 1-15 | sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tpwdPolicySubentry=`grep -w \"pwdPolicySubentry:\" ${buffer_file} \\\n\t\t| cut -d : -f 2 | sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tif [ ! \"${pwdChangedTime}\" ]; then\n\t\techo \"No password change date for ${login} (${mail})\" >> ${tmp_dir_stats}\n\t\tcontinue\n\tfi\n\tif [ ! \"${pwdPolicySubentry}\" -a ! \"${MY_LDAP_DEFAULTPWDPOLICYDN}\" ]; then\n\t\techo \"No password policy for ${login} (${mail})\" >> ${tmp_dir_stats}\n\t\tcontinue\n\tfi\n\tldap_search=\"${MY_LDAP_SEARCHBIN} ${ldap_param} -s base\"\n\tif [ \"${pwdPolicySubentry}\" ]; then\n\t\tldap_search=\"${ldap_search} -b ${pwdPolicySubentry}\"\n\telse\n\t\tldap_search=\"${ldap_search} -b ${MY_LDAP_DEFAULTPWDPOLICYDN}\"\n\tfi\n\tldap_search=\"$ldap_search pwdMaxAge pwdExpireWarning pwdMinLength pwdInHistory\"\n\tpwdMaxAge=`${ldap_search} | grep -w \"pwdMaxAge:\" | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tpwdExpireWarning=`${ldap_search} | grep -w \"pwdExpireWarning:\" | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tpwdMinLength=`${ldap_search} | grep -w \"pwdMinLength:\" | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n\tpwdInHistory=`${ldap_search} | grep -w \"pwdInHistory:\" | cut -d : -f 2 \\\n\t\t| sed \"s\/^ *\/\/;s\/ *$\/\/\"`\n        if [ ! \"${pwdMaxAge}\" ]; then\n                echo \"No password expiration configured for ${login} (${mail})\" >> ${tmp_dir_stats}\n                continue\n        fi\n\tMY_MAIL_DELAY=${MY_MAIL_DELAY:=$pwdExpireWarning}\n\tif [ \"${pwdChangedTime}\" ]; then\n\t\ts=`echo ${pwdChangedTime} | cut -c 13-14`\n\t\tm=`echo ${pwdChangedTime} | cut -c 11-12`\n\t\th=`echo ${pwdChangedTime} | cut -c 9-10`\n\t\td=`echo ${pwdChangedTime} | cut -c 7-8`\n\t\tM=`echo ${pwdChangedTime} | cut -c 5-6`\n\t\ty=`echo ${pwdChangedTime} | cut -c 1-4`\n\t\tcurrentTime=`getTimeInSeconds`\n\t\tpwdChangedTime=`getTimeInSeconds \"$y $M $d $h $m $s\"`\n\t\tdiffTime=`expr ${currentTime} - ${pwdChangedTime}`\n\tfi\n\texpireTime=`expr ${pwdChangedTime} + ${pwdMaxAge}`\n\tif [ ${currentTime} -gt ${expireTime} ]; then\n\t\tnb_expired_users=`expr ${nb_expired_users} + 1`\n\t\texpireTime=`date -d @$expireTime \"+%A %d, %B %Y at %T\"`\n\t        logmsg=\"${EX_MAIL_BODY}\"\n\t\tlogmsg=`echo -e ${logmsg} | sed \"s\/%name\/${name}\/; \\\n\t\t\ts\/%login\/${login}\/; s\/%expireTimeTZ\/${expireTime}\/; s\/%pwdMinLength\/${pwdMinLength}\/; s\/%pwdInHistory\/${pwdInHistory}\/; \\\n\t\t\ts\/%expireDays\/${expireDays}\/\"`\n\t\techo \"${logmsg}\" | ${MY_MAIL_BIN} -s \"${MY_MAIL_SUBJECT}\" ${mail} >&2\n\t\techo \"Password expired for ${login} on ${expireTime}. Mail sent to ${mail}\" >> ${tmp_dir_stats}\n\t\tcontinue\n\tfi\n\texpireTimeTZ=`date -d @$expireTime \"+%A %d, %B %Y at %T\"`\n\texpireTimeMail=`date -d @$expireTime \"+%s\"`\n\tnow=`date +%s`\n\texpireDays=`echo $(( (${expireTimeMail} - ${now} )\/(60*60*24) ))`\n\tif [ \"${mail}\" -a \"${name}\" \\\n\t\t-a \"${login}\" -a \"${diffTime}\" -a \"${pwdMaxAge}\" ]\n\tthen\n\t\tdiffTime=`expr ${diffTime} + ${MY_MAIL_DELAY}`\n\t\tif [ ${diffTime} -gt ${pwdMaxAge} ]; then\n\t\t\tlogmsg=\"${MY_MAIL_BODY}\"\n\t\t\tlogmsg=`echo -e ${logmsg} | sed \"s\/%name\/${name}\/; \\\n\t\t\t\ts\/%login\/${login}\/; s\/%expireTimeTZ\/${expireTimeTZ}\/; s\/%pwdMinLength\/${pwdMinLength}\/; s\/%pwdInHistory\/${pwdInHistory}\/; \\\n\t\t\t\ts\/%expireDays\/${expireDays}\/\"`\n\t\t\techo \"${logmsg}\" | ${MY_MAIL_BIN} -s \"${MY_MAIL_SUBJECT}\" ${mail} >&2\n\t\t\techo \"Password warning for ${login} (expiry date, ${expireTimeTZ}). Mail sent to ${mail}\" >> ${tmp_dir_stats}\n\t\t\tnb_warning_users=`expr ${nb_warning_users} + 1`\n\t\tfi\n\tfi\ndone < ${result_file}\nsed -i \"1iHello Admin,\\nFind the LDAP users account password expiry status as at ${MY_LOG_HEADER}.\\n\" ${tmp_dir_stats}\necho \"Total User Accounts checked: ${nb_users}\" >> ${tmp_dir_stats}\necho \"Accounts with Expired Passwords: ${nb_expired_users}\" >> ${tmp_dir_stats}\necho \"Accounts with Passwords in Warning state: ${nb_warning_users}\" >> ${tmp_dir_stats}\nsed -i -e '\/^Total.*\/i\\\\ ' -e '\/^Total.*\/i ===== Statistics =====' ${tmp_dir_stats}\nmail -s \"LDAP Password Expiration Status\" kifaunix@gmail.com < ${tmp_dir_stats}\nrm -rf ${tmp_dir}\nrm -rf ${tmp_dir_stats}\nexit 0\n<\/code><\/pre>\n\n\n\n

The Script Requirements<\/h4>\n\n\n\n

As outlined on the LTB page, the script requires;<\/p>\n\n\n\n