Added support for SHA512 format passwords, created common function to validate a...
authorJamie Cameron <jcameron@webmin.com>
Sat, 12 Feb 2011 00:20:02 +0000 (16:20 -0800)
committerJamie Cameron <jcameron@webmin.com>
Sat, 12 Feb 2011 00:20:02 +0000 (16:20 -0800)
21 files changed:
cluster-passwd/save_passwd.cgi
passwd/save_passwd.cgi
useradmin/CHANGELOG
useradmin/config.info
useradmin/config.info.ca
useradmin/config.info.cz
useradmin/config.info.da
useradmin/config.info.de
useradmin/config.info.es
useradmin/config.info.fa
useradmin/config.info.fr
useradmin/config.info.ja_JP.UTF-8
useradmin/config.info.ja_JP.euc
useradmin/config.info.nl
useradmin/config.info.pt_BR
useradmin/config.info.tr
useradmin/edit_user.cgi
useradmin/lang/en
useradmin/linux-lib.pl
useradmin/md5-lib.pl
useradmin/user-lib.pl

index a9c2cd0..13b04e5 100755 (executable)
@@ -15,9 +15,7 @@ $user || &error($passwd::text{'passwd_euser'});
 # Validate inputs
 if ($access{'old'} == 1 ||
     $access{'old'} == 2 && $user->{'user'} ne $remote_user) {
-       &unix_crypt($in{'old'}, $user->{'pass'}) eq $user->{'pass'} ||
-          &useradmin::encrypt_password($in{'old'}, $user->{'pass'}) eq
-          $user->{'pass'} ||
+       &useradmin::validate_password($in{'old'}, $user->{'pass'}) ||
                &error($passwd::text{'passwd_eold'});
        }
 if ($access{'repeat'}) {
index b3b4cc1..569c222 100755 (executable)
@@ -60,17 +60,8 @@ else {
                # Validate inputs
                if ($access{'old'} == 1 ||
                    $access{'old'} == 2 && $user->{'user'} ne $remote_user) {
-                       $chash = undef;
-                       eval {
-                               # May fail if crypt is broken
-                               local $main::error_must_die = 1;
-                               $chash = &unix_crypt($in{'old'},
-                                                    $user->{'pass'});
-                               };
-                       $md5hash = &useradmin::encrypt_password(
-                                          $in{'old'}, $user->{'pass'});
-                       $chash eq $user->{'pass'} ||
-                          $md5hash eq $user->{'pass'} ||
+                       &useradmin::validate_password(
+                           $in{'old'}, $user->{'pass'}) ||
                                &error($text{'passwd_eold'});
                        }
                if ($access{'repeat'}) {
index d0d862f..c9d29e6 100644 (file)
@@ -62,3 +62,5 @@ Fixed the hashing format for Blowfish passwords, to put $2a$ at the start instea
 On Linux systems with SElinux enabled, the context user_u:object_r:user_home_dir_t is set on new home directories by default.
 ---- Changes since 1.510 ----
 When deleting a user's personal group and user deletion in other modules is enabled, delete the group in other modules too.
+---- Changes since 1.530 ----
+Added support for SHA512 format passwords.
index 2863378..dd21621 100644 (file)
@@ -15,7 +15,7 @@ uid_calc=UID Calculation Method,4,0-Berkeley cksum,1-Custom mkuid program
 gid_calc=GID Calculation Method,4,0-Berkeley cksum,1-Custom mkgid program
 new_user_group=Create new group for new users?,1,1-Yes,0-No
 new_user_gid=Assign same ID to new user and group?,1,1-Yes,0-No
-md5=Password encryption method,1,2-MD5,1-Determine automatically,0-DES crypt,3-Blowfish
+md5=Password encryption method,1,1-Determine automatically,0-DES crypt,2-MD5,3-Blowfish,4-SHA512
 alias_check=Check for sendmail alias clashes?,1,1-Yes,0-No
 delete_only=Only delete files owned by user?,1,1-Yes,0-No
 max_length=Maximum user and group name length,3,Unlimited
index d01c5da..21b23dc 100644 (file)
@@ -15,7 +15,7 @@ uid_calc=M
 gid_calc=Mètode de càlcul del GID,4,0-Suma de comprovació Berkeley,1-Programa mkgid personalitzat
 new_user_group=Crea un grup nou per als usuaris nous,1,1-Sí,0-No
 new_user_gid=Assigna el mateix al nou usuari i al grup,1,1-Sí,0-No
-md5=Mètode de xifratge de contrasenyes,1,2-MD5,1-Determinat automàticament,0-DES crypt,3-Blowfish
+md5=Mètode de xifratge de contrasenyes,1,1-Determinat automàticament,0-DES crypt,2-MD5,3-Blowfish
 alias_check=Comprova duplicats amb els àlies de sendmail,1,1-Sí,0-No
 delete_only=Esborra només els fitxers propietat de l'usuari,1,1-Sí,0-No
 max_length=Llargària màxima dels noms d'usuaris i grups,3,Il·limitada
index 484d6c1..847f226 100644 (file)
@@ -13,7 +13,7 @@ uid_calc=Metoda v
 gid_calc=Metoda výpoètu GID,4,0-Berkeley cksum,1-Náhodný program mkgid
 new_user_group=Vytvoøit novou skupinu pro nové u¾ivatele?,1,1-ano,0-ne
 new_user_gid=Pøidìlit stejné ID pro nového u¾ivatele i skupinu?,1,1-ano,0-ne
-md5=Metoda kryptování hesla,1,2-MD5,1-Automatické zji¹tìní,0-DES crypt
+md5=Metoda kryptování hesla,1,1-Automatické zji¹tìní,0-DES crypt,2-MD5
 alias_check=Kontrolovat kolize v sendmail aliasech?,1,1-ano,0-ne
 delete_only=Smazat pouze soubory vlastnìné u¾ivatelem?,1,1-ano,0-ne
 max_length=Maximální délka jmen u¾ivatele a skupiny,3,Neomezeno
index 20d5d28..569659a 100644 (file)
@@ -16,7 +16,7 @@ uid_calc=UID beregningsmetode,4,0-Berkeley cksum,1-Brugerdefineret mkuid program
 gid_calc=GID beregningsmetode,4,0-Berkelet cksum,1-Brugerdefineret mkgid program
 new_user_group=Opret ny gruppe for ny brugere,1,1-Ja,0-Nej
 new_user_gid=Tildel samme ID til ny bruger og gruppe?,1,1-Ja,0-Nej
-md5=Adgangskode krypteringsmetode,1,2-MD5,1-Bestem automatisk,0-DES crypt
+md5=Adgangskode krypteringsmetode,1,1-Bestem automatisk,0-DES crypt,2-MD5
 alias_check=Tjek for sendmail alias konflikter?,1,1-Ja,0-Nej
 delete_only=Slet kun filer ejet af bruger?,1,1-Ja,0-Nej
 max_length=Maksimum bruger og gurppe navnel&#230;ngde,3,Ubegr&#230;nset
index 63f2aab..826a2e8 100644 (file)
@@ -15,7 +15,7 @@ uid_calc=User-ID Errechnungsmethode,4,0-Berkeley chksum,1-Benutzerdefiniertes mk
 gid_calc=Gruppen-ID Errechnungsmethode,4,0-Berkeley chksum,1-Benutzerdefiniertes mkgid Programm
 new_user_group=Eine Gruppe f&#252;r neue Benutzer anlegen?,1,1-Ja,0-Nein
 new_user_gid=Gleiche ID f&#252;r Benutzer und Gruppe?,1,1-Ja,0-Nein
-md5=Passwortverschl&#252;sselungsmethode,1,2-MD5,1-Automatisch ermitteln,0-DES crypt
+md5=Passwortverschl&#252;sselungsmethode,1,1-Automatisch ermitteln,0-DES crypt,2-MD5
 alias_check=&#220;berpr&#252;fe auf vorhandene Sendmail-Aliase?,1,1-Ja,0-Nein
 delete_only=Nur Dateien l&#246;schen<code>&#44;</code> die dem Benutzer geh&#246;ren?,1,1-Ja,0-Nein
 max_length=Maximale L&#228;nge von Benutzer- und Gruppennamen,3,Unbegrenzt
index cfea9e7..6739a99 100644 (file)
@@ -16,7 +16,7 @@ uid_calc=M&#233;todo de c&#225;lculo de UID,4,0-Cksum de Berkeley,1-Programa per
 gid_calc=M&#233;todo de c&#225;lculo de GID,4,0-Cksum de Berkeley,1-Programa mkgid personalizado
 new_user_group=&#191;Crear nuevo grupo para nuevos usuarios?,1,1-S&#237;,0-No
 new_user_gid=&#191;Asignar el mismo ID a nuevo usuario y grupo?,1,1-S&#237;,0-No
-md5=M&#233;todo de encriptaci&#243;n de contrase&#241;a,1,2-MD5,1-Determinar autom&#225;ticamente,0-Encriptaci&#243;n DES
+md5=M&#233;todo de encriptaci&#243;n de contrase&#241;a,1,1-Determinar autom&#225;ticamente,0-Encriptaci&#243;n DES,2-MD5
 alias_check=&#191;Revisar para evitar choques de alias de sendmail?,1,1-S&#237;,0-No
 delete_only=&#191;S&#243;lo borrar archivos pertenecientes al usuario?,1,1-S&#237;,0-No
 max_length=Tama&#241;o m&#225;ximo de nombre de usuario y grupo,3,Ilimitada
index 6bdeceb..627e19e 100644 (file)
@@ -18,7 +18,7 @@ uid_calc=روش محاسبه شناسه کاربر,4,0-Berkeley cksum,1-برنا
 gid_calc=روش محاسبه شناسه گروه,4,0-Berkeley cksum,1-برنامه سفارشي mkgid\r
 new_user_group=آيا براي کاربران جديد گروه جديدي ايجاد شود؟,1,1-بله,0-خير\r
 new_user_gid=آيا به کاربر و گروه جديد شناسه يکسان اختصاص يابد؟,1,1-بله,0-خير\r
-md5=روش رمزگذاري اسم‌رمز,1,2-MD5,1-به‌طور خودکار انتخاب شود,0-DES crypt\r
+md5=روش رمزگذاري اسم‌رمز,1,1-به‌طور خودکار انتخاب شود,0-DES crypt,2-MD5
 alias_check=آيا يکسان بودن با اسم مستعار sendmail بررسي شود؟,1,1-بله,0-خير\r
 delete_only=آيا فقط پرونده‌هاي ايجاد شده توسط کاربر حذف شوند؟,1,1-بله,0-خير\r
 max_length=بيشينه طول اسم‌کاربر و گروه,3,نامحدود\r
index d43020d..2abcf87 100644 (file)
Binary files a/useradmin/config.info.fr and b/useradmin/config.info.fr differ
index 3863d32..5bb72d1 100644 (file)
@@ -14,7 +14,7 @@ uid_calc=UID計算方法,4,0-バークレイ cksum,1-カスタムmkuidプログ
 gid_calc=GID計算方法,4,0-バークレイ cksum,1-カスタムmkgidプログラム
 new_user_group=新しいユーザ用に新しいグループを作成しますか?,1,1-はい,0-いいえ
 new_user_gid=新しいユーザとグループに同じIDを割り当てますか?,1,1-はい,0-いいえ
-md5=パスワードの暗号化方法,1,2-MD5,1-自動選択,0-DES暗号
+md5=パスワードの暗号化方法,1,1-自動選択,0-DES暗号,2-MD5
 alias_check=sendmailのエイリアスと重複するかどうかをチェックしますか?,1,1-はい,0-いいえ
 delete_only=ユーザが所有するファイルだけを削除しますか?,1,1-はい,0-いいえ
 max_length=ユーザ及びグループ名の最大長,3,無制限
index 6e6722a..38e3777 100644 (file)
@@ -14,7 +14,7 @@ uid_calc=UID
 gid_calc=GID·×»»ÊýË¡,4,0-¥Ð¡¼¥¯¥ì¥¤ cksum,1-¥«¥¹¥¿¥àmkgid¥×¥í¥°¥é¥à
 new_user_group=¿·¤·¤¤¥æ¡¼¥¶ÍѤ˿·¤·¤¤¥°¥ë¡¼¥×¤òºîÀ®¤·¤Þ¤¹¤«?,1,1-¤Ï¤¤,0-¤¤¤¤¤¨
 new_user_gid=¿·¤·¤¤¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤ËƱ¤¸ID¤ò³ä¤êÅö¤Æ¤Þ¤¹¤«?,1,1-¤Ï¤¤,0-¤¤¤¤¤¨
-md5=¥Ñ¥¹¥ï¡¼¥É¤Î°Å¹æ²½ÊýË¡,1,2-MD5,1-¼«Æ°ÁªÂò,0-DES°Å¹æ
+md5=¥Ñ¥¹¥ï¡¼¥É¤Î°Å¹æ²½ÊýË¡,1,1-¼«Æ°ÁªÂò,0-DES°Å¹æ,2-MD5
 alias_check=sendmail¤Î¥¨¥¤¥ê¥¢¥¹¤È½ÅÊ£¤¹¤ë¤«¤É¤¦¤«¤ò¥Á¥§¥Ã¥¯¤·¤Þ¤¹¤«?,1,1-¤Ï¤¤,0-¤¤¤¤¤¨
 delete_only=¥æ¡¼¥¶¤¬½êÍ­¤¹¤ë¥Õ¥¡¥¤¥ë¤À¤±¤òºï½ü¤·¤Þ¤¹¤«?,1,1-¤Ï¤¤,0-¤¤¤¤¤¨
 max_length=¥æ¡¼¥¶µÚ¤Ó¥°¥ë¡¼¥×̾¤ÎºÇÂçĹ,3,̵À©¸Â
index d4f0ba4..ca7c06a 100644 (file)
@@ -14,7 +14,7 @@ uid_calc=UID bereken methoden,4,0-Berkeley cksum,1-Eigen mkuid programma
 gid_calc=GID bereken methoden,4,0-Berkeley cksum,1-Eigen mkgid programma
 new_user_group=Maak nieuwe groep voor nieuwe gebruikers?,1,1-Ja,0-Nee
 new_user_gid=Zelfde ID toewijzen aan nieuwe gebruiker en groep?,1,1-Ja,0-Nee
-md5=Wachtwoord versleutel methoden,1,2-MD5,1-Bepaal  automatisch,0-DES crypt,3-Blowfish
+md5=Wachtwoord versleutel methoden,1,1-Bepaal  automatisch,0-DES crypt,2-MD5,3-Blowfish
 alias_check=Controleer op conflict met Sendmail alias,1,1-Ja,0-Nee
 delete_only=Alleen bestanden verwijderen die van de gebruiker zijn?,1,1-Ja,0-Nee
 max_length=Maximum gebruiker en groepen naam lengte,3,Ongelimiteerd
index 28b0719..b9ffaba 100644 (file)
@@ -34,7 +34,7 @@ gid_mode=M
 uid_calc=Método de cálculo de UID,4,0-Berkeley cksum,1-Programa mkuid personalizado
 gid_calc=Método de cálculo de GID,4,0-Berkeley cksum,1-Programa mkuid personalizado
 new_user_gid=Atribuir a mesma ID a novo usuário e grupo?,1,1-Sim,0-Não
-md5=Método de criptografia da senha,1,2-MD5,1-Determinado automaticamente,0-DES crypt,3-Blowfish
+md5=Método de criptografia da senha,1,1-Determinado automaticamente,0-DES crypt,2-MD5,3-Blowfish
 max_length=Tamanho máximo de nome de usuário e grupo,3,Ilimitado
 username_re=Expressão regular Perl para verificar o nome de usuário,3,Nenhuma
 shells=Gerar lista de shells baseado em,2,fixed-Lista incluida,passwd-Usuários existentes,shells-/etc/shells
index 90b7785..be5f022 100644 (file)
@@ -15,7 +15,7 @@ uid_calc=UID Hesaplama Metodu,4,0-Berkeley cksum,1-
 gid_calc=GID Hesaplama Metodu,4,0-Berkeley cksum,1-Özel mkgid programý
 new_user_group=Yeni kullanýcýlar için yeni grup oluþturulsun mu?,1,1-Evet,0-Hayýr
 new_user_gid=Ayný ID kullanýcý ve gruba atansýn mý?,1,1-Evet,0-Hayýr
-md5=Parola þifreleme metodu,1,2-MD5,1-Otomatik olarak bul,0-DES crypt
+md5=Parola þifreleme metodu,1,1-Otomatik olarak bul,0-DES crypt,2-MD5
 delete_only=Sadece kullanýcýnýn sahibi olduðu dosyalar silinsin?,1,1-Evet,0-Hayýr
 max_length=Maksimum kullanýcý ve grup adý uzunluðu,3,Limitsiz
 username_re=Kullanýcý adlarýnýn kontrol edileceði Perl düzenli ifades,3,Yok
index 0a66466..c6708ca 100755 (executable)
@@ -201,7 +201,7 @@ print &ui_table_row(&hlink($text{'pass'}, "pass"),
                ( [ 2, $text{'nochange'},
                    &ui_hidden("encpass", $pass) ] ) :
                ( [ 2, $text{'encrypted'},
-                   &ui_textbox("encpass", $passmode == 2 ? $pass : "", 40) ] )
+                   &ui_textbox("encpass", $passmode == 2 ? $pass : "", 60) ] )
          ]).
          ($can_disable ? "&nbsp;&nbsp;".&ui_checkbox("disable", 1,
                                $text{'uedit_disabled'}, $disabled) : "")
index 436820d..7486a2e 100644 (file)
@@ -169,6 +169,7 @@ usave_eworkph=Work phone cannot contain a : character
 usave_ehomeph=Home phone cannot contain a : character
 usave_edigestmd5=Your system has MD5 passwords enabled, but the Perl <tt>$3</tt> module is not installed.<p>To force the use of normal encrypted passwords, adjust your <a href='$1'>module configuration</a>.<p>Or have Webmin <a href='$2'>download and install</a> the <tt>$3</tt> module for you.
 usave_edigestblowfish=Your system has Blowfish passwords enabled, but the Perl <tt>$3</tt> module is not installed.<p>To force the use of normal encrypted passwords, adjust your <a href='$1'>module configuration</a>.<p>Or have Webmin <a href='$2'>download and install</a> the <tt>$3</tt> module for you.
+usave_edigestsha512=Your system has Blowfish passwords enabled, but the <tt>crypt</tt> function does not support this format.
 usave_emaking=Before update command failed : $1
 usave_epasswd_min=Password must be at least $1 letters long
 usave_epasswd_re=Password does not match regexp $1
index 218a3d1..4fef69c 100755 (executable)
@@ -60,7 +60,7 @@ return @rv;
 }
 
 # use_md5()
-# Returns 1 if pam is set up to use MD5 encryption
+# Returns 1 if pam is set up to use MD5 encryption, 2 for blowfish, 3 for SHA512
 sub use_md5
 {
 if (defined($use_md5_cache)) {
@@ -79,6 +79,12 @@ if (&foreign_check("pam")) {
                        if ($m->{'args'} =~ /md5/) {
                                $md5 = 1;
                                }
+                       elsif ($m->{'args'} =~ /sha512/) {
+                               $md5 = 3;
+                               }
+                       elsif ($m->{'args'} =~ /blowfish/) {
+                               $md5 = 2;
+                               }
                        elsif ($m->{'module'} =~ /pam_stack\.so/ &&
                               $m->{'args'} =~ /service=(\S+)/) {
                                # Referred to another service!
@@ -102,11 +108,24 @@ if (&foreign_check("pam")) {
                        }
                }
        }
-elsif (&open_readfile(PAM, "/etc/pam.d/passwd")) {
+if (!$md5 && &open_readfile(PAM, "/etc/pam.d/passwd")) {
        # Otherwise try to check the PAM file directly
        while(<PAM>) {
                s/#.*$//g;
-               $md5 = 1 if (/^password.*md5/);
+               if (/^password.*md5/) { $md5 = 1; }
+               elsif (/^password.*blowfish/) { $md5 = 2; }
+               elsif (/^password.*sha512/) { $md5 = 3; }
+               }
+       close(PAM);
+       }
+if (!$md5 && (&open_readfile(PAM, "/etc/pam.d/common-password") ||
+             &open_readfile(PAM, "/etc/pam.d/system-auth"))) {
+       # Then try reading common password config file
+       while(<PAM>) {
+               s/#.*$//g;
+               if (/^password.*md5/) { $md5 = 1; }
+               elsif (/^password.*blowfish/) { $md5 = 2; }
+               elsif (/^password.*sha512/) { $md5 = 3; }
                }
        close(PAM);
        }
index 7b1a639..faba73e 100755 (executable)
@@ -38,7 +38,7 @@ $salt ||= substr(time(), -8);
 
 # Use built-in crypt support for MD5, if we can
 if (&unix_crypt_supports_md5()) {
-       return &unix_crypt($passwd, $magic.$salt.'$xxxxxxxxxxxxxxxxxxxxxx');
+       return crypt($passwd, $magic.$salt.'$xxxxxxxxxxxxxxxxxxxxxx');
        }
 
 # Add the password, magic and salt
@@ -113,8 +113,9 @@ return $rv;
 # Returns 1 if the built-in crypt() function can already do MD5
 sub unix_crypt_supports_md5
 {
-return &unix_crypt('test', '$1$A9wB3O18$zaZgqrEmb9VNltWTL454R/') eq
-       '$1$A9wB3O18$zaZgqrEmb9VNltWTL454R/';
+my $hash = '$1$A9wB3O18$zaZgqrEmb9VNltWTL454R/';
+my $newhash = eval { crypt('test', $hash) };
+return $newhash eq $hash;
 }
 
 @itoa64 = split(//, "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
@@ -184,5 +185,30 @@ if (!$salt) {
 return Crypt::Eksblowfish::Bcrypt::bcrypt($passwd, $salt);
 }
 
+# unix_crypt_supports_sha512()
+# Returns 1 if the built-in crypt() function can already do SHA512
+sub unix_crypt_supports_sha512
+{
+my $hash = '$6$Tk5o/GEE$zjvXhYf/dr5M7/jan3pgunkNrAsKmQO9r5O8sr/Cr1hFOLkWmsH4iE9hhqdmHwXd5Pzm4ubBWTEjtMeC.h5qv1';
+my $newhash = eval { crypt('test', $hash) };
+return $newhash eq $hash;
+}
+
+# check_sha512()
+# Returns undef if SHA512 hashing is supported, or an error message if not
+sub check_sha512
+{
+return &unix_crypt_supports_sha512() ? undef : 'Crypt::SHA';
+}
+
+# encrypt_sha512(password, [salt])
+# Hashes a password, possibly with the give salt, with SHA512
+sub encrypt_sha512
+{
+local ($passwd, $salt) = @_;
+$salt ||= '$6$'.substr(time(), -8).'$';
+return crypt($passwd, $salt);
+}
+
 1;
 
index a85fca8..bab7bae 100755 (executable)
@@ -1769,6 +1769,10 @@ elsif ($config{'md5'} == 3) {
        # Always use blowfish
        $format = 2;
        }
+elsif ($config{'md5'} == 4) {
+       # Always use SHA512
+       $format = 3;
+       }
 elsif ($config{'md5'} == 1 && !$config{'skip_md5'}) {
        # Up to system
        $format = &use_md5() if (defined(&use_md5));
@@ -1798,6 +1802,14 @@ elsif ($format == 2) {
                }
        return &encrypt_blowfish($pass, $salt);
        }
+elsif ($format == 3) {
+       # SHA512 is selected .. use it
+       local $err = &check_sha512();
+       if ($err) {
+               &error($text{'usave_edigestsha512'});
+               }
+       return &encrypt_sha512($pass, $salt);
+       }
 else {
        # Just do old-style crypt() DES encryption
        if ($salt !~ /^[a-z0-9]{2}/i) {
@@ -1809,6 +1821,45 @@ else {
        }
 }
 
+# validate_password(password, hash)
+# Compares a password with a hash to see if they match, returns 1 if so,
+# 0 otherwise. Tries all supported hashing schemes.
+sub validate_password
+{
+local ($passwd, $hash) = @_;
+
+# Classic Unix crypt
+local $chash = eval {
+       local $main::error_must_die = 1;
+       &unix_crypt($passwd, $hash);
+       };
+return 1 if ($chash eq $hash);
+
+# MD5
+if (!&check_md5()) {
+       local $mhash = &encrypt_md5($passwd, $hash);
+       return 1 if ($mhash eq $hash);
+       }
+
+# Blowfish
+if (!&check_blowfish()) {
+       local $mhash = &encrypt_blowfish($passwd, $hash);
+       return 1 if ($mhash eq $hash);
+       }
+
+# SHA1
+if (!&check_sha512()) {
+       local $shash = &encrypt_sha512($passwd, $hash);
+       return 1 if ($shash eq $hash);
+       }
+
+# Some other hashing, maybe supported by crypt
+local $ohash = eval { crypt($passwd, $hash) };
+return 1 if ($ohash eq $hash);
+
+return 0;
+}
+
 =head2 build_user_used([&uid-hash], [&shell-list], [&username-hash])
 
 Fills in hashes with used UIDs, shells and usernames, based on existing users.