Migrate user accounts from OpenLDAP to unix system user

At the moment I want to get rid of an OpenLDAP instance wich is only used to authenticate users on a single host by now. I want to take all user accounts and store them as Unix user accounts in /etc/passwd, /etc/shadow and /etc/group. The only problem is the userPassword field. The passwords in OpenLDAP are hashed with the SSHA algorithm, which means Salted SHA-1. They look like "{SSHA}Nxs1gQ299W/QPXoRwW9kDZfaPpLApSWP", which is the Base64 encoded hash and salt.

SHA-1, and especially salted SHA-1, aren't supported by Linux's crypt. So while I can migrate the user names, uid, gid, homeDirectory and unixShell I am not able to migrate the user's passwords. That is very bad.

Fortunately, PAM and pam_exec.so exists! pam_exec calls a user-defined program that can do it's own verification routine. So I wrote a little Python script that looks into the system's shadow file and if the user's password hash starts with '{SSHA}' tries to verify it using the SSHA algorithm:

https://gist.github.com/Cybso/2016e4de9a2465cef920

Store this script under /usr/local/sbin/verify_ssha_passwd, make it executable and change the /etc/pam.d/common-auth from:

auth [success=1 default=ignore] pam_unix.so nullok_secure
auth requisite pam_deny.so

to

auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_exec.so expose_authtok /usr/local/sbin/verify_ssha_passwd
auth requisite pam_deny.so

This will call verify_ssha_passwd if and only if pam_unix.so fails to verify the password on its own.

When the password has been verified successfully this program will call 'passwd' to update the password to the system's default format. This means that this program will make itself obsolete over time.

Security considerations:

This script might be vulnerable to timing attacks, so don't use it in critical environments. Also it doesn't respect the additional shadow fields like 'maximum password age' and 'account expiration date'! If your security setup relies on these fields this script is not for you!