Submitted By:            Randy McMurchy (randy_at_linuxfromscratch_dot_org)
Date:                    2005-07-23
Initial Package Version: 2.8.3
Upstream Status:         Pending Submission
Origin:                  Randy McMurchy and
                         ftp://ftp.pdc.kth.se/pub/krb/src/cracklib.patch 
Description:             Patches Cracklib to work with Heimdal Kerberos 5 by
                         creating a separate library (libcrack_heimdal.[so,a]
                         and header files; requires patching the Heimdal
                         source code as well.

$LastChangedBy: bdubbs $
$Date: 2005-08-01 13:29:19 -0600 (Mon, 01 Aug 2005) $


diff -Naur cracklib-2.8.3-orig/Makefile.in cracklib-2.8.3/Makefile.in
--- cracklib-2.8.3-orig/Makefile.in	2005-04-12 02:13:14.000000000 +0000
+++ cracklib-2.8.3/Makefile.in	2005-07-23 19:00:05.000000000 +0000
@@ -133,7 +133,7 @@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-SUBDIRS = lib util doc
+SUBDIRS = lib lib_heimdal util doc
 
 EXTRA_DIST = \
 		autogen.sh \

diff -Naur cracklib-2.8.3-orig/configure cracklib-2.8.3/configure
--- cracklib-2.8.3-orig/configure	2005-04-12 02:13:16.000000000 +0000
+++ cracklib-2.8.3/configure	2005-07-23 19:00:05.000000000 +0000
@@ -426,6 +426,7 @@
 PACKAGE_BUGREPORT=
 
 ac_unique_file="lib/crack.h"
+ac_unique_file="lib_heimdal/crack_heimdal.h"
 # Factoring default headers for most tests.
 ac_includes_default="\
 #include <stdio.h>
@@ -22616,7 +22617,7 @@
 done
 
 
-                                                  ac_config_files="$ac_config_files util/Makefile lib/Makefile doc/Makefile Makefile cracklib.spec"
+                                                  ac_config_files="$ac_config_files util/Makefile lib/Makefile lib_heimdal/Makefile doc/Makefile Makefile cracklib.spec"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure

diff -Naur cracklib-2.8.3-orig/lib_heimdal/Makefile.am cracklib-2.8.3/lib_heimdal/Makefile.am
--- cracklib-2.8.3-orig/lib_heimdal/Makefile.am	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/Makefile.am	2005-07-23 19:00:05.000000000 +0000
@@ -0,0 +1,19 @@
+lib_heimdal_LTLIBRARIES = libcrack_heimdal.la
+
+include_HEADERS = crack_heimdal.h packer_heimdal.h
+
+libcrack_heimdal_la_SOURCES = 	fascist.c \
+			packlib.c \
+			rules.c \
+			stringlib.c \
+			packer_heimdal.h \
+			crack_heimdal.h 
+
+#
+# For initial release, use 10:0:8 to get 2.8.0
+# For next ABI changing release, use 3:0:0
+# After that, follow the libtool recommended incrementing procedure
+#
+libcrack_heimdal_la_LDFLAGS = -version-info 10:0:8
+
+AM_CPPFLAGS = -I. -I.. -I$(top_srcdir)/lib -DIN_CRACKLIB_HEIMDAL '-DDEFAULT_CRACKLIB_DICT="$(pkgdatadir)/pw_dict"'

diff -Naur cracklib-2.8.3-orig/lib_heimdal/Makefile.in cracklib-2.8.3/lib_heimdal/Makefile.in
--- cracklib-2.8.3-orig/lib_heimdal/Makefile.in	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/Makefile.in	2005-07-23 19:00:05.000000000 +0000
@@ -0,0 +1,478 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+lib_heimdal_LTLIBRARIES = libcrack_heimdal.la
+
+include_HEADERS = crack_heimdal.h packer_heimdal.h
+
+libcrack_la_SOURCES = fascist.c \
+			packlib.c \
+			rules.c \
+			stringlib.c \
+			packer_heimdal.h \
+			crack_heimdal.h 
+
+
+#
+# For initial release, use 10:0:8 to get 2.8.0
+# For next ABI changing release, use 3:0:0
+# After that, follow the libtool recommended incrementing procedure
+#
+libcrack_heimdal_la_LDFLAGS = -version-info 10:0:8
+
+AM_CPPFLAGS = -I. -I.. -I$(top_srcdir)/lib -DIN_CRACKLIB_HEIMDAL '-DDEFAULT_CRACKLIB_DICT="$(pkgdatadir)/pw_dict"'
+subdir = lib_heimdal
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_heimdal_LTLIBRARIES)
+
+libcrack_heimdal_la_LIBADD =
+am_libcrack_heimdal_la_OBJECTS = fascist.lo packlib.lo rules.lo stringlib.lo
+libcrack_heimdal_la_OBJECTS = $(am_libcrack_heimdal_la_OBJECTS)
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/fascist.Plo ./$(DEPDIR)/packlib.Plo \
+@AMDEP_TRUE@	./$(DEPDIR)/rules.Plo ./$(DEPDIR)/stringlib.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+	$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libcrack_heimdal_la_SOURCES)
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(libcrack_heimdal_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  lib/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+lib_heimdalLTLIBRARIES_INSTALL = $(INSTALL)
+install-lib_heimdalLTLIBRARIES: $(lib_heimdal_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	@list='$(lib_heimdal_LTLIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    f="`echo $$p | sed -e 's|^.*/||'`"; \
+	    echo " $(LIBTOOL) --mode=install $(lib_heimdalLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+	    $(LIBTOOL) --mode=install $(lib_heimdalLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+	  else :; fi; \
+	done
+
+uninstall-lib_heimdalLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_heimdal_LTLIBRARIES)'; for p in $$list; do \
+	    p="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+	  $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+	done
+
+clean-lib_heimdalLTLIBRARIES:
+	-test -z "$(lib_heimdal_LTLIBRARIES)" || rm -f $(lib_heimdal_LTLIBRARIES)
+	@list='$(lib_heimdal_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" = "$$p" && dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libcrack_heimdal.la: $(libcrack_heimdal_la_OBJECTS) $(libcrack_heimdal_la_DEPENDENCIES) 
+	$(LINK) -rpath $(libdir) $(libcrack_heimdal_la_LDFLAGS) $(libcrack_heimdal_la_OBJECTS) $(libcrack_heimdal_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fascist.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packlib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rules.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringlib.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+install-includeHEADERS: $(include_HEADERS)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(includedir)
+	@list='$(include_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " $(includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(includedir)/$$f"; \
+	  $(includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(includedir)/$$f; \
+	done
+
+uninstall-includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(include_HEADERS)'; for p in $$list; do \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f $(DESTDIR)$(includedir)/$$f"; \
+	  rm -f $(DESTDIR)$(includedir)/$$f; \
+	done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$tags$$unique" \
+	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	     $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkinstalldirs) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+
+installdirs:
+	$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-lib_heimdalLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-exec-am: install-lib_heimdalLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS uninstall-info-am \
+	uninstall-lib_heimdalLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-lib_heimdalLTLIBRARIES clean-libtool ctags distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am info info-am install \
+	install-am install-data install-data-am install-exec \
+	install-exec-am install-includeHEADERS install-info \
+	install-info-am install-lib_heimdalLTLIBRARIES install-man \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
+	pdf-am ps ps-am tags uninstall uninstall-am \
+	uninstall-includeHEADERS uninstall-info-am \
+	uninstall-lib_heimdalLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

diff -Naur cracklib-2.8.3-orig/lib_heimdal/crack_heimdal.h cracklib-2.8.3/lib_heimdal/crack_heimdal.h
--- cracklib-2.8.3-orig/lib_heimdal/crack_heimdal.h	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/crack_heimdal.h	2005-07-23 19:08:01.000000000 +0000
@@ -0,0 +1,24 @@
+#ifndef CRACKLIB_HEIMDAL_H
+#define CRACKLIB_HEIMDAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* This header file is required for using cracklib with
+  * the Heimdal Kerberos 5 package. This file differs from
+  * the original cracklib header as Heimdal requires a third
+  * parameter passed to the FascistCheck function.
+  *
+  * You must link with -lcrack_heimdal
+  */
+
+extern char *FascistCheck(char *pw, char *dictpath, char *strings);
+
+#define CRACKLIB_DICTPATH "/lib/cracklib/pw_dict"
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif

diff -Naur cracklib-2.8.3-orig/lib_heimdal/fascist.c cracklib-2.8.3/lib_heimdal/fascist.c
--- cracklib-2.8.3-orig/lib_heimdal/fascist.c	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/fascist.c	2005-07-23 19:49:58.000000000 +0000
@@ -0,0 +1,907 @@
+/*
+ * This program is copyright Alec Muffett 1993. The author disclaims all
+ * responsibility or liability with respect to it's usage or its effect
+ * upon hardware or computer systems, and maintains copyright as set out
+ * in the "LICENCE" document which accompanies distributions of Crack v4.0
+ * and upwards.
+ */
+
+static char vers_id[] = "fascist.c : v2.3p3 Alec Muffett 14 dec 1997";
+
+#include "config.h"
+#include <sys/types.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#else
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+#endif
+#endif
+
+#include "packer_heimdal.h"
+
+#define ISSKIP(x) (isspace(x) || ispunct(x))
+
+#define MINDIFF 5
+#define MINLEN 6
+#define MAXSTEP 4
+
+#undef DEBUG
+#undef DEBUG2
+
+extern char *Reverse(char *buf);
+extern char *Lowercase(char *buf);
+
+static char *r_destructors[] = {
+    ":",                        /* noop - must do this to test raw word. */
+
+#ifdef DEBUG2
+    (char *) 0,
+#endif
+
+    "[",                        /* trimming leading/trailing junk */
+    "]",
+    "[[",
+    "]]",
+    "[[[",
+    "]]]",
+
+    "/?p@?p",                   /* purging out punctuation/symbols/junk */
+    "/?s@?s",
+    "/?X@?X",
+
+    /* attempt reverse engineering of password strings */
+
+    "/$s$s",
+    "/$s$s/0s0o",
+    "/$s$s/0s0o/2s2a",
+    "/$s$s/0s0o/2s2a/3s3e",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/1s1i",
+    "/$s$s/0s0o/2s2a/3s3e/1s1l",
+    "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/4s4h",
+    "/$s$s/0s0o/2s2a/3s3e/4s4a",
+    "/$s$s/0s0o/2s2a/3s3e/4s4h",
+    "/$s$s/0s0o/2s2a/5s5s",
+    "/$s$s/0s0o/2s2a/5s5s/1s1i",
+    "/$s$s/0s0o/2s2a/5s5s/1s1l",
+    "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4a",
+    "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4h",
+    "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4a",
+    "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4h",
+    "/$s$s/0s0o/2s2a/5s5s/4s4a",
+    "/$s$s/0s0o/2s2a/5s5s/4s4h",
+    "/$s$s/0s0o/2s2a/5s5s/4s4a",
+    "/$s$s/0s0o/2s2a/5s5s/4s4h",
+    "/$s$s/0s0o/2s2a/1s1i",
+    "/$s$s/0s0o/2s2a/1s1l",
+    "/$s$s/0s0o/2s2a/1s1i/4s4a",
+    "/$s$s/0s0o/2s2a/1s1i/4s4h",
+    "/$s$s/0s0o/2s2a/1s1l/4s4a",
+    "/$s$s/0s0o/2s2a/1s1l/4s4h",
+    "/$s$s/0s0o/2s2a/4s4a",
+    "/$s$s/0s0o/2s2a/4s4h",
+    "/$s$s/0s0o/2s2a/4s4a",
+    "/$s$s/0s0o/2s2a/4s4h",
+    "/$s$s/0s0o/3s3e",
+    "/$s$s/0s0o/3s3e/5s5s",
+    "/$s$s/0s0o/3s3e/5s5s/1s1i",
+    "/$s$s/0s0o/3s3e/5s5s/1s1l",
+    "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4a",
+    "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4h",
+    "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4a",
+    "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4h",
+    "/$s$s/0s0o/3s3e/5s5s/4s4a",
+    "/$s$s/0s0o/3s3e/5s5s/4s4h",
+    "/$s$s/0s0o/3s3e/5s5s/4s4a",
+    "/$s$s/0s0o/3s3e/5s5s/4s4h",
+    "/$s$s/0s0o/3s3e/1s1i",
+    "/$s$s/0s0o/3s3e/1s1l",
+    "/$s$s/0s0o/3s3e/1s1i/4s4a",
+    "/$s$s/0s0o/3s3e/1s1i/4s4h",
+    "/$s$s/0s0o/3s3e/1s1l/4s4a",
+    "/$s$s/0s0o/3s3e/1s1l/4s4h",
+    "/$s$s/0s0o/3s3e/4s4a",
+    "/$s$s/0s0o/3s3e/4s4h",
+    "/$s$s/0s0o/3s3e/4s4a",
+    "/$s$s/0s0o/3s3e/4s4h",
+    "/$s$s/0s0o/5s5s",
+    "/$s$s/0s0o/5s5s/1s1i",
+    "/$s$s/0s0o/5s5s/1s1l",
+    "/$s$s/0s0o/5s5s/1s1i/4s4a",
+    "/$s$s/0s0o/5s5s/1s1i/4s4h",
+    "/$s$s/0s0o/5s5s/1s1l/4s4a",
+    "/$s$s/0s0o/5s5s/1s1l/4s4h",
+    "/$s$s/0s0o/5s5s/4s4a",
+    "/$s$s/0s0o/5s5s/4s4h",
+    "/$s$s/0s0o/5s5s/4s4a",
+    "/$s$s/0s0o/5s5s/4s4h",
+    "/$s$s/0s0o/1s1i",
+    "/$s$s/0s0o/1s1l",
+    "/$s$s/0s0o/1s1i/4s4a",
+    "/$s$s/0s0o/1s1i/4s4h",
+    "/$s$s/0s0o/1s1l/4s4a",
+    "/$s$s/0s0o/1s1l/4s4h",
+    "/$s$s/0s0o/4s4a",
+    "/$s$s/0s0o/4s4h",
+    "/$s$s/0s0o/4s4a",
+    "/$s$s/0s0o/4s4h",
+    "/$s$s/2s2a",
+    "/$s$s/2s2a/3s3e",
+    "/$s$s/2s2a/3s3e/5s5s",
+    "/$s$s/2s2a/3s3e/5s5s/1s1i",
+    "/$s$s/2s2a/3s3e/5s5s/1s1l",
+    "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4a",
+    "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4h",
+    "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4a",
+    "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4h",
+    "/$s$s/2s2a/3s3e/5s5s/4s4a",
+    "/$s$s/2s2a/3s3e/5s5s/4s4h",
+    "/$s$s/2s2a/3s3e/5s5s/4s4a",
+    "/$s$s/2s2a/3s3e/5s5s/4s4h",
+    "/$s$s/2s2a/3s3e/1s1i",
+    "/$s$s/2s2a/3s3e/1s1l",
+    "/$s$s/2s2a/3s3e/1s1i/4s4a",
+    "/$s$s/2s2a/3s3e/1s1i/4s4h",
+    "/$s$s/2s2a/3s3e/1s1l/4s4a",
+    "/$s$s/2s2a/3s3e/1s1l/4s4h",
+    "/$s$s/2s2a/3s3e/4s4a",
+    "/$s$s/2s2a/3s3e/4s4h",
+    "/$s$s/2s2a/3s3e/4s4a",
+    "/$s$s/2s2a/3s3e/4s4h",
+    "/$s$s/2s2a/5s5s",
+    "/$s$s/2s2a/5s5s/1s1i",
+    "/$s$s/2s2a/5s5s/1s1l",
+    "/$s$s/2s2a/5s5s/1s1i/4s4a",
+    "/$s$s/2s2a/5s5s/1s1i/4s4h",
+    "/$s$s/2s2a/5s5s/1s1l/4s4a",
+    "/$s$s/2s2a/5s5s/1s1l/4s4h",
+    "/$s$s/2s2a/5s5s/4s4a",
+    "/$s$s/2s2a/5s5s/4s4h",
+    "/$s$s/2s2a/5s5s/4s4a",
+    "/$s$s/2s2a/5s5s/4s4h",
+    "/$s$s/2s2a/1s1i",
+    "/$s$s/2s2a/1s1l",
+    "/$s$s/2s2a/1s1i/4s4a",
+    "/$s$s/2s2a/1s1i/4s4h",
+    "/$s$s/2s2a/1s1l/4s4a",
+    "/$s$s/2s2a/1s1l/4s4h",
+    "/$s$s/2s2a/4s4a",
+    "/$s$s/2s2a/4s4h",
+    "/$s$s/2s2a/4s4a",
+    "/$s$s/2s2a/4s4h",
+    "/$s$s/3s3e",
+    "/$s$s/3s3e/5s5s",
+    "/$s$s/3s3e/5s5s/1s1i",
+    "/$s$s/3s3e/5s5s/1s1l",
+    "/$s$s/3s3e/5s5s/1s1i/4s4a",
+    "/$s$s/3s3e/5s5s/1s1i/4s4h",
+    "/$s$s/3s3e/5s5s/1s1l/4s4a",
+    "/$s$s/3s3e/5s5s/1s1l/4s4h",
+    "/$s$s/3s3e/5s5s/4s4a",
+    "/$s$s/3s3e/5s5s/4s4h",
+    "/$s$s/3s3e/5s5s/4s4a",
+    "/$s$s/3s3e/5s5s/4s4h",
+    "/$s$s/3s3e/1s1i",
+    "/$s$s/3s3e/1s1l",
+    "/$s$s/3s3e/1s1i/4s4a",
+    "/$s$s/3s3e/1s1i/4s4h",
+    "/$s$s/3s3e/1s1l/4s4a",
+    "/$s$s/3s3e/1s1l/4s4h",
+    "/$s$s/3s3e/4s4a",
+    "/$s$s/3s3e/4s4h",
+    "/$s$s/3s3e/4s4a",
+    "/$s$s/3s3e/4s4h",
+    "/$s$s/5s5s",
+    "/$s$s/5s5s/1s1i",
+    "/$s$s/5s5s/1s1l",
+    "/$s$s/5s5s/1s1i/4s4a",
+    "/$s$s/5s5s/1s1i/4s4h",
+    "/$s$s/5s5s/1s1l/4s4a",
+    "/$s$s/5s5s/1s1l/4s4h",
+    "/$s$s/5s5s/4s4a",
+    "/$s$s/5s5s/4s4h",
+    "/$s$s/5s5s/4s4a",
+    "/$s$s/5s5s/4s4h",
+    "/$s$s/1s1i",
+    "/$s$s/1s1l",
+    "/$s$s/1s1i/4s4a",
+    "/$s$s/1s1i/4s4h",
+    "/$s$s/1s1l/4s4a",
+    "/$s$s/1s1l/4s4h",
+    "/$s$s/4s4a",
+    "/$s$s/4s4h",
+    "/$s$s/4s4a",
+    "/$s$s/4s4h",
+    "/0s0o",
+    "/0s0o/2s2a",
+    "/0s0o/2s2a/3s3e",
+    "/0s0o/2s2a/3s3e/5s5s",
+    "/0s0o/2s2a/3s3e/5s5s/1s1i",
+    "/0s0o/2s2a/3s3e/5s5s/1s1l",
+    "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
+    "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
+    "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
+    "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
+    "/0s0o/2s2a/3s3e/5s5s/4s4a",
+    "/0s0o/2s2a/3s3e/5s5s/4s4h",
+    "/0s0o/2s2a/3s3e/5s5s/4s4a",
+    "/0s0o/2s2a/3s3e/5s5s/4s4h",
+    "/0s0o/2s2a/3s3e/1s1i",
+    "/0s0o/2s2a/3s3e/1s1l",
+    "/0s0o/2s2a/3s3e/1s1i/4s4a",
+    "/0s0o/2s2a/3s3e/1s1i/4s4h",
+    "/0s0o/2s2a/3s3e/1s1l/4s4a",
+    "/0s0o/2s2a/3s3e/1s1l/4s4h",
+    "/0s0o/2s2a/3s3e/4s4a",
+    "/0s0o/2s2a/3s3e/4s4h",
+    "/0s0o/2s2a/3s3e/4s4a",
+    "/0s0o/2s2a/3s3e/4s4h",
+    "/0s0o/2s2a/5s5s",
+    "/0s0o/2s2a/5s5s/1s1i",
+    "/0s0o/2s2a/5s5s/1s1l",
+    "/0s0o/2s2a/5s5s/1s1i/4s4a",
+    "/0s0o/2s2a/5s5s/1s1i/4s4h",
+    "/0s0o/2s2a/5s5s/1s1l/4s4a",
+    "/0s0o/2s2a/5s5s/1s1l/4s4h",
+    "/0s0o/2s2a/5s5s/4s4a",
+    "/0s0o/2s2a/5s5s/4s4h",
+    "/0s0o/2s2a/5s5s/4s4a",
+    "/0s0o/2s2a/5s5s/4s4h",
+    "/0s0o/2s2a/1s1i",
+    "/0s0o/2s2a/1s1l",
+    "/0s0o/2s2a/1s1i/4s4a",
+    "/0s0o/2s2a/1s1i/4s4h",
+    "/0s0o/2s2a/1s1l/4s4a",
+    "/0s0o/2s2a/1s1l/4s4h",
+    "/0s0o/2s2a/4s4a",
+    "/0s0o/2s2a/4s4h",
+    "/0s0o/2s2a/4s4a",
+    "/0s0o/2s2a/4s4h",
+    "/0s0o/3s3e",
+    "/0s0o/3s3e/5s5s",
+    "/0s0o/3s3e/5s5s/1s1i",
+    "/0s0o/3s3e/5s5s/1s1l",
+    "/0s0o/3s3e/5s5s/1s1i/4s4a",
+    "/0s0o/3s3e/5s5s/1s1i/4s4h",
+    "/0s0o/3s3e/5s5s/1s1l/4s4a",
+    "/0s0o/3s3e/5s5s/1s1l/4s4h",
+    "/0s0o/3s3e/5s5s/4s4a",
+    "/0s0o/3s3e/5s5s/4s4h",
+    "/0s0o/3s3e/5s5s/4s4a",
+    "/0s0o/3s3e/5s5s/4s4h",
+    "/0s0o/3s3e/1s1i",
+    "/0s0o/3s3e/1s1l",
+    "/0s0o/3s3e/1s1i/4s4a",
+    "/0s0o/3s3e/1s1i/4s4h",
+    "/0s0o/3s3e/1s1l/4s4a",
+    "/0s0o/3s3e/1s1l/4s4h",
+    "/0s0o/3s3e/4s4a",
+    "/0s0o/3s3e/4s4h",
+    "/0s0o/3s3e/4s4a",
+    "/0s0o/3s3e/4s4h",
+    "/0s0o/5s5s",
+    "/0s0o/5s5s/1s1i",
+    "/0s0o/5s5s/1s1l",
+    "/0s0o/5s5s/1s1i/4s4a",
+    "/0s0o/5s5s/1s1i/4s4h",
+    "/0s0o/5s5s/1s1l/4s4a",
+    "/0s0o/5s5s/1s1l/4s4h",
+    "/0s0o/5s5s/4s4a",
+    "/0s0o/5s5s/4s4h",
+    "/0s0o/5s5s/4s4a",
+    "/0s0o/5s5s/4s4h",
+    "/0s0o/1s1i",
+    "/0s0o/1s1l",
+    "/0s0o/1s1i/4s4a",
+    "/0s0o/1s1i/4s4h",
+    "/0s0o/1s1l/4s4a",
+    "/0s0o/1s1l/4s4h",
+    "/0s0o/4s4a",
+    "/0s0o/4s4h",
+    "/0s0o/4s4a",
+    "/0s0o/4s4h",
+    "/2s2a",
+    "/2s2a/3s3e",
+    "/2s2a/3s3e/5s5s",
+    "/2s2a/3s3e/5s5s/1s1i",
+    "/2s2a/3s3e/5s5s/1s1l",
+    "/2s2a/3s3e/5s5s/1s1i/4s4a",
+    "/2s2a/3s3e/5s5s/1s1i/4s4h",
+    "/2s2a/3s3e/5s5s/1s1l/4s4a",
+    "/2s2a/3s3e/5s5s/1s1l/4s4h",
+    "/2s2a/3s3e/5s5s/4s4a",
+    "/2s2a/3s3e/5s5s/4s4h",
+    "/2s2a/3s3e/5s5s/4s4a",
+    "/2s2a/3s3e/5s5s/4s4h",
+    "/2s2a/3s3e/1s1i",
+    "/2s2a/3s3e/1s1l",
+    "/2s2a/3s3e/1s1i/4s4a",
+    "/2s2a/3s3e/1s1i/4s4h",
+    "/2s2a/3s3e/1s1l/4s4a",
+    "/2s2a/3s3e/1s1l/4s4h",
+    "/2s2a/3s3e/4s4a",
+    "/2s2a/3s3e/4s4h",
+    "/2s2a/3s3e/4s4a",
+    "/2s2a/3s3e/4s4h",
+    "/2s2a/5s5s",
+    "/2s2a/5s5s/1s1i",
+    "/2s2a/5s5s/1s1l",
+    "/2s2a/5s5s/1s1i/4s4a",
+    "/2s2a/5s5s/1s1i/4s4h",
+    "/2s2a/5s5s/1s1l/4s4a",
+    "/2s2a/5s5s/1s1l/4s4h",
+    "/2s2a/5s5s/4s4a",
+    "/2s2a/5s5s/4s4h",
+    "/2s2a/5s5s/4s4a",
+    "/2s2a/5s5s/4s4h",
+    "/2s2a/1s1i",
+    "/2s2a/1s1l",
+    "/2s2a/1s1i/4s4a",
+    "/2s2a/1s1i/4s4h",
+    "/2s2a/1s1l/4s4a",
+    "/2s2a/1s1l/4s4h",
+    "/2s2a/4s4a",
+    "/2s2a/4s4h",
+    "/2s2a/4s4a",
+    "/2s2a/4s4h",
+    "/3s3e",
+    "/3s3e/5s5s",
+    "/3s3e/5s5s/1s1i",
+    "/3s3e/5s5s/1s1l",
+    "/3s3e/5s5s/1s1i/4s4a",
+    "/3s3e/5s5s/1s1i/4s4h",
+    "/3s3e/5s5s/1s1l/4s4a",
+    "/3s3e/5s5s/1s1l/4s4h",
+    "/3s3e/5s5s/4s4a",
+    "/3s3e/5s5s/4s4h",
+    "/3s3e/5s5s/4s4a",
+    "/3s3e/5s5s/4s4h",
+    "/3s3e/1s1i",
+    "/3s3e/1s1l",
+    "/3s3e/1s1i/4s4a",
+    "/3s3e/1s1i/4s4h",
+    "/3s3e/1s1l/4s4a",
+    "/3s3e/1s1l/4s4h",
+    "/3s3e/4s4a",
+    "/3s3e/4s4h",
+    "/3s3e/4s4a",
+    "/3s3e/4s4h",
+    "/5s5s",
+    "/5s5s/1s1i",
+    "/5s5s/1s1l",
+    "/5s5s/1s1i/4s4a",
+    "/5s5s/1s1i/4s4h",
+    "/5s5s/1s1l/4s4a",
+    "/5s5s/1s1l/4s4h",
+    "/5s5s/4s4a",
+    "/5s5s/4s4h",
+    "/5s5s/4s4a",
+    "/5s5s/4s4h",
+    "/1s1i",
+    "/1s1l",
+    "/1s1i/4s4a",
+    "/1s1i/4s4h",
+    "/1s1l/4s4a",
+    "/1s1l/4s4h",
+    "/4s4a",
+    "/4s4h",
+    "/4s4a",
+    "/4s4h",
+
+    /* done */
+    (char *) 0
+};
+
+static char *r_constructors[] = {
+    ":",
+
+#ifdef DEBUG2
+    (char *) 0,
+#endif
+
+    "r",
+    "d",
+    "f",
+    "dr",
+    "fr",
+    "rf",
+    (char *) 0
+};
+
+int
+GTry(rawtext, password)
+    char *rawtext;
+    char *password;
+{
+    int i;
+    int len;
+    char *mp;
+
+    /* use destructors to turn password into rawtext */
+    /* note use of Reverse() to save duplicating all rules */
+
+    len = strlen(password);
+
+    for (i = 0; r_destructors[i]; i++)
+    {
+	if (!(mp = Mangle(password, r_destructors[i])))
+	{
+	    continue;
+	}
+
+#ifdef DEBUG
+	printf("%-16s = %-16s (destruct %s)\n", mp, rawtext, r_destructors[i]);
+#endif
+
+	if (!strncmp(mp, rawtext, len))
+	{
+	    return (1);
+	}
+
+#ifdef DEBUG
+	printf("%-16s = %-16s (destruct %s reversed)\n", Reverse(mp), rawtext, r_destructors[i]);
+#endif
+
+	if (!strncmp(Reverse(mp), rawtext, len))
+	{
+	    return (1);
+	}
+    }
+
+    for (i = 0; r_constructors[i]; i++)
+    {
+	if (!(mp = Mangle(rawtext, r_constructors[i])))
+	{
+	    continue;
+	}
+
+#ifdef DEBUG
+	printf("%-16s = %-16s (construct %s)\n", mp, password, r_constructors[i]);
+#endif
+
+	if (!strncmp(mp, password, len))
+	{
+	    return (1);
+	}
+    }
+
+    return (0);
+}
+
+char *
+FascistStrings(password, strings)
+    char *password;
+    char **strings;
+{
+    char *p;
+
+    while(p = *strings++)
+    {
+       if(GTry(p, password))
+       {
+           return ("it is based on your name");
+       }
+    }
+    return ((char *) 0);
+}
+
+char *
+FascistGecos(password, uid)
+    char *password;
+    int uid;
+{
+    int i;
+    int j;
+    int wc;
+    char *ptr;
+    int gwords;
+    struct passwd *pwp, passwd;
+    char gbuffer[STRINGSIZE];
+    char tbuffer[STRINGSIZE];
+    char *sbuffer = NULL;
+#ifdef HAVE_GETPWUID_R
+    size_t sbufferlen = LINE_MAX;
+#endif
+    char *uwords[STRINGSIZE];
+    char longbuffer[STRINGSIZE * 2];
+
+#ifdef HAVE_GETPWUID_R
+    sbuffer = malloc(sbufferlen);
+    if (sbuffer == NULL)
+    {
+        return ("memory allocation error");
+    }
+    while ((i = getpwuid_r(uid, &passwd, sbuffer, sbufferlen, &pwp)) != 0)
+    {
+        if (i == ERANGE)
+        {
+            free(sbuffer);
+
+	    sbufferlen += LINE_MAX;
+            sbuffer = malloc(sbufferlen);
+
+            if (sbuffer == NULL)
+            {
+                return ("memory allocation error");
+            }
+        } else {
+            pwp = NULL;
+            break;
+        }
+    }
+#else
+    /* Non-reentrant, but no choice since no _r routine */
+    pwp = getpwuid(uid);
+#endif
+
+    if (pwp == NULL)
+    {
+	if (sbuffer)
+	{
+		free(sbuffer);
+		sbuffer = NULL;
+	}
+	return ("you are not registered in the password file");
+    }
+
+    /* lets get really paranoid and assume a dangerously long gecos entry */
+
+    strncpy(tbuffer, pwp->pw_name, STRINGSIZE);
+    tbuffer[STRINGSIZE-1] = '\0';
+    if (GTry(tbuffer, password))
+    {
+	if (sbuffer)
+	{
+		free(sbuffer);
+		sbuffer = NULL;
+	}
+	return ("it is based on your username");
+    }
+
+    /* it never used to be that you got passwd strings > 1024 chars, but now... */
+
+    strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE);
+    tbuffer[STRINGSIZE-1] = '\0';
+    strcpy(gbuffer, Lowercase(tbuffer));
+
+    wc = 0;
+    ptr = gbuffer;
+    gwords = 0;
+    uwords[0] = (char *)0;
+
+    while (*ptr)
+    {
+	while (*ptr && ISSKIP(*ptr))
+	{
+	    ptr++;
+	}
+
+	if (ptr != gbuffer)
+	{
+	    ptr[-1] = '\0';
+	}
+
+	gwords++;
+	uwords[wc++] = ptr;
+
+	if (wc == STRINGSIZE)
+	{
+	    uwords[--wc] = (char *) 0;  /* to hell with it */
+	    break;
+	} else
+	{
+	    uwords[wc] = (char *) 0;
+	}
+
+	while (*ptr && !ISSKIP(*ptr))
+	{
+	    ptr++;
+	}
+
+	if (*ptr)
+	{
+	    *(ptr++) = '\0';
+	}
+    }
+
+#ifdef DEBUG
+    for (i = 0; uwords[i]; i++)
+    {
+	printf("gecosword %s\n", uwords[i]);
+    }
+#endif
+
+    for (i = 0; uwords[i]; i++)
+    {
+	if (GTry(uwords[i], password))
+	{
+	    if (sbuffer)
+	    {
+	    	free(sbuffer);
+		sbuffer = NULL;
+	    }
+	    return ("it is based upon your password entry");
+	}
+    }
+
+    /* since uwords are taken from gbuffer, no uword can be longer than gbuffer */
+
+    for (j = 1; (j < gwords) && uwords[j]; j++)
+    {
+	for (i = 0; i < j; i++)
+	{
+	    strcpy(longbuffer, uwords[i]);
+	    strcat(longbuffer, uwords[j]);
+
+	    if (GTry(longbuffer, password))
+	    {
+	        if (sbuffer)
+	        {
+	       	    free(sbuffer);
+		    sbuffer = NULL;
+	        }
+		return ("it is derived from your password entry");
+	    }
+
+	    strcpy(longbuffer, uwords[j]);
+	    strcat(longbuffer, uwords[i]);
+
+	    if (GTry(longbuffer, password))
+	    {
+	        if (sbuffer)
+	        {
+	       	    free(sbuffer);
+		    sbuffer = NULL;
+	        }
+		return ("it's derived from your password entry");
+	    }
+
+	    longbuffer[0] = uwords[i][0];
+	    longbuffer[1] = '\0';
+	    strcat(longbuffer, uwords[j]);
+
+	    if (GTry(longbuffer, password))
+	    {
+	        if (sbuffer)
+	        {
+	       	    free(sbuffer);
+		    sbuffer = NULL;
+	        }
+		return ("it is derivable from your password entry");
+	    }
+
+	    longbuffer[0] = uwords[j][0];
+	    longbuffer[1] = '\0';
+	    strcat(longbuffer, uwords[i]);
+
+	    if (GTry(longbuffer, password))
+	    {
+	        if (sbuffer)
+	        {
+	       	    free(sbuffer);
+		    sbuffer = NULL;
+	        }
+		return ("it's derivable from your password entry");
+	    }
+	}
+    }
+
+    if (sbuffer)
+    {
+        free(sbuffer);
+        sbuffer = NULL;
+    }
+
+    return ((char *) 0);
+}
+
+char *
+FascistLook(pwp, instring, strings)
+    PWDICT *pwp;
+    char *instring;
+    char **strings;
+{
+    int i;
+    char *ptr;
+    char *jptr;
+    char junk[STRINGSIZE];
+    char *password;
+    char rpassword[STRINGSIZE];
+    uint32_t notfound;
+
+    notfound = PW_WORDS(pwp);
+    /* already truncated if from FascistCheck() */
+    /* but pretend it wasn't ... */
+    strncpy(rpassword, instring, TRUNCSTRINGSIZE);
+    rpassword[TRUNCSTRINGSIZE - 1] = '\0';
+    password = rpassword;
+
+    if (strlen(password) < 4)
+    {
+	return ("it's WAY too short");
+    }
+
+    if (strlen(password) < MINLEN)
+    {
+	return ("it is too short");
+    }
+
+    jptr = junk;
+    *jptr = '\0';
+
+    for (i = 0; i < STRINGSIZE && password[i]; i++)
+    {
+	if (!strchr(junk, password[i]))
+	{
+	    *(jptr++) = password[i];
+	    *jptr = '\0';
+	}
+    }
+
+    if (strlen(junk) < MINDIFF)
+    {
+	return ("it does not contain enough DIFFERENT characters");
+    }
+
+    strcpy(password, (char *)Lowercase(password));
+
+    Trim(password);
+
+    while (*password && isspace(*password))
+    {
+	password++;
+    }
+
+    if (!*password)
+    {
+	return ("it is all whitespace");
+    }
+
+    i = 0;
+    ptr = password;
+    while (ptr[0] && ptr[1])
+    {
+	if ((ptr[1] == (ptr[0] + 1)) || (ptr[1] == (ptr[0] - 1)))
+	{
+	    i++;
+	}
+	ptr++;
+    }
+
+    if (i > MAXSTEP)
+    {
+	return ("it is too simplistic/systematic");
+    }
+
+    if (PMatch("aadddddda", password))  /* smirk */
+    {
+	return ("it looks like a National Insurance number.");
+    }
+
+#if 0
+    if (ptr = FascistGecos(password, getuid()))
+    {
+	return (ptr);
+    }
+#endif
+    if (ptr = FascistStrings(password, strings))
+    {
+	return (ptr);
+    }
+
+    /* it should be safe to use Mangle with its reliance on STRINGSIZE
+       since password cannot be longer than TRUNCSTRINGSIZE;
+       nonetheless this is not an elegant solution */
+
+    for (i = 0; r_destructors[i]; i++)
+    {
+	char *a;
+
+	if (!(a = Mangle(password, r_destructors[i])))
+	{
+	    continue;
+	}
+
+#ifdef DEBUG
+	printf("%-16s (dict)\n", a);
+#endif
+
+	if (FindPW(pwp, a) != notfound)
+	{
+	    return ("it is based on a dictionary word");
+	}
+    }
+
+    strcpy(password, (char *)Reverse(password));
+
+    for (i = 0; r_destructors[i]; i++)
+    {
+	char *a;
+
+	if (!(a = Mangle(password, r_destructors[i])))
+	{
+	    continue;
+	}
+#ifdef DEBUG
+	printf("%-16s (reversed dict)\n", a);
+#endif
+	if (FindPW(pwp, a) != notfound)
+	{
+	    return ("it is based on a (reversed) dictionary word");
+	}
+    }
+
+    return ((char *) 0);
+}
+
+char *
+FascistCheck(password, path, strings)
+    char *password;
+    char *path;
+    char *strings;
+{
+    PWDICT *pwp;
+    char pwtrunced[STRINGSIZE];
+    char *res;
+
+    /* If passed null for the path, use a compiled-in default */
+    if ( ! path )
+    {
+	path = DEFAULT_CRACKLIB_DICT;
+    }
+
+    /* security problem: assume we may have been given a really long
+       password (buffer attack) and so truncate it to a workable size;
+       try to define workable size as something from which we cannot
+       extend a buffer beyond its limits in the rest of the code */
+
+    strncpy(pwtrunced, password, TRUNCSTRINGSIZE);
+    pwtrunced[TRUNCSTRINGSIZE - 1] = '\0'; /* enforce */
+
+    /* perhaps someone should put something here to check if password
+       is really long and syslog() a message denoting buffer attacks?  */
+
+    if (!(pwp = PWOpen(path, "r")))
+    {
+        /* shouldn't perror in a library or exit */
+	/* but should we return a "bad password" or "good password" if this error occurs */
+	perror("PWOpen");
+	exit(-1);
+    }
+
+    /* sure seems like we should close the database, since we're only likely to check one password */
+    res = FascistLook(pwp, pwtrunced, strings);
+
+    PWClose(pwp);
+    pwp = (PWDICT *)0;
+
+    return res;
+}

diff -Naur cracklib-2.8.3-orig/lib_heimdal/packer_heimdal.h cracklib-2.8.3/lib_heimdal/packer_heimdal.h
--- cracklib-2.8.3-orig/lib_heimdal/packer_heimdal.h	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/packer_heimdal.h	2005-07-23 19:00:05.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * This program is copyright Alec Muffett 1993. The author disclaims all 
+ * responsibility or liability with respect to it's usage or its effect 
+ * upon hardware or computer systems, and maintains copyright as set out 
+ * in the "LICENCE" document which accompanies distributions of Crack v4.0 
+ * and upwards.
+ */
+
+#ifndef CRACKLIB_HEIMDAL_PACKER_H
+#define CRACKLIB_HEIMDAL_PACKER_H
+
+#ifdef IN_CRACKLIB_HEIMDAL
+
+#include <stdio.h>
+#include <ctype.h>
+#include <crack_heimdal.h>
+
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#else
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+#endif
+#endif
+
+#define STRINGSIZE	1024
+#define TRUNCSTRINGSIZE	(STRINGSIZE/4)
+
+#ifndef NUMWORDS
+#define NUMWORDS 	16
+#endif
+#define MAXWORDLEN	32
+#define MAXBLOCKLEN 	(MAXWORDLEN * NUMWORDS)
+
+struct pi_header
+{
+    uint32_t pih_magic;
+    uint32_t pih_numwords;
+    uint16_t pih_blocklen;
+    uint16_t pih_pad;
+};
+
+typedef struct
+{
+    FILE *ifp;
+    FILE *dfp;
+    FILE *wfp;
+
+    uint32_t flags;
+#define PFOR_WRITE	0x0001
+#define PFOR_FLUSH	0x0002
+#define PFOR_USEHWMS	0x0004
+
+    uint32_t hwms[256];
+
+    struct pi_header header;
+
+    int count;
+    char data[NUMWORDS][MAXWORDLEN];
+} PWDICT;
+
+#define PW_WORDS(x) ((x)->header.pih_numwords)
+#define PIH_MAGIC 0x70775631
+
+/* Internal routines */
+extern char *GetPW(PWDICT *pwp, uint32_t number);
+
+#else
+
+/* Dummy structure, this is an internal only opaque data type */
+typedef struct {
+	int dummy;
+} PWDICT;
+
+#endif
+
+extern PWDICT *PWOpen(char *prefix, char *mode);
+extern char *Mangle(char *input, char *control);
+
+
+#endif

diff -Naur cracklib-2.8.3-orig/lib_heimdal/packlib.c cracklib-2.8.3/lib_heimdal/packlib.c
--- cracklib-2.8.3-orig/lib_heimdal/packlib.c	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/packlib.c	2005-07-23 19:52:45.000000000 +0000
@@ -0,0 +1,526 @@
+/*
+ * This program is copyright Alec Muffett 1993. The author disclaims all 
+ * responsibility or liability with respect to it's usage or its effect 
+ * upon hardware or computer systems, and maintains copyright as set out 
+ * in the "LICENCE" document which accompanies distributions of Crack v4.0 
+ * and upwards.
+ */
+
+#include "config.h"
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include "packer_heimdal.h"
+
+static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
+
+#define DEBUG 0
+
+/* Structures for processing "broken" 64bit dictionary files */
+
+struct pi_header64
+{
+    uint64_t pih_magic;
+    uint64_t pih_numwords;
+    uint16_t pih_blocklen;
+    uint16_t pih_pad;
+};
+
+typedef struct
+{
+    FILE *ifp;
+    FILE *dfp;
+    FILE *wfp;
+    uint64_t flags;
+    uint64_t hwms[256];
+    struct pi_header64 header;
+    int count;
+    char data[NUMWORDS][MAXWORDLEN];
+} PWDICT64;
+
+
+static int
+_PWIsBroken64(FILE *ifp)
+{
+    PWDICT64 pdesc64;
+
+    rewind(ifp);
+    if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
+    {
+       return 0;
+    }
+
+    return (pdesc64.header.pih_magic == PIH_MAGIC);
+}
+
+
+PWDICT *
+PWOpen(prefix, mode)
+    char *prefix;
+    char *mode;
+{
+    uint32_t i;
+    int use64 = 0;
+    static PWDICT pdesc;
+    static PWDICT64 pdesc64;
+    char iname[STRINGSIZE];
+    char dname[STRINGSIZE];
+    char wname[STRINGSIZE];
+    char buffer[STRINGSIZE];
+    FILE *dfp;
+    FILE *ifp;
+    FILE *wfp;
+
+    if (pdesc.header.pih_magic == PIH_MAGIC)
+    {
+	fprintf(stderr, "%s: another dictionary already open\n", prefix);
+	return ((PWDICT *) 0);
+    }
+
+    memset(&pdesc, '\0', sizeof(pdesc));
+    memset(&pdesc64, '\0', sizeof(pdesc64));
+
+    snprintf(iname, STRINGSIZE, "%s.pwi", prefix);
+    snprintf(dname, STRINGSIZE, "%s.pwd", prefix);
+    snprintf(wname, STRINGSIZE, "%s.hwm", prefix);
+
+    if (!(pdesc.dfp = fopen(dname, mode)))
+    {
+	perror(dname);
+	return ((PWDICT *) 0);
+    }
+
+    if (!(pdesc.ifp = fopen(iname, mode)))
+    {
+	fclose(pdesc.dfp);
+	perror(iname);
+	return ((PWDICT *) 0);
+    }
+
+    if (pdesc.wfp = fopen(wname, mode))
+    {
+	pdesc.flags |= PFOR_USEHWMS;
+    }
+
+    ifp = pdesc.ifp;
+    dfp = pdesc.dfp;
+    wfp = pdesc.wfp;
+
+    if (mode[0] == 'w')
+    {
+	pdesc.flags |= PFOR_WRITE;
+	pdesc.header.pih_magic = PIH_MAGIC;
+	pdesc.header.pih_blocklen = NUMWORDS;
+	pdesc.header.pih_numwords = 0;
+
+	fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
+    } else
+    {
+	pdesc.flags &= ~PFOR_WRITE;
+
+	if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
+	{
+	    fprintf(stderr, "%s: error reading header\n", prefix);
+
+	    pdesc.header.pih_magic = 0;
+	    fclose(ifp);
+	    fclose(dfp);
+	    return ((PWDICT *) 0);
+	}
+
+        if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0))
+        {
+            /* uh-oh. either a broken "64-bit" file or a garbage file. */
+            rewind (ifp);
+            if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
+            {
+                fprintf(stderr, "%s: error reading header\n", prefix);
+ 
+                pdesc.header.pih_magic = 0;
+                fclose(ifp);
+                fclose(dfp);
+                return ((PWDICT *) 0);
+            }
+            if (pdesc64.header.pih_magic != PIH_MAGIC)
+            {
+                /* nope, not "64-bit" after all */
+                fprintf(stderr, "%s: error reading header\n", prefix);
+ 
+                pdesc.header.pih_magic = 0;
+                fclose(ifp);
+                fclose(dfp);
+                return ((PWDICT *) 0);
+            }
+            pdesc.header.pih_magic = pdesc64.header.pih_magic;
+            pdesc.header.pih_numwords = pdesc64.header.pih_numwords;
+            pdesc.header.pih_blocklen = pdesc64.header.pih_blocklen;
+            pdesc.header.pih_pad = pdesc64.header.pih_pad;
+            use64 = 1;
+        }
+
+	if (pdesc.header.pih_magic != PIH_MAGIC)
+	{
+	    fprintf(stderr, "%s: magic mismatch\n", prefix);
+
+	    pdesc.header.pih_magic = 0;
+	    fclose(ifp);
+	    fclose(dfp);
+	    return ((PWDICT *) 0);
+	}
+
+        if (pdesc.header.pih_numwords < 1)
+        {
+            fprintf(stderr, "%s: invalid word count\n", prefix);
+ 
+            pdesc.header.pih_magic = 0;
+            fclose(ifp);
+            fclose(dfp);
+            return ((PWDICT *) 0);
+        }
+
+	if (pdesc.header.pih_blocklen != NUMWORDS)
+	{
+	    fprintf(stderr, "%s: size mismatch\n", prefix);
+
+	    pdesc.header.pih_magic = 0;
+	    fclose(ifp);
+	    fclose(dfp);
+	    return ((PWDICT *) 0);
+	}
+
+	if (pdesc.flags & PFOR_USEHWMS)
+	{
+            int i;
+
+            if (use64)
+            {
+                if (fread(pdesc64.hwms, 1, sizeof(pdesc64.hwms), wfp) != sizeof(pdesc64.hwms))
+                {
+                    pdesc.flags &= ~PFOR_USEHWMS;
+                }
+                for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++)
+                {
+                    pdesc.hwms[i] = pdesc64.hwms[i];
+                }
+            } 
+            else if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
+	    {
+		pdesc.flags &= ~PFOR_USEHWMS;
+	    }
+#if DEBUG
+            for (i=1; i<=0xff; i++)
+            {
+                printf("hwm[%02x] = %d\n", i, pdesc.hwms[i]);
+            }
+#endif
+	}
+    }
+
+    return (&pdesc);
+}
+
+int
+PWClose(pwp)
+    PWDICT *pwp;
+{
+    if (pwp->header.pih_magic != PIH_MAGIC)
+    {
+	fprintf(stderr, "PWClose: close magic mismatch\n");
+	return (-1);
+    }
+
+    if (pwp->flags & PFOR_WRITE)
+    {
+	pwp->flags |= PFOR_FLUSH;
+	PutPW(pwp, (char *) 0);	/* flush last index if necess */
+
+	if (fseek(pwp->ifp, 0L, 0))
+	{
+	    fprintf(stderr, "index magic fseek failed\n");
+	    return (-1);
+	}
+
+	if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp))
+	{
+	    fprintf(stderr, "index magic fwrite failed\n");
+	    return (-1);
+	}
+
+	if (pwp->flags & PFOR_USEHWMS)
+	{
+	    int i;
+	    for (i=1; i<=0xff; i++)
+	    {
+	    	if (!pwp->hwms[i])
+	    	{
+	    	    pwp->hwms[i] = pwp->hwms[i-1];
+	    	}
+#if DEBUG
+	    	printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
+#endif
+	    }
+	    fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
+	}
+    }
+
+    fclose(pwp->ifp);
+    fclose(pwp->dfp);
+
+    pwp->header.pih_magic = 0;
+
+    return (0);
+}
+
+int
+PutPW(pwp, string)
+    PWDICT *pwp;
+    char *string;
+{
+    if (!(pwp->flags & PFOR_WRITE))
+    {
+	return (-1);
+    }
+
+    if (string)
+    {
+	strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
+	pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
+
+	pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords;
+
+	++(pwp->count);
+	++(pwp->header.pih_numwords);
+
+    } else if (!(pwp->flags & PFOR_FLUSH))
+    {
+	return (-1);
+    }
+
+    if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS))
+    {
+	int i;
+	uint32_t datum;
+	register char *ostr;
+
+	datum = (uint32_t) ftell(pwp->dfp);
+
+	fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp);
+
+	fputs(pwp->data[0], pwp->dfp);
+	putc(0, pwp->dfp);
+
+	ostr = pwp->data[0];
+
+	for (i = 1; i < NUMWORDS; i++)
+	{
+	    register int j;
+	    register char *nstr;
+	    nstr = pwp->data[i];
+
+	    if (nstr[0])
+	    {
+		for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++);
+		putc(j & 0xff, pwp->dfp);
+		fputs(nstr + j, pwp->dfp);
+	    }
+	    putc(0, pwp->dfp);
+
+	    ostr = nstr;
+	}
+
+	memset(pwp->data, '\0', sizeof(pwp->data));
+	pwp->count = 0;
+    }
+    return (0);
+}
+
+char *
+GetPW(pwp, number)
+    PWDICT *pwp;
+    uint32_t number;
+{
+    uint32_t datum;
+    register int i;
+    register char *ostr;
+    register char *nstr;
+    register char *bptr;
+    char buffer[NUMWORDS * MAXWORDLEN];
+    static char data[NUMWORDS][MAXWORDLEN];
+    static uint32_t prevblock = 0xffffffff;
+    uint32_t thisblock;
+
+    thisblock = number / NUMWORDS;
+
+    if (prevblock == thisblock)
+    {
+#if DEBUG
+	fprintf(stderr, "returning (%s)\n", data[number % NUMWORDS]);
+#endif
+	return (data[number % NUMWORDS]);
+    }
+
+    if (_PWIsBroken64(pwp->ifp))
+    {
+       uint64_t datum64;
+       if (fseek(pwp->ifp, sizeof(struct pi_header64) + (thisblock * sizeof(uint64_t)), 0))
+       {
+           perror("(index fseek failed)");
+           return ((char *) 0);
+       }
+
+       if (!fread((char *) &datum64, sizeof(datum64), 1, pwp->ifp))
+       {
+           perror("(index fread failed)");
+           return ((char *) 0);
+       }
+       datum = datum64;
+    } else {
+       if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0))
+       {
+           perror("(index fseek failed)");
+           return ((char *) 0);
+       }
+
+       if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp))
+       {
+           perror("(index fread failed)");
+           return ((char *) 0);
+       }
+    }
+
+    if (fseek(pwp->dfp, datum, 0))
+    {
+	perror("(data fseek failed)");
+	return ((char *) 0);
+    }
+
+    if (!fread(buffer, 1, sizeof(buffer), pwp->dfp))
+    {
+	perror("(data fread failed)");
+	return ((char *) 0);
+    }
+
+    prevblock = thisblock;
+
+    bptr = buffer;
+
+    for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */ );
+
+    ostr = data[0];
+
+    for (i = 1; i < NUMWORDS; i++)
+    {
+	nstr = data[i];
+	strcpy(nstr, ostr);
+
+	ostr = nstr + *(bptr++);
+	while (*(ostr++) = *(bptr++));
+
+	ostr = nstr;
+    }
+
+    return (data[number % NUMWORDS]);
+}
+
+uint32_t
+FindPW(pwp, string)
+    PWDICT *pwp;
+    char *string;
+{
+    register uint32_t lwm;
+    register uint32_t hwm;
+    register uint32_t middle;
+    register char *this;
+    int idx;
+
+#if DEBUG
+fprintf(stderr, "look for (%s)\n", string);
+#endif
+       if (lwm > hwm) {
+            register uint32_t tmp;
+
+            tmp = hwm;
+            hwm = lwm;
+            lwm = tmp;
+       }
+
+    if (pwp->flags & PFOR_USEHWMS)
+    {
+	idx = string[0] & 0xff;
+    	lwm = idx ? pwp->hwms[idx - 1] : 0;
+    	hwm = pwp->hwms[idx];
+
+#if DEBUG
+	fprintf(stderr, "idx = %d\n", idx);
+	fprintf(stderr, "lwm = %d,  hwm = %d\n", lwm, hwm);
+#endif
+    } else
+    {
+    	lwm = 0;
+    	hwm = PW_WORDS(pwp) - 1;
+    }
+
+    /* if the high water mark is lower than the low water mark, something is screwed up */
+    if ( hwm < lwm )
+    {
+	lwm = 0;
+	hwm = PW_WORDS(pwp) - 1;
+    }
+
+#if DEBUG
+    fprintf(stderr, "---- %lu, %lu ----\n", lwm, hwm);
+#endif
+
+    for (;;)
+    {
+	int cmp;
+
+	middle = lwm + ((hwm - lwm + 1) / 2);
+
+#if DEBUG
+	fprintf(stderr, "lwm = %lu,  middle = %lu,  hwm = %lu\n", lwm, middle, hwm);
+#endif
+
+	this = GetPW(pwp, middle);
+	if ( ! this )
+	{
+#if DEBUG
+		fprintf(stderr, "getpw returned null, returning null in FindPW\n");
+#endif
+		return(PW_WORDS(pwp));
+	}
+	else
+	{
+#if DEBUG
+		fprintf(stderr, "comparing %s against found %s\n", string, this);
+#endif
+	}
+
+	cmp = strcmp(string, this);
+	if (cmp == 0)
+	{
+	    return(middle);
+        }
+
+        if (middle == hwm)
+        {
+#if DEBUG 
+		fprintf(stderr, "at terminal subdivision, stopping search\n");
+#endif
+		break;
+        }
+
+	if (cmp < 0)
+	{
+	    hwm = middle;
+	} 
+	else if (cmp > 0)
+	{
+	    lwm = middle;
+	} 
+    }
+
+    return (PW_WORDS(pwp));
+}

diff -Naur cracklib-2.8.3-orig/lib_heimdal/rules.c cracklib-2.8.3/lib_heimdal/rules.c
--- cracklib-2.8.3-orig/lib_heimdal/rules.c	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/rules.c	2005-07-23 19:00:05.000000000 +0000
@@ -0,0 +1,841 @@
+/*
+ * This program is copyright Alec Muffett 1993. The author disclaims all 
+ * responsibility or liability with respect to it's usage or its effect 
+ * upon hardware or computer systems, and maintains copyright as set out 
+ * in the "LICENCE" document which accompanies distributions of Crack v4.0 
+ * and upwards.
+ */
+
+static char vers_id[] = "rules.c : v5.0p3 Alec Muffett 20 May 1993";
+
+#include "config.h"
+#include <string.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include "crack_heimdal.h"
+#include "packer_heimdal.h"
+
+#define CRACK_TOLOWER(a)        (isupper(a)?tolower(a):(a))
+#define CRACK_TOUPPER(a)        (islower(a)?toupper(a):(a))
+#define STRCMP(a,b)             strcmp((a),(b))
+
+#if 0
+static void
+Debug(val, a, b, c, d, e, f, g)
+    int val;
+    char *a, *b, *c, *d, *e, *f, *g;
+{
+    fprintf(stderr, a, b, c, d, e, f);
+}
+#else
+static void
+Debug(val, a, b, c, d, e, f, g)
+    int val;
+    char *a, *b, *c, *d, *e, *f, *g;
+{
+}
+#endif
+
+#define RULE_NOOP	':'
+#define RULE_PREPEND	'^'
+#define RULE_APPEND	'$'
+#define RULE_REVERSE	'r'
+#define RULE_UPPERCASE	'u'
+#define RULE_LOWERCASE	'l'
+#define RULE_PLURALISE	'p'
+#define RULE_CAPITALISE	'c'
+#define RULE_DUPLICATE	'd'
+#define RULE_REFLECT	'f'
+#define RULE_SUBSTITUTE	's'
+#define RULE_MATCH	'/'
+#define RULE_NOT	'!'
+#define RULE_LT		'<'
+#define RULE_GT		'>'
+#define RULE_EXTRACT	'x'
+#define RULE_OVERSTRIKE	'o'
+#define RULE_INSERT	'i'
+#define RULE_EQUALS	'='
+#define RULE_PURGE	'@'
+#define RULE_CLASS	'?'	/* class rule? socialist ethic in cracker? */
+
+#define RULE_DFIRST	'['
+#define RULE_DLAST	']'
+#define RULE_MFIRST	'('
+#define RULE_MLAST	')'
+
+int
+Suffix(myword, suffix)
+    char *myword;
+    char *suffix;
+{
+    register int i;
+    register int j;
+    i = strlen(myword);
+    j = strlen(suffix);
+
+    if (i > j)
+    {
+	return (STRCMP((myword + i - j), suffix));
+    } else
+    {
+	return (-1);
+    }
+}
+
+char *
+Reverse(str)			/* return a pointer to a reversal */
+    register char *str;
+{
+    register int i;
+    register int j;
+    static char area[STRINGSIZE];
+    j = i = strlen(str);
+    while (*str)
+    {
+	area[--i] = *str++;
+    }
+    area[j] = '\0';
+    return (area);
+}
+
+char *
+Uppercase(str)			/* return a pointer to an uppercase */
+    register char *str;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*str)
+    {
+	*(ptr++) = CRACK_TOUPPER(*str);
+	str++;
+    }
+    *ptr = '\0';
+
+    return (area);
+}
+
+char *
+Lowercase(str)			/* return a pointer to an lowercase */
+    register char *str;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*str)
+    {
+	*(ptr++) = CRACK_TOLOWER(*str);
+	str++;
+    }
+    *ptr = '\0';
+
+    return (area);
+}
+
+char *
+Capitalise(str)			/* return a pointer to an capitalised */
+    register char *str;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+
+    while (*str)
+    {
+	*(ptr++) = CRACK_TOLOWER(*str);
+	str++;
+    }
+
+    *ptr = '\0';
+    area[0] = CRACK_TOUPPER(area[0]);
+    return (area);
+}
+
+char *
+Pluralise(string)		/* returns a pointer to a plural */
+    register char *string;
+{
+    register int length;
+    static char area[STRINGSIZE];
+    length = strlen(string);
+    strcpy(area, string);
+
+    if (!Suffix(string, "ch") ||
+	!Suffix(string, "ex") ||
+	!Suffix(string, "ix") ||
+	!Suffix(string, "sh") ||
+	!Suffix(string, "ss"))
+    {
+	/* bench -> benches */
+	strcat(area, "es");
+    } else if (length > 2 && string[length - 1] == 'y')
+    {
+	if (strchr("aeiou", string[length - 2]))
+	{
+	    /* alloy -> alloys */
+	    strcat(area, "s");
+	} else
+	{
+	    /* gully -> gullies */
+	    strcpy(area + length - 1, "ies");
+	}
+    } else if (string[length - 1] == 's')
+    {
+	/* bias -> biases */
+	strcat(area, "es");
+    } else
+    {
+	/* catchall */
+	strcat(area, "s");
+    }
+
+    return (area);
+}
+
+char *
+Substitute(string, old, new)	/* returns pointer to a swapped about copy */
+    register char *string;
+    register char old;
+    register char new;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*string)
+    {
+	*(ptr++) = (*string == old ? new : *string);
+	string++;
+    }
+    *ptr = '\0';
+    return (area);
+}
+
+char *
+Purge(string, target)		/* returns pointer to a purged copy */
+    register char *string;
+    register char target;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*string)
+    {
+	if (*string != target)
+	{
+	    *(ptr++) = *string;
+	}
+	string++;
+    }
+    *ptr = '\0';
+    return (area);
+}
+/* -------- CHARACTER CLASSES START HERE -------- */
+
+/*
+ * this function takes two inputs, a class identifier and a character, and
+ * returns non-null if the given character is a member of the class, based
+ * upon restrictions set out below
+ */
+
+int
+MatchClass(class, input)
+    register char class;
+    register char input;
+{
+    register char c;
+    register int retval;
+    retval = 0;
+
+    switch (class)
+    {
+	/* ESCAPE */
+
+    case '?':			/* ?? -> ? */
+	if (input == '?')
+	{
+	    retval = 1;
+	}
+	break;
+
+	/* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
+
+    case 'V':
+    case 'v':			/* vowels */
+	c = CRACK_TOLOWER(input);
+	if (strchr("aeiou", c))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'C':
+    case 'c':			/* consonants */
+	c = CRACK_TOLOWER(input);
+	if (strchr("bcdfghjklmnpqrstvwxyz", c))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'W':
+    case 'w':			/* whitespace */
+	if (strchr("\t ", input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'P':
+    case 'p':			/* punctuation */
+	if (strchr(".`,:;'!?\"", input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'S':
+    case 's':			/* symbols */
+	if (strchr("$%%^&*()-_+=|\\[]{}#@/~", input))
+	{
+	    retval = 1;
+	}
+	break;
+
+	/* LOGICAL GROUPINGS */
+
+    case 'L':
+    case 'l':			/* lowercase */
+	if (islower(input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'U':
+    case 'u':			/* uppercase */
+	if (isupper(input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'A':
+    case 'a':			/* alphabetic */
+	if (isalpha(input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'X':
+    case 'x':			/* alphanumeric */
+	if (isalnum(input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    case 'D':
+    case 'd':			/* digits */
+	if (isdigit(input))
+	{
+	    retval = 1;
+	}
+	break;
+
+    default:
+	Debug(1, "MatchClass: unknown class %c\n", class);
+	return (0);
+	break;
+    }
+
+    if (isupper(class))
+    {
+	return (!retval);
+    }
+    return (retval);
+}
+
+char *
+PolyStrchr(string, class)
+    register char *string;
+    register char class;
+{
+    while (*string)
+    {
+	if (MatchClass(class, *string))
+	{
+	    return (string);
+	}
+	string++;
+    }
+    return ((char *) 0);
+}
+
+char *
+PolySubst(string, class, new)	/* returns pointer to a swapped about copy */
+    register char *string;
+    register char class;
+    register char new;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*string)
+    {
+	*(ptr++) = (MatchClass(class, *string) ? new : *string);
+	string++;
+    }
+    *ptr = '\0';
+    return (area);
+}
+
+char *
+PolyPurge(string, class)	/* returns pointer to a purged copy */
+    register char *string;
+    register char class;
+{
+    register char *ptr;
+    static char area[STRINGSIZE];
+    ptr = area;
+    while (*string)
+    {
+	if (!MatchClass(class, *string))
+	{
+	    *(ptr++) = *string;
+	}
+	string++;
+    }
+    *ptr = '\0';
+    return (area);
+}
+/* -------- BACK TO NORMALITY -------- */
+
+int
+Char2Int(character)
+    char character;
+{
+    if (isdigit(character))
+    {
+	return (character - '0');
+    } else if (islower(character))
+    {
+	return (character - 'a' + 10);
+    } else if (isupper(character))
+    {
+	return (character - 'A' + 10);
+    }
+    return (-1);
+}
+
+char *
+Mangle(input, control)		/* returns a pointer to a controlled Mangle */
+    char *input;
+    char *control;
+{
+    int limit;
+    register char *ptr;
+    static char area[STRINGSIZE];
+    char area2[STRINGSIZE];
+    area[0] = '\0';
+    strcpy(area, input);
+
+    for (ptr = control; *ptr; ptr++)
+    {
+	switch (*ptr)
+	{
+	case RULE_NOOP:
+	    break;
+	case RULE_REVERSE:
+	    strcpy(area, Reverse(area));
+	    break;
+	case RULE_UPPERCASE:
+	    strcpy(area, Uppercase(area));
+	    break;
+	case RULE_LOWERCASE:
+	    strcpy(area, Lowercase(area));
+	    break;
+	case RULE_CAPITALISE:
+	    strcpy(area, Capitalise(area));
+	    break;
+	case RULE_PLURALISE:
+	    strcpy(area, Pluralise(area));
+	    break;
+	case RULE_REFLECT:
+	    strcat(area, Reverse(area));
+	    break;
+	case RULE_DUPLICATE:
+	    strcpy(area2, area);
+	    strcat(area, area2);
+	    break;
+	case RULE_GT:
+	    if (!ptr[1])
+	    {
+		Debug(1, "Mangle: '>' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		limit = Char2Int(*(++ptr));
+		if (limit < 0)
+		{
+		    Debug(1, "Mangle: '>' weird argument in '%s'\n", control);
+		    return ((char *) 0);
+		}
+		if (strlen(area) <= limit)
+		{
+		    return ((char *) 0);
+		}
+	    }
+	    break;
+	case RULE_LT:
+	    if (!ptr[1])
+	    {
+		Debug(1, "Mangle: '<' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		limit = Char2Int(*(++ptr));
+		if (limit < 0)
+		{
+		    Debug(1, "Mangle: '<' weird argument in '%s'\n", control);
+		    return ((char *) 0);
+		}
+		if (strlen(area) >= limit)
+		{
+		    return ((char *) 0);
+		}
+	    }
+	    break;
+	case RULE_PREPEND:
+	    if (!ptr[1])
+	    {
+		Debug(1, "Mangle: prepend missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		area2[0] = *(++ptr);
+		strcpy(area2 + 1, area);
+		strcpy(area, area2);
+	    }
+	    break;
+	case RULE_APPEND:
+	    if (!ptr[1])
+	    {
+		Debug(1, "Mangle: append missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register char *string;
+		string = area;
+		while (*(string++));
+		string[-1] = *(++ptr);
+		*string = '\0';
+	    }
+	    break;
+	case RULE_EXTRACT:
+	    if (!ptr[1] || !ptr[2])
+	    {
+		Debug(1, "Mangle: extract missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register int i;
+		int start;
+		int length;
+		start = Char2Int(*(++ptr));
+		length = Char2Int(*(++ptr));
+		if (start < 0 || length < 0)
+		{
+		    Debug(1, "Mangle: extract: weird argument in '%s'\n", control);
+		    return ((char *) 0);
+		}
+		strcpy(area2, area);
+		for (i = 0; length-- && area2[start + i]; i++)
+		{
+		    area[i] = area2[start + i];
+		}
+		/* cant use strncpy() - no trailing NUL */
+		area[i] = '\0';
+	    }
+	    break;
+	case RULE_OVERSTRIKE:
+	    if (!ptr[1] || !ptr[2])
+	    {
+		Debug(1, "Mangle: overstrike missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register int i;
+		i = Char2Int(*(++ptr));
+		if (i < 0)
+		{
+		    Debug(1, "Mangle: overstrike weird argument in '%s'\n",
+			  control);
+		    return ((char *) 0);
+		} else
+		{
+		    ++ptr;
+		    if (area[i])
+		    {
+			area[i] = *ptr;
+		    }
+		}
+	    }
+	    break;
+	case RULE_INSERT:
+	    if (!ptr[1] || !ptr[2])
+	    {
+		Debug(1, "Mangle: insert missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register int i;
+		register char *p1;
+		register char *p2;
+		i = Char2Int(*(++ptr));
+		if (i < 0)
+		{
+		    Debug(1, "Mangle: insert weird argument in '%s'\n",
+			  control);
+		    return ((char *) 0);
+		}
+		p1 = area;
+		p2 = area2;
+		while (i && *p1)
+		{
+		    i--;
+		    *(p2++) = *(p1++);
+		}
+		*(p2++) = *(++ptr);
+		strcpy(p2, p1);
+		strcpy(area, area2);
+	    }
+	    break;
+	    /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
+
+	case RULE_PURGE:	/* @x or @?c */
+	    if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
+	    {
+		Debug(1, "Mangle: delete missing arguments in '%s'\n", control);
+		return ((char *) 0);
+	    } else if (ptr[1] != RULE_CLASS)
+	    {
+		strcpy(area, Purge(area, *(++ptr)));
+	    } else
+	    {
+		strcpy(area, PolyPurge(area, ptr[2]));
+		ptr += 2;
+	    }
+	    break;
+	case RULE_SUBSTITUTE:	/* sxy || s?cy */
+	    if (!ptr[1] || !ptr[2] || (ptr[1] == RULE_CLASS && !ptr[3]))
+	    {
+		Debug(1, "Mangle: subst missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else if (ptr[1] != RULE_CLASS)
+	    {
+		strcpy(area, Substitute(area, ptr[1], ptr[2]));
+		ptr += 2;
+	    } else
+	    {
+		strcpy(area, PolySubst(area, ptr[2], ptr[3]));
+		ptr += 3;
+	    }
+	    break;
+	case RULE_MATCH:	/* /x || /?c */
+	    if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
+	    {
+		Debug(1, "Mangle: '/' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else if (ptr[1] != RULE_CLASS)
+	    {
+		if (!strchr(area, *(++ptr)))
+		{
+		    return ((char *) 0);
+		}
+	    } else
+	    {
+		if (!PolyStrchr(area, ptr[2]))
+		{
+		    return ((char *) 0);
+		}
+		ptr += 2;
+	    }
+	    break;
+	case RULE_NOT:		/* !x || !?c */
+	    if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
+	    {
+		Debug(1, "Mangle: '!' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else if (ptr[1] != RULE_CLASS)
+	    {
+		if (strchr(area, *(++ptr)))
+		{
+		    return ((char *) 0);
+		}
+	    } else
+	    {
+		if (PolyStrchr(area, ptr[2]))
+		{
+		    return ((char *) 0);
+		}
+		ptr += 2;
+	    }
+	    break;
+	    /*
+	     * alternative use for a boomerang, number 1: a standard throwing
+	     * boomerang is an ideal thing to use to tuck the sheets under
+	     * the mattress when making your bed.  The streamlined shape of
+	     * the boomerang allows it to slip easily 'twixt mattress and
+	     * bedframe, and it's curve makes it very easy to hook sheets
+	     * into the gap.
+	     */
+
+	case RULE_EQUALS:	/* =nx || =n?c */
+	    if (!ptr[1] || !ptr[2] || (ptr[2] == RULE_CLASS && !ptr[3]))
+	    {
+		Debug(1, "Mangle: '=' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register int i;
+		if ((i = Char2Int(ptr[1])) < 0)
+		{
+		    Debug(1, "Mangle: '=' weird argument in '%s'\n", control);
+		    return ((char *) 0);
+		}
+		if (ptr[2] != RULE_CLASS)
+		{
+		    ptr += 2;
+		    if (area[i] != *ptr)
+		    {
+			return ((char *) 0);
+		    }
+		} else
+		{
+		    ptr += 3;
+		    if (!MatchClass(*ptr, area[i]))
+		    {
+			return ((char *) 0);
+		    }
+		}
+	    }
+	    break;
+
+	case RULE_DFIRST:
+	    if (area[0])
+	    {
+		register int i;
+		for (i = 1; area[i]; i++)
+		{
+		    area[i - 1] = area[i];
+		}
+		area[i - 1] = '\0';
+	    }
+	    break;
+
+	case RULE_DLAST:
+	    if (area[0])
+	    {
+		register int i;
+		for (i = 1; area[i]; i++);
+		area[i - 1] = '\0';
+	    }
+	    break;
+
+	case RULE_MFIRST:
+	    if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
+	    {
+		Debug(1, "Mangle: '(' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		if (ptr[1] != RULE_CLASS)
+		{
+		    ptr++;
+		    if (area[0] != *ptr)
+		    {
+			return ((char *) 0);
+		    }
+		} else
+		{
+		    ptr += 2;
+		    if (!MatchClass(*ptr, area[0]))
+		    {
+			return ((char *) 0);
+		    }
+		}
+	    }
+	case RULE_MLAST:
+	    if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
+	    {
+		Debug(1, "Mangle: ')' missing argument in '%s'\n", control);
+		return ((char *) 0);
+	    } else
+	    {
+		register int i;
+
+		for (i = 0; area[i]; i++);
+
+		if (i > 0)
+		{
+		    i--;
+		} else
+		{
+		    return ((char *) 0);
+		}
+
+		if (ptr[1] != RULE_CLASS)
+		{
+		    ptr++;
+		    if (area[i] != *ptr)
+		    {
+			return ((char *) 0);
+		    }
+		} else
+		{
+		    ptr += 2;
+		    if (!MatchClass(*ptr, area[i]))
+		    {
+			return ((char *) 0);
+		    }
+		}
+	    }
+
+	default:
+	    Debug(1, "Mangle: unknown command %c in %s\n", *ptr, control);
+	    return ((char *) 0);
+	    break;
+	}
+    }
+    if (!area[0])		/* have we deweted de poor widdle fing away? */
+    {
+	return ((char *) 0);
+    }
+    return (area);
+}
+
+int
+PMatch(control, string)
+register char *control;
+register char *string;
+{
+    while (*string && *control)
+    {
+    	if (!MatchClass(*control, *string))
+    	{
+    	    return(0);
+    	}
+
+    	string++;
+    	control++;
+    }
+
+    if (*string || *control)
+    {
+    	return(0);
+    }
+
+    return(1);
+}

diff -Naur cracklib-2.8.3-orig/lib_heimdal/stringlib.c cracklib-2.8.3/lib_heimdal/stringlib.c
--- cracklib-2.8.3-orig/lib_heimdal/stringlib.c	1970-01-01 00:00:00.000000000 +0000
+++ cracklib-2.8.3/lib_heimdal/stringlib.c	2005-07-23 19:00:05.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ * This program is copyright Alec Muffett 1993. The author disclaims all 
+ * responsibility or liability with respect to it's usage or its effect 
+ * upon hardware or computer systems, and maintains copyright as set out 
+ * in the "LICENCE" document which accompanies distributions of Crack v4.0 
+ * and upwards.
+ */
+
+#include "config.h"
+#include <string.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include "packer_heimdal.h"
+
+static char vers_id[] = "stringlib.c : v2.3p2 Alec Muffett 18 May 1993";
+
+char
+Chop(string)
+    register char *string;
+{
+    register char c;
+    register char *ptr;
+    c = '\0';
+
+    for (ptr = string; *ptr; ptr++);
+    if (ptr != string)
+    {
+	c = *(--ptr);
+	*ptr = '\0';
+    }
+    return (c);
+}
+
+char *
+Trim(string)
+    register char *string;
+{
+    register char *ptr;
+    for (ptr = string; *ptr; ptr++);
+
+    while ((--ptr >= string) && isspace(*ptr));
+
+    *(++ptr) = '\0';
+
+    return (ptr);
+}
+
+char *
+Clone(string)
+    char *string;
+{
+    register char *retval;
+    retval = (char *) malloc(strlen(string) + 1);
+    if (retval)
+    {
+	strcpy(retval, string);
+    }
+    return (retval);
+}
