I need to migrate legacy directory-like Mysql data to a new ldap database. Not much hassle except for the passwords. They are stored as sha1 in the Mysql database (I checked I can generate them by typing "echo -n "cleartextpassword" | openssl dgst -sha1").

The problem is I fail to import them in our openldap server.

I'm afraid there might be 2 problems here.

First an encryption / encoding problem: is this sha1 encoding usable as such in ldap at all?

An interface problem: when I use ldapadd or ldapmodify to enter/update the userPassword field, the data provided in the ldif file is re-encrypted. Is it possible to somehow bypass this problem ?

Thanks in advance


I finally got it, after a lot of trials.

The sha1 strings I have are so-called hex-digest. To get them into openldap, I first need to convert them back to binary sha1 digest and then base64 encode them.

On the command line one could do that with:

echo -n "sha1-hex-digest" | xxd -r -p | openssl enc -base64

Then the resulting string should be inserted in the ldif file this way:

userPassword: {SHA}base-64-blurb

For those interested, this could be done in Python this way:

import base64
import binascii

sha1_pwd = "your-sha1-hex-digest-here"
ldap_pwd = base64.b64encode(binascii.unhexlify(sha1_pwd)).decode('utf-8')
print("userPassword: {SHA}%s" % ldap_pwd)

In my case, I wanted the crypt salted SHA-512 algorithm hashes from the linux user accounts to be imported. So I found (Answer) What are {CRYPT} passwords and how do I generate them? which has more detail, but basically all you have to do is prepend {CRYPT} before the usual hash that looks like $6$salthere$base64hashhere.

At that link they say to use some perl libs to generate a hash. You don't need to do any of the commands in there to generate anything except to test. (but you'd use ldapmodifyuser or another ldif based command, which they don't mention, to actually import the password). But it's useful for seeing the right syntax ($1$salt... which is md5crypt):

$ perl -e 'use Crypt::PasswdMD5;print("userPassword: {CRYPT}".unix_md5_crypt("password","salt")."\n");'
userPassword: {CRYPT}$1$salt$qJH7.N4xYta3aEG/dfqo/0

But the right algorithm wasn't available (which is sha512crypt which looks like $6$salt...). there is a perl-crypt-passwdmd5 package but no sha2 or sha512, so I tested it using mkpasswd instead:

$ mkpasswd -S "saltsalt" -m SHA-512 secret

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.