I’ve got some machines which authenticate their local users against OpenLDAP, and I wanted to reset some passwords from a Perl script.
First I tried just calling modify from Net::LDAP. That worked but just set the new password as plain text. My passwords appear to be “md5crypt”, and normally look like this:
{CRYPT}$1$fywXcrPC$Uakrx8POGBf1WM9l6mkG6/
I could come up with some code to create the correct hash on the machine where I was running the Perl script, but I really wanted the LDAP server to do it for me, for consistency.
A little bit of searching revealed Net::LDAP::Extension::SetPassword, so I gave that a go. Well, that was progress, but it set MD5 passwords. They look like this:
{MD5}13dmpYRmooMYt50wdZBpSQ==
Why did it just decide to use MD5? The answer’s in the OpenLDAP FAQ. password-hash was indeed set to {md5} on the server.
Right, OK, so set password-hash to {md5crypt} then? No! It does not accept that value. It does accept {crypt}, but that ends up like:
{CRYPT}Q.nfbCdTMBuGU
It seems to have the right hash type ({CRYPT}) but it’s much shorter. It’s the POSIX crypt(3) based on DES. Not quite what I wanted.
The eventual answer was found in the archives of the openldap-software mailing list from almost 8 years ago! So once slapd.conf contained:
password-hash {CRYPT} password-crypt-salt-format "$1$%.8s"
the correct password hash was generated.
How did I know about the “.8” bit? In an md5crypt hash, the characters between the $1$ and the next $ are the salt, and there’s 8 of them, so that’s why .8s.