r4768 - in trunk: BOOK BOOK/introduction/welcome BOOK/postlfs/security patches

randy at linuxfromscratch.org randy at linuxfromscratch.org
Sun Jul 24 15:02:43 PDT 2005


Author: randy
Date: 2005-07-24 16:02:41 -0600 (Sun, 24 Jul 2005)
New Revision: 4768

Added:
   trunk/patches/cracklib-2.8.3-heimdal-1.patch
Removed:
   trunk/patches/cracklib,2.7-blfs-1.patch
   trunk/patches/cracklib,2.7-heimdal-1.patch
Modified:
   trunk/BOOK/general.ent
   trunk/BOOK/introduction/welcome/changelog.xml
   trunk/BOOK/postlfs/security/cracklib.xml
Log:
Updated to CrackLib-2.8.3

Modified: trunk/BOOK/general.ent
===================================================================
--- trunk/BOOK/general.ent	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/BOOK/general.ent	2005-07-24 22:02:41 UTC (rev 4768)
@@ -2,7 +2,7 @@
 <!ENTITY month        "07">
 <!ENTITY year         "2005">
 <!ENTITY version      "svn-&year;&month;&day;">
-<!ENTITY releasedate  "July &day;rd, &year;">
+<!ENTITY releasedate  "July &day;th, &year;">
 <!ENTITY pubdate      "&year;-&month;-&day;"> <!-- metadata req. by TLDP -->
 <!ENTITY blfs-version "svn">                  <!-- svn|[release #] -->
 <!ENTITY lfs-version  "stable">          <!-- version|stable|testing|unstable|development] -->
@@ -30,7 +30,7 @@
 
 <!-- Chapter 4 -->
 <!ENTITY openssl-version              "0.9.7g">
-<!ENTITY cracklib-version             "2.7">
+<!ENTITY cracklib-version             "2.8.3">
 <!ENTITY Linux_PAM-version            "0.78">
 <!ENTITY shadow-version               "4.0.9">
 <!ENTITY iptables-version             "1.3.1">

Modified: trunk/BOOK/introduction/welcome/changelog.xml
===================================================================
--- trunk/BOOK/introduction/welcome/changelog.xml	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/BOOK/introduction/welcome/changelog.xml	2005-07-24 22:02:41 UTC (rev 4768)
@@ -25,6 +25,10 @@
   <itemizedlist>
     
     <listitem>
+      <para>July 24th 2005 [randy]: Updated to CrackLib-2.8.3.</para>
+    </listitem>
+
+    <listitem>
       <para>July 23rd 2005 [djensen]: Added security patch to Mpg123.</para>
     </listitem>
 

Modified: trunk/BOOK/postlfs/security/cracklib.xml
===================================================================
--- trunk/BOOK/postlfs/security/cracklib.xml	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/BOOK/postlfs/security/cracklib.xml	2005-07-24 22:02:41 UTC (rev 4768)
@@ -4,18 +4,18 @@
   <!ENTITY % general-entities SYSTEM "../../general.ent">
   %general-entities;
 
-  <!ENTITY cracklib-download-http "http://www.crypticide.com/users/alecm/security/cracklib,&cracklib-version;.tar.gz">
-  <!ENTITY cracklib-download-ftp "ftp://ftp.cerias.purdue.edu/pub/tools/unix/libs/cracklib/cracklib.&cracklib-version;.tar.gz">
-  <!ENTITY cracklib-http-md5sum "0c84ad7413d9dd3e5c2eaa5f97d53c4a">
-  <!ENTITY cracklib-ftp-md5sum  "7f810e310c7f2df33d1eaa2b41ab2435">
-  <!ENTITY cracklib-size      "21 KB">
-  <!ENTITY cracklib-buildsize "21.8 MB">
-  <!ENTITY cracklib-time      "0.05 SBU">
-  <!ENTITY crackdict-size     "15.6 MB">
-  <!ENTITY alldict-size       "466 KB">
+  <!ENTITY cracklib-download-http "http://prdownloads.sourceforge.net/cracklib/cracklib-&cracklib-version;.tar.gz">
+  <!ENTITY cracklib-download-ftp  " ">
+  <!ENTITY cracklib-http-md5sum   "13f82f75b892cbd0ba7cb9069e307006">
+  <!ENTITY cracklib-size          "480 KB">
+  <!ENTITY cracklib-buildsize     "27.6 MB">
+  <!ENTITY cracklib-time          "0.1 SBU">
+  <!ENTITY crackdict-download     "http://prdownloads.sourceforge.net/cracklib/cracklib-words.gz">
+  <!ENTITY crackdict-size         "4.4 MB">
+  <!ENTITY crackdict-md5sum       "d18e670e5df560a8745e1b4dede8f84f">
 ]>
 
-<sect1 id="cracklib" xreflabel="cracklib-&cracklib-version;">
+<sect1 id="cracklib" xreflabel="CrackLib-&cracklib-version;">
   <?dbhtml filename="cracklib.html"?>
 
   <sect1info>
@@ -23,18 +23,18 @@
     <date>$Date$</date>
   </sect1info>
 
-  <title>Cracklib-&cracklib-version;</title>
+  <title>CrackLib-&cracklib-version;</title>
 
   <indexterm zone="cracklib">
-    <primary sortas="a-Cracklib">Cracklib</primary>
+    <primary sortas="a-CrackLib">CrackLib</primary>
   </indexterm>
 
   <sect2 role="package">
-    <title>Introduction to Cracklib</title>
+    <title>Introduction to CrackLib</title>
 
-    <para>The <application>cracklib</application> package contains a
+    <para>The <application>CrackLib</application> package contains a
     library used to enforce strong passwords by comparing user selected
-    passwords to words in a chosen wordlist.</para>
+    passwords to words in chosen word lists.</para>
 
     <bridgehead renderas="sect3">Package Information</bridgehead>
     <itemizedlist spacing="compact">
@@ -45,12 +45,9 @@
         <para>Download (FTP): <ulink url="&cracklib-download-ftp;"/></para>
       </listitem>
       <listitem>
-        <para>Download MD5 sum (HTTP): &cracklib-http-md5sum;</para>
+        <para>Download MD5 sum: &cracklib-http-md5sum;</para>
       </listitem>
       <listitem>
-        <para>Download MD5 sum (FTP): &cracklib-ftp-md5sum;</para>
-      </listitem>
-      <listitem>
         <para>Download size: &cracklib-size;</para>
       </listitem>
       <listitem>
@@ -64,85 +61,99 @@
     <bridgehead renderas="sect3">Additional Downloads</bridgehead>
     <itemizedlist spacing='compact'>
       <listitem>
-        <para>Required Patch: <ulink
-        url="&patch-root;/cracklib,&cracklib-version;-blfs-1.patch"/></para>
+        <para>Recommended word list (size: &crackdict-size;;
+        md5sum: &crackdict-md5sum;): <ulink url="&crackdict-download;"/></para>
       </listitem>
       <listitem>
-        <para>Recommended Patch: <ulink
-        url="&patch-root;/cracklib,&cracklib-version;-heimdal-1.patch"/></para>
+        <para>Required patch to create a library used with the Heimdal
+        Kerberos 5 package: <ulink
+        url="&patch-root;/cracklib-&cracklib-version;-heimdal-1.patch"/></para>
       </listitem>
     </itemizedlist>
 
-    <para>You will also need to download a wordlist for use with
+    <!-- <para>You will also need to download a wordlist for use with
     <application>cracklib</application>. There are two wordlists
     to choose from at the following location.  Use the
     <filename>cracklib</filename> word list for good security, or
     opt for the <filename>allwords</filename> word list for
     lightweight machines short on RAM. You can of course choose
-    any other word list that you have at your disposal.</para>
+    any other word list that you have at your disposal.</para> -->
 
-    <itemizedlist spacing='compact'>
-      <listitem>
-        <para>cracklib (&crackdict-size;) at <ulink
-        url="http://www.cotse.com/tools/wordlists.htm"/></para>
-      </listitem>
-      <listitem>
-        <para>allwords (&alldict-size;) at <ulink
-        url="http://www.cotse.com/tools/wordlists.htm"/></para>
-      </listitem>
-    </itemizedlist>
-
   </sect2>
 
   <sect2 role="installation">
-    <title>Installation of Cracklib</title>
+    <title>Installation of CrackLib</title>
 
-    <para>First, as the <systemitem class="username">root</systemitem>
-    user, install the chosen word list for
-    <application>cracklib</application>:</para>
+    <para>If desired, apply the <application>Heimdal</application> patch
+    (note that with this patch the original library is not affected; this patch
+    only creates an additional library used by the
+    <application>Heimdal</application> password-checking routines):</para>
 
-<screen role="root"><userinput>install -v -d -m755 /usr/share/dict &&
-install -v -m644 ../<replaceable>[wordlist]</replaceable> /usr/share/dict &&
-ln -v -sf <replaceable>[wordlist]</replaceable> /usr/share/dict/words &&
-echo $(hostname) >> /usr/share/dict/extra.words</userinput></screen>
+<screen><userinput>patch -Np1 -i ../cracklib-&cracklib-version;-heimdal-1.patch</userinput></screen>
 
-    <para>The wordlist is linked to <filename>/usr/share/dict/words</filename>
-    as historically, <filename>words</filename> is the primary wordlist in the
-    <filename class="directory">/usr/share/dict</filename> directory.
-    Additionally, the value of <command>hostname</command> is echoed to a file
-    called <filename>extra.words</filename>. This extra file is intended to be
-    a site specific list which includes easy to guess passwords such as company
-    or department names, user's names, product names, computer names, domain
-    names, etc.</para>
+    <para>Install <application>CrackLib</application> by running the following
+    commands:</para>
 
-    <para>Now apply the BLFS patch:</para>
+<screen><userinput>./configure --prefix=/usr --datadir=/lib &&
+make</userinput></screen>
 
-<screen><userinput>patch -Np1 -i ../cracklib,&cracklib-version;-blfs-1.patch</userinput></screen>
+    <para>Now, as the <systemitem class="username">root</systemitem> user:</para>
 
-    <para>If necessary, apply the <application>Heimdal</application>
-    patch:</para>
+<screen role="root"><userinput>make install &&
+mv -v /usr/lib/libcrack.so.2* /lib &&
+ln -v -sf ../../lib/libcrack.so.2.8.0 /usr/lib/libcrack.so &&
+install -v -m644 -D ../cracklib-words.gz \
+    /usr/share/dict/cracklib-words.gz &&
+gunzip -v /usr/share/dict/cracklib-words.gz &&
+ln -v -s cracklib-words /usr/share/dict/words &&
+echo $(hostname) >>/usr/share/dict/cracklib-extra-words &&
+create-cracklib-dict /usr/share/dict/cracklib-words \
+                     /usr/share/dict/cracklib-extra-words</userinput></screen>
 
-<screen><userinput>cp -R cracklib cracklib_krb5 &&
-patch -Np1 -i ../cracklib,&cracklib-version;-heimdal-1.patch</userinput></screen>
+    <para>If desired, check the proper operation of the library as an
+    unprivileged user using the tests included with the package:</para>
 
-    <para>Finally, as the <systemitem class="username">root</systemitem>
-    user, build and install the package:</para>
+<screen><userinput>make test</userinput></screen>
 
-<screen role="root"><userinput>make install &&
-rm -v /lib/libcrack.so &&
-ln -v -sf ../../lib/libcrack.so.2.7 /usr/lib/libcrack.so</userinput></screen>
-
   </sect2>
 
   <sect2 role="commands">
     <title>Command Explanations</title>
 
-    <para><command>rm -v /lib/libcrack.so; ln -v -sf ...
-    /usr/lib/libcrack.so</command>: These two commands move the
-    <filename class='symlink'>libcrack.so</filename>
-    symlink from <filename class='directory'>/lib</filename> to
-    <filename class='directory'>/usr/lib</filename>.</para>
+    <para><parameter>--datadir=/lib</parameter>: This parameter forces the
+    installation of the <application>CrackLib</application> dictionary to the
+    <filename class='directory'>/lib</filename> hierarchy.</para>
 
+    <para><command>mv -v /usr/lib/libcrack.so.2* /lib</command> and
+    <command>ln -v -sf ../../lib/libcrack.so.2.8.0 ...</command>: These two
+    commands move the <filename class='libraryfile'>libcrack.so.2.8.0</filename>
+    library and associated symlink from
+    <filename class='directory'>/usr/lib</filename> to
+    <filename class='directory'>/lib</filename>, then recreates the
+    <filename class='symlink'>/usr/lib/libcrack.so</filename> symlink to point
+    to the relocated file.</para>
+
+    <para><command>install -v -m644 -D ...</command>: This command creates the
+    <filename class='directory'>/usr/share/dict</filename> directory (if it
+    doesn't already exist) and installs the compressed word list there.</para>
+
+    <para><command>ln -v -s cracklib-words /usr/share/dict/words</command>: The
+    word list is linked to <filename>/usr/share/dict/words</filename> as
+    historically, <filename>words</filename> is the primary word list in the
+    <filename class="directory">/usr/share/dict</filename> directory. Omit this
+    command if you already have a <filename>/usr/share/dict/words</filename>
+    file installed on your system.</para>
+
+    <para><command>echo $(hostname) >>...</command>: The value of
+    <command>hostname</command> is echoed to a file called
+    <filename>cracklib-extra-words</filename>. This extra file is intended to be
+    a site specific list which includes easy to guess passwords such as company
+    or department names, user's names, product names, computer names, domain
+    names, etc.</para>
+
+    <para><command>create-cracklib-dict ...</command>: This command creates the
+    <application>CrackLib</application> dictionary from the word lists.</para>
+
   </sect2>
 
   <sect2 role="content">
@@ -154,9 +165,10 @@
       <segtitle>Installed Directory</segtitle>
 
       <seglistitem>
-        <seg>create-cracklib-dict, mkdict, and packer</seg>
-        <seg>libcrack.so and optionally, libcrack_krb5.so</seg>
-        <seg>/usr/share/dict</seg>
+        <seg>cracklib-check, cracklib-format, cracklib-packer,
+        cracklib-unpacker and create-cracklib-dict</seg>
+        <seg>libcrack.[so,a] and optionally, libcrack_heimdal.[so,a]</seg>
+        <seg>/lib/cracklib and /usr/share/dict</seg>
       </seglistitem>
     </segmentedlist>
 
@@ -165,13 +177,24 @@
       <?dbfo list-presentation="list"?>
       <?dbhtml list-presentation="table"?>
 
+      <varlistentry id="create-cracklib-dict">
+        <term><filename>create-cracklib-dict</filename></term>
+        <listitem>
+          <para>is used to create the <application>CrackLib</application>
+          dictionary from the given word list(s).</para>
+          <indexterm zone="cracklib create-cracklib-dict">
+            <primary sortas="b-create-cracklib-dict">create-cracklib-dict</primary>
+          </indexterm>
+        </listitem>
+      </varlistentry>
+
       <varlistentry id="libcrack">
-        <term><filename class='libraryfile'>libcrack.so</filename></term>
+        <term><filename class='libraryfile'>libcrack.[so,a]</filename></term>
         <listitem>
-          <para>provide a fast dictionary lookup method for strong
+          <para>provides a fast dictionary lookup method for strong
           password enforcement.</para>
           <indexterm zone="cracklib libcrack">
-            <primary sortas="c-libcrack">libcrack.so</primary>
+            <primary sortas="c-libcrack">libcrack.[so,a]</primary>
           </indexterm>
         </listitem>
       </varlistentry>

Deleted: trunk/patches/cracklib,2.7-blfs-1.patch
===================================================================
--- trunk/patches/cracklib,2.7-blfs-1.patch	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/patches/cracklib,2.7-blfs-1.patch	2005-07-24 22:02:41 UTC (rev 4768)
@@ -1,194 +0,0 @@
-Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
-Date: 2004-04-22
-Initial Package Version: 2,7
-Origin: Jim Gifford & DJ Lucas
-Description: Makes Cracklib a dynamic library installed at /lib
-             Fixes buffer underruns
-             Add's missing header
-             Install's Missing Headers
-
-$LastChangedBy$
-$Date$
-
-diff -Naur cracklib,2.7-orig/Makefile cracklib,2.7/Makefile
---- cracklib,2.7-orig/Makefile	1997-12-31 04:33:53.000000000 -0600
-+++ cracklib,2.7/Makefile	2004-04-30 16:58:01.000000000 -0500
-@@ -7,14 +7,21 @@
- ###
- 
- ###
-+# cracklib version
-+MAJOR=2
-+MINOR=7
-+VERSION=$(MAJOR).$(MINOR)
-+export MAJOR MINOR VERSION
-+
-+###
- # set this to the absolute path (less extn) of compressed dict.
- 
--DICTPATH="/usr/local/lib/pw_dict"
-+DICTPATH="/lib/cracklib_dict"
- 
- ###
- # Set this to the path of one or more files continaing wordlists.
- 
--SRCDICTS=/usr/dict/words
-+SRCDICTS=/usr/share/dict/words /usr/share/dict/extra.words
- 
- ###
- # If you have installed the cracklib-dicts directory, use this
-@@ -36,7 +43,9 @@
- 	-rm -f all installed Part* *.BAK *.bak *~
- 
- install: all
-+	( cd cracklib && make install && exit $$? )
-+	( cd util && make install && exit $$? )
- 	@echo 'if "sort" dies from lack of space, see "util/mkdict"'
--	util/mkdict $(SRCDICTS) | util/packer $(DICTPATH)
-+	util/mkdict $(SRCDICTS) | LD_LIBRARY_PATH=cracklib util/packer $(DESTDIR)$(DICTPATH)
- 	touch installed
- ###	@echo 'now go install passwd/passwd where you want it'
-diff -Naur cracklib,2.7-orig/cracklib/Makefile cracklib,2.7/cracklib/Makefile
---- cracklib,2.7-orig/cracklib/Makefile	1997-12-14 16:49:21.000000000 -0600
-+++ cracklib,2.7/cracklib/Makefile	2004-04-30 16:58:01.000000000 -0500
-@@ -6,13 +6,24 @@
- # and upwards.
- ###
- 
--LIB=	libcrack.a
--OBJ=	fascist.o packlib.o rules.o stringlib.o
--CFLAGS= -O -I../cracklib -DIN_CRACKLIB
-+LIB	= libcrack.so
-+OBJ	= fascist.o packlib.o rules.o stringlib.o
-+CFLAGS += -g -I../cracklib -DIN_CRACKLIB -fPIC
-+LD	= ld
- 
--$(LIB):	$(OBJ)
--	ar rv $(LIB) $?
--	-ranlib $(LIB)
-+$(LIB):	$(OBJ) Makefile
-+	$(LD) -shared -soname $(LIB).$(MAJOR) -o $(LIB).$(VERSION) $(OBJ) -lc
-+	rm -f $(LIB).$(MAJOR) $(LIB)
-+	ln -s $(LIB).$(VERSION) $(LIB).$(MAJOR)
-+	ln -s $(LIB).$(MAJOR) $(LIB)
- 
- clean:
--	-rm -f $(OBJ) $(LIB) *~
-+	-rm -f $(OBJ) $(LIB) $(LIB).$(VERSION) *~
-+
-+install: $(LIB) crack.h
-+	install -m 755 $(LIB).$(VERSION) $(DESTDIR)/lib
-+	ln -sf $(LIB).$(VERSION) $(DESTDIR)/lib/$(LIB)
-+	ln -sf $(DESTDIR)/lib/$(LIB).$(VERSION) $(DESTDIR)/lib/$(LIB).$(MAJOR)
-+
-+	install -m 644 packer.h $(DESTDIR)/usr/include
-+	install -m 644 crack.h $(DESTDIR)/usr/include
-diff -Naur cracklib,2.7-orig/cracklib/crack.h cracklib,2.7/cracklib/crack.h
---- cracklib,2.7-orig/cracklib/crack.h	1969-12-31 18:00:00.000000000 -0600
-+++ cracklib,2.7/cracklib/crack.h	2004-04-30 17:11:03.000000000 -0500
-@@ -0,0 +1,15 @@
-+
-+#ifndef CRACKLIB_H
-+#define CRACKLIB_H
-+
-+/* Pass this function a password (pw) and a path to the
-+ * dictionaries (/lib/cracklib_dict should be specified)
-+ * and it will either return a NULL string, meaning that the
-+ * password is good, or a pointer to a string that explains the
-+ * problem with the password.
-+ * You must link with -lcrack
-+ */
-+
-+extern char *FascistCheck(char *pw, char *dictpath);
-+
-+#endif
-diff -Naur cracklib,2.7-orig/cracklib/fascist.c cracklib,2.7/cracklib/fascist.c
---- cracklib,2.7-orig/cracklib/fascist.c	1997-12-31 04:26:46.000000000 -0600
-+++ cracklib,2.7/cracklib/fascist.c	2004-04-30 16:58:01.000000000 -0500
-@@ -11,6 +11,7 @@
- #include "packer.h"
- #include <sys/types.h>
- #include <pwd.h>
-+#include <string.h>
- 
- #define ISSKIP(x) (isspace(x) || ispunct(x))
- 
-@@ -659,7 +660,7 @@
- 	return ("it does not contain enough DIFFERENT characters");
-     }
- 
--    strcpy(password, Lowercase(password));
-+    strcpy(password, (char *)Lowercase(password));
- 
-     Trim(password);
- 
-@@ -722,7 +723,7 @@
- 	}
-     }
- 
--    strcpy(password, Reverse(password));
-+    strcpy(password, (char *)Reverse(password));
- 
-     for (i = 0; r_destructors[i]; i++)
-     {
-diff -Naur cracklib,2.7-orig/util/Makefile cracklib,2.7/util/Makefile
---- cracklib,2.7-orig/util/Makefile	1997-12-14 16:49:34.000000000 -0600
-+++ cracklib,2.7/util/Makefile	2004-04-30 16:58:01.000000000 -0500
-@@ -14,27 +14,31 @@
- #SunOS users (and others?) should consider static linking of their passwd binary
- #CFLAGS= -O -I../cracklib '-DCRACKLIB_DICTPATH="$(DICTPATH)"' -Bstatic
- 
--CFLAGS= -O -I../cracklib '-DCRACKLIB_DICTPATH="$(DICTPATH)"'
--LIBS=	../cracklib/libcrack.a
-+CFLAGS += -I../cracklib '-DCRACKLIB_DICTPATH="$(DICTPATH)"'
-+LDFLAGS	= -L../cracklib -lcrack
-+LIBS	= ../cracklib/libcrack.so
- 
- all:	packer unpacker testnum teststr testlib
- 	touch all
- 
- packer: packer.o $(LIBS)
--	cc $(CFLAGS) -o $@ $@.o $(LIBS)
-+	$(CC) $(CFLAGS) -o $@ $@.o $(LDFLAGS)
- 
- unpacker: unpacker.o $(LIBS)
--	cc $(CFLAGS) -o $@ $@.o $(LIBS)
-+	$(CC) $(CFLAGS) -o $@ $@.o $(LDFLAGS)
- 
- testnum: testnum.o $(LIBS)
--	cc $(CFLAGS) -o $@ $@.o $(LIBS)
-+	$(CC) $(CFLAGS) -o $@ $@.o $(LDFLAGS)
- 
- teststr: teststr.o $(LIBS)
--	cc $(CFLAGS) -o $@ $@.o $(LIBS)
-+	$(CC) $(CFLAGS) -o $@ $@.o $(LDFLAGS)
- 
- testlib: testlib.o $(LIBS)
--	cc $(CFLAGS) -o $@ $@.o $(LIBS)
-+	$(CC) $(CFLAGS) -o $@ $@.o $(LDFLAGS)
- 
- clean:
- 	-rm *.o *~ all
- 	-rm teststr testnum testlib packer unpacker
-+
-+install: all create-cracklib-dict
-+	install -m 755 mkdict packer create-cracklib-dict $(DESTDIR)/usr/sbin
-diff -Naur cracklib,2.7-orig/util/create-cracklib-dict cracklib,2.7/util/create-cracklib-dict
---- cracklib,2.7-orig/util/create-cracklib-dict	1969-12-31 18:00:00.000000000 -0600
-+++ cracklib,2.7/util/create-cracklib-dict	2004-04-30 16:58:01.000000000 -0500
-@@ -0,0 +1,15 @@
-+#!/bin/sh
-+if [ -z "$*" ]; then
-+    echo "Usage:"
-+    echo "  /usr/sbin/create-cracklib-dict wordlist ..."
-+    echo
-+    echo "This script takes one or more word list files as arguments"
-+    echo "and converts them into cracklib dictionaries for use"
-+    echo "by password checking programs. The results are placed in"
-+    echo "/lib/cracklib_dict.*"
-+    echo
-+    echo "Example:"
-+    echo "/usr/sbin/create-cracklib-dict /usr/dict/words"
-+else
-+    /usr/sbin/mkdict $* | /usr/sbin/packer /usr/share/cracklib/pw_dict
-+fi

Deleted: trunk/patches/cracklib,2.7-heimdal-1.patch
===================================================================
--- trunk/patches/cracklib,2.7-heimdal-1.patch	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/patches/cracklib,2.7-heimdal-1.patch	2005-07-24 22:02:41 UTC (rev 4768)
@@ -1,200 +0,0 @@
-Submitted By: Randy McMurchy (LFS-User_AT_mcmurchy_DOT_com)
-Date: 2004-05-03
-Initial Package Version: 2.7
-Origin: Randy McMurchy and ftp://ftp.pdc.kth.se/pub/krb/src/cracklib.patch 
-Description: Patches cracklib to work with Heimdal Kerberos 5
-             Requires heimdal-0.6.3-cracklib-1.patch applied to the Heimdal
-             source code. Patch is available at:
-             http://www.linuxfromscratch.org/patches/blfs/cvs/
-
-$LastChangedBy$
-$Date$
-
-diff -Naur cracklib,2.7-orig/Makefile cracklib,2.7/Makefile
---- cracklib,2.7-orig/Makefile	2004-05-01 00:41:30.000000000 +0000
-+++ cracklib,2.7/Makefile	2004-05-01 01:07:16.000000000 +0000
-@@ -32,18 +32,21 @@
- 
- all:
- 	( cd cracklib && make && exit $$? )
-+	( cd cracklib_krb5 && make && exit $$? )
- 	( cd util && make DICTPATH=$(DICTPATH) && exit $$? )
- ###	( cd passwd && make DICTPATH=$(DICTPATH) passwd && exit $$? )
- ###	touch all
- 
- clean:
- 	-( cd cracklib && make clean && exit $$? )
-+	-( cd cracklib_krb5 && make clean && exit $$? )
- 	-( cd util && make clean && exit $$? )
- ###	-( cd passwd && make clean && exit $$? )
- 	-rm -f all installed Part* *.BAK *.bak *~
- 
- install: all
- 	( cd cracklib && make install && exit $$? )
-+	( cd cracklib_krb5 && make install && exit $$? )
- 	( cd util && make install && exit $$? )
- 	@echo 'if "sort" dies from lack of space, see "util/mkdict"'
- 	util/mkdict $(SRCDICTS) | LD_LIBRARY_PATH=cracklib util/packer $(DESTDIR)$(DICTPATH)
-
-diff -Naur cracklib,2.7-orig/cracklib_krb5/Makefile cracklib,2.7/cracklib_krb5/Makefile
---- cracklib,2.7-orig/cracklib_krb5/Makefile	2004-05-01 01:02:47.000000000 +0000
-+++ cracklib,2.7/cracklib_krb5/Makefile	2004-05-01 02:03:26.000000000 +0000
-@@ -6,9 +6,9 @@
- # and upwards.
- ###
- 
--LIB	= libcrack.so
-+LIB	= libcrack_krb5.so
- OBJ	= fascist.o packlib.o rules.o stringlib.o
--CFLAGS += -g -I../cracklib -DIN_CRACKLIB -fPIC
-+CFLAGS += -g -I../cracklib_krb5 -DIN_CRACKLIB_KRB5 -fPIC
- LD	= ld
- 
- $(LIB):	$(OBJ) Makefile
-@@ -20,10 +20,9 @@
- clean:
- 	-rm -f $(OBJ) $(LIB) $(LIB).$(VERSION) *~
- 
--install: $(LIB) crack.h
--	install -m 755 $(LIB).$(VERSION) $(DESTDIR)/lib
--	ln -sf $(LIB).$(VERSION) $(DESTDIR)/lib/$(LIB)
--	ln -sf $(DESTDIR)/lib/$(LIB).$(VERSION) $(DESTDIR)/lib/$(LIB).$(MAJOR)
-+install: $(LIB) crack_krb5.h
-+	install -m 755 $(LIB).$(VERSION) $(DESTDIR)/usr/lib
-+	ln -sf $(LIB).$(VERSION) $(DESTDIR)/usr/lib/$(LIB)
-+	ln -sf $(LIB).$(VERSION) $(DESTDIR)/usr/lib/$(LIB).$(MAJOR)
- 
--	install -m 644 packer.h $(DESTDIR)/usr/include
--	install -m 644 crack.h $(DESTDIR)/usr/include
-+	install -m 644 crack_krb5.h $(DESTDIR)/usr/include
-
-diff -Naur cracklib,2.7-orig/cracklib_krb5/crack_krb5.h cracklib,2.7/cracklib_krb5/crack_krb5.h
---- cracklib,2.7-orig/cracklib_krb5/crack_krb5.h	2004-05-01 01:03:13.000000000 +0000
-+++ cracklib,2.7/cracklib_krb5/crack_krb5.h	2004-05-01 01:01:08.000000000 +0000
-@@ -0,0 +1,16 @@
-+#ifndef CRACKLIB_KRB5_H
-+#define CRACKLIB_KRB5_H
-+
-+/* 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_krb5
-+ */
-+
-+extern char *FascistCheck(char *pw, char *dictpath, char *strings);
-+
-+#define CRACKLIB_DICTPATH "/lib/cracklib_dict"
-+
-+#endif
-
-diff -Naur cracklib,2.7-orig/cracklib_krb5/fascist.c cracklib,2.7/cracklib_krb5/fascist.c
---- cracklib,2.7-orig/cracklib_krb5/fascist.c	2004-05-01 01:02:47.000000000 +0000
-+++ cracklib,2.7/cracklib_krb5/fascist.c	2004-05-01 01:35:59.000000000 +0000
-@@ -478,6 +478,23 @@
- }
- 
- 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;
-@@ -614,9 +631,10 @@
- }
- 
- char *
--FascistLook(pwp, instring)
-+FascistLook(pwp, instring, strings)
-     PWDICT *pwp;
-     char *instring;
-+    char **strings;
- {
-     int i;
-     char *ptr;
-@@ -695,10 +713,16 @@
- 	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;
-@@ -746,9 +770,10 @@
- }
- 
- char *
--FascistCheck(password, path)
-+FascistCheck(password, path, strings)
-     char *password;
-     char *path;
-+    char **strings;
- {
-     static char lastpath[STRINGSIZE];
-     static PWDICT *pwp;
-@@ -781,5 +806,5 @@
- 	strncpy(lastpath, path, STRINGSIZE);
-     }
- 
--    return (FascistLook(pwp, pwtrunced));
-+    return (FascistLook(pwp, pwtrunced, strings));
- }
-
-diff -Naur cracklib,2.7-orig/cracklib_krb5/packlib.c cracklib,2.7/cracklib_krb5/packlib.c
---- cracklib,2.7-orig/cracklib_krb5/packlib.c	2004-05-01 01:02:47.000000000 +0000
-+++ cracklib,2.7/cracklib_krb5/packlib.c	2004-05-01 01:34:10.000000000 +0000
-@@ -329,6 +329,13 @@
- #ifdef DEBUG
- 	printf("%lu, %lu\n", lwm, hwm);
- #endif
-+	if (lwm > hwm) {
-+	     register int32 tmp;
-+
-+	     tmp = hwm;
-+	     hwm = lwm;
-+	     lwm = tmp;
-+	}
- 
- 	middle = lwm + ((hwm - lwm + 1) / 2);
- 
-
-diff -Naur cracklib,2.7-orig/cracklib_krb5/rules.c cracklib,2.7/cracklib_krb5/rules.c
---- cracklib,2.7-orig/cracklib_krb5/rules.c	2004-05-01 01:02:47.000000000 +0000
-+++ cracklib,2.7/cracklib_krb5/rules.c	2004-05-01 01:57:58.000000000 +0000
-@@ -8,9 +8,9 @@
- 
- static char vers_id[] = "rules.c : v5.0p3 Alec Muffett 20 May 1993";
- 
--#ifndef IN_CRACKLIB
-+#ifndef IN_CRACKLIB_KRB5
- 
--#include "crack.h"
-+#include "crack_krb5.h"
- 
- #else
- 

Added: trunk/patches/cracklib-2.8.3-heimdal-1.patch
===================================================================
--- trunk/patches/cracklib-2.8.3-heimdal-1.patch	2005-07-24 19:48:24 UTC (rev 4767)
+++ trunk/patches/cracklib-2.8.3-heimdal-1.patch	2005-07-24 22:02:41 UTC (rev 4768)
@@ -0,0 +1,3027 @@
+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$
+$Date$
+
+
+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.
++
++ at 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
++ at AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/fascist.Plo ./$(DEPDIR)/packlib.Plo \
++ at 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
++
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fascist.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/packlib.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rules.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stringlib.Plo at am__quote@
++
++.c.o:
++ at am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
++ at am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
++ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
++ at am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
++ at am__fastdepCC_TRUE@	fi
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++ at am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
++
++.c.obj:
++ at am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
++ at am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
++ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
++ at am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
++ at am__fastdepCC_TRUE@	fi
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++ at am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
++
++.c.lo:
++ at am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
++ at am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
++ at am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
++ at am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
++ at am__fastdepCC_TRUE@	fi
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++ at 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);
++}


Property changes on: trunk/patches/cracklib-2.8.3-heimdal-1.patch
___________________________________________________________________
Name: svn:keywords
   + LastChangedBy Date




More information about the blfs-book mailing list