Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
Date: 2005-02-04
Initial Package Version: 4.0.7
Upstream Status: Not submitted
Origin: http://www.openwall.com/crypt/contrib/\
        shadow-4.0.3-crypt_blowfish.diff.gz
Description: Adds blowfish passwords to shadow. This depends on a blowfish
library. See:
http://www.openwall.com/crypt/
or
http://ftp.suse.com/pub/people/kukuk/pam/libxcrypt/

If you use libxcrypt you need to do:
sed -e 's/lcrypt/lxcrypt/g' -i configure

There's a hint for this patch here:
http://www.linuxfromscratch.org/hints/downloads/files/blowfish-passwords.txt

diff -Naur shadow-4.0.7.orig/acconfig.h shadow-4.0.7/acconfig.h
--- shadow-4.0.7.orig/acconfig.h	2005-02-04 13:06:12.152309336 +0000
+++ shadow-4.0.7/acconfig.h	2005-02-04 13:31:08.595564424 +0000
@@ -8,6 +8,9 @@
 /* Path for faillog file.  */
 #undef FAILLOG_FILE
 
+/* Defined if you have blowfish crypt.  */
+#undef HAVE_CRYPT_GENSALT
+
 /* Defined if you have libcrack.  */
 #undef HAVE_LIBCRACK
 
@@ -44,6 +47,9 @@
 /* Path to passwd program.  */
 #undef PASSWD_PROGRAM
 
+/* Where is /dev/urandom or a /dev/urandom-alike.  */
+#undef RANDOM_FILE
+
 /* Define if login should support the -r flag for rlogind.  */
 #undef RLOGIN
 
diff -Naur shadow-4.0.7.orig/config.h.in shadow-4.0.7/config.h.in
--- shadow-4.0.7.orig/config.h.in	2005-02-04 13:06:11.841356608 +0000
+++ shadow-4.0.7/config.h.in	2005-02-04 13:31:08.598560968 +0000
@@ -9,6 +9,9 @@
 /* Path for faillog file.  */
 #undef FAILLOG_FILE
 
+/* Defined if you have crypt blowfish.  */
+#undef HAVE_CRYPT_GENSALT
+
 /* Defined if you have libcrack.  */
 #undef HAVE_LIBCRACK
 
@@ -45,6 +48,9 @@
 /* Path to passwd program.  */
 #undef PASSWD_PROGRAM
 
+/* Where is /dev/urandom or a /dev/urandom-alike.  */
+#undef RANDOM_FILE
+
 /* Define if login should support the -r flag for rlogind.  */
 #undef RLOGIN
 
diff -Naur shadow-4.0.7.orig/configure shadow-4.0.7/configure
--- shadow-4.0.7.orig/configure	2005-02-04 13:06:11.857354176 +0000
+++ shadow-4.0.7/configure	2005-02-04 13:31:42.004033480 +0000
@@ -462,7 +462,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LN_S YACC CPP EGREP U ANSI2KNR build build_cpu build_vendor build_os host host_cpu host_vendor host_os ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LIBCRYPT LIBCRACK LIBSKEY LIBMD LIBSELINUX LIBPAM MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LN_S YACC CPP EGREP U ANSI2KNR build build_cpu build_vendor build_os host host_cpu host_vendor host_os ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS RANDOM_FILE LIBCRYPT LIBCRACK LIBSKEY LIBMD LIBSELINUX LIBPAM MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1053,6 +1053,7 @@
   --with-libpam 		use libpam for PAM support
   --with-libskey		use libskey for S/Key support
   --with-selinux		use SELinux support
+  --with-random=FILE	read randomness from FILE (default=/dev/urandom)
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
   --without-libiconv-prefix     don't search for libiconv in includedir and libdir
@@ -1171,8 +1172,6 @@
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
@@ -4512,7 +4511,7 @@
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4515 "configure"' > conftest.$ac_ext
+  echo '#line 4514 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5618,7 +5617,7 @@
 
 
 # Provide some information about the compiler.
-echo "$as_me:5621:" \
+echo "$as_me:5620:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -6675,11 +6674,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6678: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6677: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6682: \$? = $ac_status" >&5
+   echo "$as_me:6681: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -6918,11 +6917,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6921: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6920: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6925: \$? = $ac_status" >&5
+   echo "$as_me:6924: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -6978,11 +6977,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6981: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6980: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:6985: \$? = $ac_status" >&5
+   echo "$as_me:6984: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9178,7 +9177,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9181 "configure"
+#line 9180 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9276,7 +9275,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9279 "configure"
+#line 9278 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11469,11 +11468,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11472: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11471: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11476: \$? = $ac_status" >&5
+   echo "$as_me:11475: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -11529,11 +11528,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11532: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11531: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11536: \$? = $ac_status" >&5
+   echo "$as_me:11535: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -12905,7 +12904,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 12908 "configure"
+#line 12907 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13003,7 +13002,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 13006 "configure"
+#line 13005 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13840,11 +13839,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13843: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13842: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13847: \$? = $ac_status" >&5
+   echo "$as_me:13846: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -13900,11 +13899,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13903: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13902: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13907: \$? = $ac_status" >&5
+   echo "$as_me:13906: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15950,11 +15949,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15953: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15952: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15957: \$? = $ac_status" >&5
+   echo "$as_me:15956: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -16193,11 +16192,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16196: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16195: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16200: \$? = $ac_status" >&5
+   echo "$as_me:16199: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -16253,11 +16252,11 @@
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16256: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16255: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16260: \$? = $ac_status" >&5
+   echo "$as_me:16259: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -18453,7 +18452,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 18456 "configure"
+#line 18455 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18551,7 +18550,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 18554 "configure"
+#line 18553 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -22828,6 +22827,48 @@
 fi;
 
 
+# Check whether --with-random or --without-random was given.
+if test "${with_random+set}" = set; then
+  withval="$with_random"
+   RANDOM_FILE="$withval"
+else
+
+            echo "$as_me:$LINENO: checking for \"/dev/urandom\"" >&5
+echo $ECHO_N "checking for \"/dev/urandom\"... $ECHO_C" >&6
+if test "${ac_cv_file___dev_urandom_+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  test "$cross_compiling" = yes &&
+  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+   { (exit 1); exit 1; }; }
+if test -r ""/dev/urandom""; then
+  ac_cv_file___dev_urandom_=yes
+else
+  ac_cv_file___dev_urandom_=no
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_file___dev_urandom_" >&5
+echo "${ECHO_T}$ac_cv_file___dev_urandom_" >&6
+if test $ac_cv_file___dev_urandom_ = yes; then
+
+              RANDOM_FILE="/dev/urandom";
+
+
+fi
+
+
+
+fi;
+if test -n "$RANDOM_FILE" ; then
+
+      cat >>confdefs.h <<_ACEOF
+#define RANDOM_FILE "$RANDOM_FILE"
+_ACEOF
+
+fi
+
+
 echo "$as_me:$LINENO: checking for library containing inet_ntoa" >&5
 echo $ECHO_N "checking for library containing inet_ntoa... $ECHO_C" >&6
 if test "${ac_cv_search_inet_ntoa+set}" = set; then
@@ -23460,6 +23501,77 @@
  LIBCRYPT=-lcrypt
 fi
 
+	echo "$as_me:$LINENO: checking for crypt_gensalt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt_gensalt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt_gensalt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt_gensalt ();
+int
+main ()
+{
+crypt_gensalt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt_gensalt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_crypt_gensalt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt_gensalt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt_gensalt" >&6
+if test $ac_cv_lib_crypt_crypt_gensalt = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_CRYPT_GENSALT 1
+_ACEOF
+
+fi
+
 fi
 
 
@@ -26787,6 +26899,7 @@
 s,@ac_ct_F77@,$ac_ct_F77,;t t
 s,@LIBTOOL@,$LIBTOOL,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
+s,@RANDOM_FILE@,$RANDOM_FILE,;t t
 s,@LIBCRYPT@,$LIBCRYPT,;t t
 s,@LIBCRACK@,$LIBCRACK,;t t
 s,@LIBSKEY@,$LIBSKEY,;t t
diff -Naur shadow-4.0.7.orig/etc/login.defs.linux shadow-4.0.7/etc/login.defs.linux
--- shadow-4.0.7.orig/etc/login.defs.linux	2005-02-04 13:06:11.878350984 +0000
+++ shadow-4.0.7/etc/login.defs.linux	2005-02-04 13:31:08.605552904 +0000
@@ -260,13 +260,6 @@
 PASS_ALWAYS_WARN	yes
 
 #
-# Number of significant characters in the password for crypt().
-# Default is 8, don't change unless your crypt() is better.
-# Ignored if MD5_CRYPT_ENAB set to "yes".
-#
-#PASS_MAX_LEN		8
-
-#
 # Require password before chfn/chsh can make any changes.
 #
 CHFN_AUTH		yes
@@ -287,14 +280,62 @@
 #LOGIN_STRING		"%s's Password: "
 
 #
-# Only works if compiled with MD5_CRYPT defined:
-# If set to "yes", new passwords will be encrypted using the MD5-based
-# algorithm compatible with the one used by recent releases of FreeBSD.
-# It supports passwords of unlimited length and longer salt strings.
-# Set to "no" if you need to copy encrypted passwords to other systems
-# which don't understand the new algorithm.  Default is "no".
+# Each password entry contains a prefix that specifies the hashing algorithm
+# used to create the remaining characters/bytes. Use this setting to specify
+# which hashing algorithm is used to create new passwords.
+#
+# The default here is to use the Blowfish-based algorithm, (which currently
+# requires you to be running a patched version of glibc). To use the slightly
+# more compatible MD5-based algorithm, you would set this to $1$. To be
+# completely backwards compatible and use the traditional DES-based hashing,
+# you should set this value to an empty string, but be warned, passwords using
+# this algorithm offer very little security.
+#
+CRYPT_PREFIX	"$2a$"
+
+#
+# For hashing algorithms that can alter their complexity, use this setting to
+# achieve a balance between the security of the password and performance on the
+# host system.
+#
+# This value is interpreted by each algorithm in specific ways. With the
+# Blowfish algorithm, it specifies the number of rounds as a base-2 logarithm
+# of the actual iteration count, so 12 actually refers to 2^12. Altering the
+# value to 11 would therefore halve the number of iterations used to 2^11.
+#
+# Make sure that if you alter the above setting, this setting is also
+# appropriate. For algorithms that have fixed iteration counts, or to
+# enforce the use of a low default value, use a setting of 0.
+#
+CRYPT_ROUNDS	12
+
+#
+# All algorithms require varying amounts of random bytes known as salt. For
+# example the DES-based algorithm requires only 12-bits, (1½ bytes), whereas
+# the Blowfish-based algorithm requires 128-bits, (16 bytes).
+#
+# If an algorithm doesn't receive enough salt, more will be collected from
+# /dev/urandom, a byte at a time until it's satisfied. If you know how much
+# is enough to satisfy even the most hungry of algorithms locally available,
+# setting it here will speed up the generation of passwords.
+#
+# A maximum is also provided to enforce an upper limit on this to prevent a
+# wayward algorithm munching all the randomness unnecessarily.
+#
+CRYPT_MINSALT	16
+CRYPT_MAXSALT	32
+
+#
+# Number of significant characters in the password for crypt(). MD5 can
+# effectively cope with unlimited length passwords, but a limit of ~127 is
+# reasonable. Blowfish can handle up to 72 characters, and the DES algorithm
+# can only handle 8.
+#
+# This setting is used in some of the obscure checks, and also to inform the
+# user on how big their new password should be, so it should be set in
+# accordance to the choice of algorithm.
 #
-#MD5_CRYPT_ENAB	no
+PASS_MAX_LEN	72
 
 #
 # List of groups to add to the user's supplementary group set
diff -Naur shadow-4.0.7.orig/lib/getdef.c shadow-4.0.7/lib/getdef.c
--- shadow-4.0.7.orig/lib/getdef.c	2005-02-04 13:06:11.888349464 +0000
+++ shadow-4.0.7/lib/getdef.c	2005-02-04 13:31:08.608549448 +0000
@@ -63,6 +63,12 @@
 	{ "CONSOLE_GROUPS",		NULL },
 	{ "CRACKLIB_DICTPATH",		NULL },
 	{ "CREATE_HOME",		NULL },
+#ifdef HAVE_CRYPT_GENSALT
+	{ "CRYPT_MAXSALT",		NULL },
+	{ "CRYPT_MINSALT",		NULL },
+	{ "CRYPT_PREFIX",		NULL },
+	{ "CRYPT_ROUNDS",		NULL },
+#endif /* HAVE_CRYPT_GENSALT */
 	{ "DEFAULT_HOME",		NULL },
 	{ "ENVIRON_FILE",		NULL },
 	{ "ENV_HZ",			NULL },
@@ -90,7 +96,9 @@
 	{ "MAIL_CHECK_ENAB",		NULL },
 	{ "MAIL_DIR",			NULL },
 	{ "MAIL_FILE",			NULL },
+#ifndef HAVE_CRYPT_GENSALT
 	{ "MD5_CRYPT_ENAB",		NULL },
+#endif /* ! HAVE_CRYPT_GENSALT */
 	{ "MOTD_FILE",			NULL },
 	{ "NOLOGINS_FILE",		NULL },
 	{ "NOLOGIN_STR",		NULL },
diff -Naur shadow-4.0.7.orig/libmisc/obscure.c shadow-4.0.7/libmisc/obscure.c
--- shadow-4.0.7.orig/libmisc/obscure.c	2005-02-04 13:06:11.920344600 +0000
+++ shadow-4.0.7/libmisc/obscure.c	2005-02-04 13:31:08.611545992 +0000
@@ -231,8 +231,10 @@
 	   Example: "password$%^&*123".  So check it again, this time
 	   truncated to the maximum length.  Idea from npasswd.  --marekm */
 
+#ifndef HAVE_CRYPT_GENSALT
 	if (getdef_bool ("MD5_CRYPT_ENAB"))
 		return NULL;	/* unlimited password length */
+#endif
 
 	maxlen = getdef_num ("PASS_MAX_LEN", 8);
 	if (oldlen <= maxlen && newlen <= maxlen)
diff -Naur shadow-4.0.7.orig/libmisc/salt.c shadow-4.0.7/libmisc/salt.c
--- shadow-4.0.7.orig/libmisc/salt.c	2005-02-04 13:06:11.922344296 +0000
+++ shadow-4.0.7/libmisc/salt.c	2005-02-04 13:31:08.613543688 +0000
@@ -3,8 +3,12 @@
  *
  * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
  * public domain.
+ *
+ * Broken by Matt Dainty <madmatt@bits.bris.ac.uk>
  */
 
+#define _OW_SOURCE
+
 #include <config.h>
 
 #include "rcsid.h"
@@ -12,8 +16,97 @@
 #include "prototypes.h"
 #include "defines.h"
 #include <sys/time.h>
-#if 1
+
+#ifdef HAVE_CRYPT_GENSALT
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <crypt.h>
+#include "getdef.h"
+
+/* Soopa-doopa salt generation function. There isn't anything algorithm
+ * specific in here, although it does require the Openwall-patched glibc to
+ * provide the crypt_gensalt() function, as well as make use of Blowfish-based
+ * hashing.
+ *
+ * All parameters can be customised from the /etc/login.defs file
+ *
+ * Written by Matt Dainty <madmatt@bits.bris.ac.uk>
+ */
+char *
+crypt_make_salt(void)
+{
+	char *result, *salt;
+	int fd, offset, minsalt, maxsalt, count;
+
+	minsalt = getdef_num( "CRYPT_MINSALT", 16 );
+	maxsalt = getdef_num( "CRYPT_MAXSALT", 32 );
+
+	if( minsalt > maxsalt ) {
+		fprintf( stderr, "Check the CRYPT_MINSALT and CRYPT_MAXSALT settings!\n" );
+		exit(1);
+	}
+
+	if( ( salt = ( char * ) malloc( maxsalt ) ) == NULL ) {
+		fprintf( stderr, "Can't allocate %d bytes of memory\n", maxsalt );
+		exit(1);
+	}
+
+	if( ( fd = open( RANDOM_FILE, O_RDONLY ) ) < 0 ) {
+		fprintf( stderr, "Can't open %s for reading\n", RANDOM_FILE );
+		free( salt );
+		exit(1);
+	}
+
+	offset = 0;
+	result = NULL;
+
+	while( !result ) {
+		while( offset < minsalt ) {
+			count = read( fd, &salt[offset], minsalt - offset );
+			if( count <= 0 ) {
+				if( errno == EINTR )
+					continue;
+				goto finish;
+			}
+			offset += count;
+		}
+		result = crypt_gensalt( getdef_str( "CRYPT_PREFIX" ),
+					getdef_num( "CRYPT_ROUNDS", 0 ),
+					salt, minsalt );
+
+		if( !result && errno == EINVAL ) {
+			if( minsalt < maxsalt ) {
+				minsalt++;
+			} else {
+				fprintf( stderr, "CRYPT_PREFIX or CRYPT_ROUNDS is set incorrectly\n" );
+				goto finish;
+			}
+		}
+	}
+
+finish:
+	if( salt )
+		free( salt );
+	if( fd )
+		close( fd );
+
+	/* XXX	If we return the salt string as NULL, crypt will currently
+	 * 	segfault, so if have we a NULL salt string, exit here.
+	 * 	Otherwise, every invocation of crypt_make_salt() will have to
+	 * 	check for a NULL return value.
+	 *
+	 * 	This way, I don't muck up any more code! :-)
+	 */
+	if( result )
+		return result;
+
+	exit(1);
+}
+#elif 1 /* HAVE_CRYPT_GENSALT */
 #include "getdef.h"
+
 extern char *l64a ();
 
 /*
diff -Naur shadow-4.0.7.orig/src/passwd.c shadow-4.0.7/src/passwd.c
--- shadow-4.0.7.orig/src/passwd.c	2005-02-04 13:06:12.145310400 +0000
+++ shadow-4.0.7/src/passwd.c	2005-02-04 13:31:08.617539080 +0000
@@ -240,9 +240,11 @@
 	 * for initial login passwords.
 	 */
 
+#ifndef HAVE_CRYPT_GENSALT	    
 	if (getdef_bool ("MD5_CRYPT_ENAB"))
 		pass_max_len = 127;
 	else
+#endif
 		pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
 
 	if (!qflg)
