Leopard Server’s LDAP implementation allows an administrator to set requirements about user passwords, such as length of password, what characters it must include, how often it must be changed, etc. One major oversight on Apple’s part is a facility to inform users that their passwords will expire. Maybe if users login via AFP or using Network Home Directories they’d see a message, but we’re using LDAP for authentication from a bunch of other servers. As I didn’t want to have to remember to remind people to change their passwords, I came up with a script to handle it for me. I’ve seen other scripts out their, but they made some assumptions that didn’t work for us. Our mail server is on a different machine and usernames don’t match email addresses, so my solution had to be robust. The only requirement for my script is that the email address has to be filled in for the LDAP entry. Also you must have some facility for users to change his/her own password. We’re using a WebObjects program we found to let users do this.
You’ll need to change the LDAP server name and the number of days to send out the reminder; we require password changes every 90 days, so I send the reminder seven days before. This is run via a crontab at midnight (or so) each evening.
I’m not an awk master, but this seems to be working fine
#!/bin/sh
datelogfile=/backups/datechange.log
tmpfile=/tmp/passwordchange.tmp
grep -h "changed" /Library/Logs/PasswordService/ApplePasswordServer.Server.log* | awk '{ test=$1 " " $2 " " $3 " " $4; cmd="date -j -f \"%b %d %Y %H:%M:%S\" \047"test"\047 +%s"; cmd | getline day; close(cmd); {printf day " " $13"\n"}; }' | sed s/}/' '/g >> $datelogfile
sort -r $datelogfile | sort -r -k 2 -k 1 - | uniq -f 1 | sort -r - > $tmpfile
cat $tmpfile > $datelogfile
# Walk each line in $datelogfile
# See if the date > 83 days ago. If it is, send out a password change reminder
cat $datelogfile | awk '{ cmd="date -v-83d +%s"; cmd | getline expire; { if ($1 < expire) print}}' > $tmpfile
cat $tmpfile | awk '{test=$2; cmd = "ldapsearch -x -H ldap://ldap.gruby.com -b cn=users,dc=ldap,dc=gruby,dc=com uid=\047"test"\047 mail"; while ((cmd | getline) > 0) {if ($1=="mail:") {newcmd = "echo \"From: it@gruby.com\nTo: "$2"\nCc: it@gruby.com\nSubject: Password Change Reminder\n\nYour password will expire in less than 7 days. Please visit: to change it.\n\n\nIf you have any questions, please contact it@gruby.com.\n\n\n--\nit@gruby.com\n\" | sendmail -bm -t"; newcmd | getline; close(newcmd); break;}} }'
rm -rf $tmpfile
Apple, please add some polish to the LDAP server; adding a little user interface on OpenLDAP is nice, but it isn’t finished. Building in the password change ability and the reminder system would be a good start. In addition, securing it out of the box by making the “require authenticated binding” setting actually work (I’ve ranted about this in the past; this actually makes it impossible for us to expose our LDAP server to the outside world and use it for integrating outsourced services like Salesforce that will do LDAP authentication to our server.)