[4/4] New configure option --disable-crypt.

Message ID 20180521173853.5172-5-zackw@panix.com
State Committed
Headers

Commit Message

Zack Weinberg May 21, 2018, 5:38 p.m. UTC
  Some Linux distributions are experimenting with a new, separately
maintained and hopefully more agile implementation of the crypt(3)
API.  To facilitate this, add a configure option which disables
glibc's embedded libcrypt.  When this option is given, libcrypt.*
and crypt.h will not be built nor installed.

unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.

The bulk of the patch is just various places that need to take note of
libcrypt possibly not getting built.

        * configure.ac: New command-line option --disable-crypt.
        Force --disable-nss-crypt when --disable-crypt is given, with a
        warning if it was explicitly enabled.
        * configure: Regenerate.
        * config.make.in: New boolean substitution variable $(build-crypt).
        * Makeconfig: Only include 'crypt' in all-subdirs and rpath-dirs
        when $(build-crypt).
        * manual/install.texi: Document --disable-crypt.
        * INSTALL: Regenerate.

        * crypt/Makefile: Remove code conditional on $(crypt-in-libc),
        which is never set.
        * conform/Makefile: Only include libcrypt.a in
        linknamespace-libs-xsi and linknamespace-libs-XPG4
        when $(build-crypt).
        * elf/Makefile (CFLAGS-tst-linkall-static.c): Only define
        USE_CRYPT to 1 when $(build-crypt).
        (tst-linkall-static): Only link libcrypt.a when $(build-crypt).
        (localplt-built-dso): Only add libcrypt.so when $(build-crypt).
        * elf/tst-linkall-static.c: Only include crypt.h when USE_CRYPT.
---
 INSTALL                  | 11 +++++++++++
 Makeconfig               |  9 +++++++--
 NEWS                     | 13 +++++++++++++
 config.make.in           |  1 +
 configure                | 18 ++++++++++++++++++
 configure.ac             | 11 +++++++++++
 conform/Makefile         | 11 +++++++----
 crypt/Makefile           |  4 ----
 elf/Makefile             | 27 +++++++++++++++++++--------
 elf/tst-linkall-static.c |  4 +++-
 manual/install.texi      | 12 ++++++++++++
 11 files changed, 102 insertions(+), 19 deletions(-)
  

Comments

Joseph Myers May 21, 2018, 7:51 p.m. UTC | #1
On Mon, 21 May 2018, Zack Weinberg wrote:

> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.

I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt 
and setkey.
  
Zack Weinberg May 21, 2018, 10:07 p.m. UTC | #2
On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
>
>> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>
> I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
> and setkey.

No, this is an intentional deviation from the present state of POSIX,
anticipating the removal of those functions from the standard.

zw
  
Joseph Myers May 21, 2018, 10:34 p.m. UTC | #3
On Mon, 21 May 2018, Zack Weinberg wrote:

> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> > On Mon, 21 May 2018, Zack Weinberg wrote:
> >
> >> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
> >
> > I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
> > and setkey.
> 
> No, this is an intentional deviation from the present state of POSIX,
> anticipating the removal of those functions from the standard.

That would only seem relevant to the _XOPEN_CRYPT value in future POSIX 
modes, not current ones.

The conform/ data is in any case meant to correspond to the standard 
versions in question (plus defect corrections from TCs etc., not plus 
feature changes from other revisions to the standard).  Intentionally 
unsupported features are listed in that data with appropriate XFAILs (see 
e.g. those for varargs.h in conform/Makefile).
  
Zack Weinberg May 22, 2018, 1:08 a.m. UTC | #4
On Mon, May 21, 2018 at 6:34 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
>
>> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>> > On Mon, 21 May 2018, Zack Weinberg wrote:
>> >
>> >> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>> >
>> > I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
>> > and setkey.
>>
>> No, this is an intentional deviation from the present state of POSIX,
>> anticipating the removal of those functions from the standard.
>
> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
> modes, not current ones.

Making _XOPEN_CRYPT be -1 or undefined in current conformance modes
would be a disservice to any program that is actually using it, since
it is overwhelmingly likely that they are using it to detect crypt,
not encrypt or setkey.

> The conform/ data is in any case meant to correspond to the standard
> versions in question (plus defect corrections from TCs etc., not plus
> feature changes from other revisions to the standard).  Intentionally
> unsupported features are listed in that data with appropriate XFAILs (see
> e.g. those for varargs.h in conform/Makefile).

This I can change.

zw
  
Florian Weimer June 20, 2018, 8:40 p.m. UTC | #5
On 05/22/2018 12:34 AM, Joseph Myers wrote:
> On Mon, 21 May 2018, Zack Weinberg wrote:
> 
>> On Mon, May 21, 2018 at 3:51 PM, Joseph Myers <joseph@codesourcery.com> wrote:
>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>
>>>> unistd.h continues to define _XOPEN_CRYPT to 1 and to declare crypt.
>>>
>>> I'd expect _XOPEN_CRYPT to change in patch 1, since it includes encrypt
>>> and setkey.
>>
>> No, this is an intentional deviation from the present state of POSIX,
>> anticipating the removal of those functions from the standard.
> 
> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
> modes, not current ones.

So we should stop defining _XOPEN_CRYPT, but continue to declare crypt 
in <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.

I would like to see this committed this cycle, and will try to get this 
committed on Zack's behalf.

> The conform/ data is in any case meant to correspond to the standard
> versions in question (plus defect corrections from TCs etc., not plus
> feature changes from other revisions to the standard).  Intentionally
> unsupported features are listed in that data with appropriate XFAILs (see
> e.g. those for varargs.h in conform/Makefile).

I find these XFAILs fairly annoying, by the way.  Especially for things 
we simply cannot fix because we do not supply the header (<ndbm.h> comes 
to my mind).

Thanks,
Florian
  
Zack Weinberg June 20, 2018, 10:47 p.m. UTC | #6
On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> wrote:
> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>> No, this is an intentional deviation from the present state of POSIX,
>>> anticipating the removal of those functions from the standard.
>>
>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>> modes, not current ones.
>
> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.

Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
in any mode.  Yes, this is an intentional deviation from POSIX, but I
think it is far less likely to break existing programs than the
alternative.

zw
  
Florian Weimer June 21, 2018, 9:31 a.m. UTC | #7
On 06/21/2018 12:47 AM, Zack Weinberg wrote:
> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>> No, this is an intentional deviation from the present state of POSIX,
>>>> anticipating the removal of those functions from the standard.
>>>
>>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>>> modes, not current ones.
>>
>> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
> 
> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
> in any mode.  Yes, this is an intentional deviation from POSIX, but I
> think it is far less likely to break existing programs than the
> alternative.

How can we resolve this conflict?

We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already. 
  There weren't many changes AFAICS, and they fall broadly into two 
categories:

(1) Not including <crypt.h> for the crypt function, only <unistd.h>.
(2) Using DES functions.

(1) was far more common than (2).

We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, 
so (1) will not be a problem.  (2) will not be addressed independently 
of the definition of _XOPEN_CRYPT.

This is why I'm fine with Joseph's approach.  It may even make it 
marginally easier to check whether you need your own DES implementation.

I would like to see a decision soon because I'm wondering if I have to 
back out the libxcrypt switch.

Thanks,
Florian
  
Florian Weimer June 21, 2018, 9:31 a.m. UTC | #8
On 06/21/2018 11:31 AM, Florian Weimer wrote:
> On 06/21/2018 12:47 AM, Zack Weinberg wrote:
>> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com> 
>> wrote:
>>> On 05/22/2018 12:34 AM, Joseph Myers wrote:
>>>> On Mon, 21 May 2018, Zack Weinberg wrote:
>>>>> No, this is an intentional deviation from the present state of POSIX,
>>>>> anticipating the removal of those functions from the standard.
>>>>
>>>> That would only seem relevant to the _XOPEN_CRYPT value in future POSIX
>>>> modes, not current ones.
>>>
>>> So we should stop defining _XOPEN_CRYPT, but continue to declare 
>>> crypt in
>>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
>>
>> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
>> in any mode.  Yes, this is an intentional deviation from POSIX, but I
>> think it is far less likely to break existing programs than the
>> alternative.
> 
> How can we resolve this conflict?
> 
> We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already. 
>   There weren't many changes AFAICS, and they fall broadly into two 
> categories:
> 
> (1) Not including <crypt.h> for the crypt function, only <unistd.h>.
> (2) Using DES functions.
> 
> (1) was far more common than (2).
> 
> We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, 
> so (1) will not be a problem.  (2) will not be addressed independently 
> of the definition of _XOPEN_CRYPT.
> 
> This is why I'm fine with Joseph's approach.  It may even make it 
> marginally easier to check whether you need your own DES implementation.
> 
> I would like to see a decision soon because I'm wondering if I have to 
> back out the libxcrypt switch.

In Fedora, of course.  Sorry for being unclear.

Florian
  
Zack Weinberg June 28, 2018, 6:52 p.m. UTC | #9
On Thu, Jun 21, 2018 at 5:31 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 06/21/2018 12:47 AM, Zack Weinberg wrote:
>> On Wed, Jun 20, 2018 at 4:40 PM, Florian Weimer <fweimer@redhat.com>
>>>
>>> So we should stop defining _XOPEN_CRYPT, but continue to declare crypt in
>>> <unistd.h> for __USE_MISC || __USE_XOPEN?  That would work for me.
>>
>>
>> Again, I think that it is inappropriate to stop defining _XOPEN_CRYPT
>> in any mode.  Yes, this is an intentional deviation from POSIX, but I
>> think it is far less likely to break existing programs than the
>> alternative.
>
> How can we resolve this conflict?
>
> We have mostly cleaned up Fedora 28 to build with !_XOPEN_CRYPT already.
> There weren't many changes AFAICS, and they fall broadly into two
> categories:
>
> (1) Not including <crypt.h> for the crypt function, only <unistd.h>.
> (2) Using DES functions.
>
> (1) was far more common than (2).
>
> We'll keep the declaration of crypt in <unistd.h> for _DEFAULT_SOURCE, so
> (1) will not be a problem.  (2) will not be addressed independently of the
> definition of _XOPEN_CRYPT.

Based on this I withdraw my objection.  I was primarily worried about
programs that might substitute their own, possibly DES-only, crypt()
implementation if _XOPEN_CRYPT wasn't defined.

zw
  

Patch

diff --git a/INSTALL b/INSTALL
index 052b1b6f89..37ec68fb3d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -197,6 +197,17 @@  if 'CFLAGS' is specified it must enable optimization.  For example:
      libnss_nisplus are not built at all.  Use this option to enable
      libnsl with all depending NSS modules and header files.
 
+'--disable-crypt'
+     Do not install the passphrase-hashing library 'libcrypt' or the
+     header file 'crypt.h'.  'unistd.h' will still declare the function
+     'crypt', as required by POSIX.  Using this option does not change
+     the set of programs that may need to be linked with '-lcrypt'; it
+     only means that the GNU C Library will not provide that library.
+
+     This option is for hackers and distributions experimenting with
+     independently-maintained implementations of libcrypt.  It may
+     become the default in a future release.
+
 '--disable-experimental-malloc'
      By default, a per-thread cache is enabled in 'malloc'.  While this
      cache can be disabled on a per-application basis using tunables
diff --git a/Makeconfig b/Makeconfig
index 1afe86475c..608ffe648c 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -566,7 +566,7 @@  link-libc-printers-tests = $(link-libc-rpath) \
 			   $(link-libc-tests-after-rpath-link)
 
 # This is how to find at build-time things that will be installed there.
-rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support
+rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
 else  # build-static
@@ -1205,9 +1205,14 @@  all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
 	      stdlib stdio-common libio malloc string wcsmbs time dirent    \
 	      grp pwd posix io termios resource misc socket sysvipc gmon    \
 	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
-	      crypt localedata timezone rt conform debug mathvec support    \
+	      localedata timezone rt conform debug mathvec support	    \
 	      dlfcn elf
 
+ifeq ($(build-crypt),yes)
+all-subdirs += crypt
+rpath-dirs += crypt
+endif
+
 ifndef avoid-generated
 # sysd-sorted itself will contain rules making the sysd-sorted target
 # depend on Depend files.  But if you just added a Depend file to an
diff --git a/NEWS b/NEWS
index 0bd21948f6..e80d3d800c 100644
--- a/NEWS
+++ b/NEWS
@@ -86,6 +86,19 @@  Deprecated and removed features, and other changes affecting compatibility:
   binaries.  It was just another name for the standard function 'crypt',
   and it has not appeared in any header file in many years.
 
+* We have tentative plans to hand off maintenance of the passphrase-hashing
+  library, libcrypt, to a separate development project that will, we hope,
+  keep up better with new passphrase-hashing algorithms.  We will continue
+  to declare 'crypt' in <unistd.h>, as required by POSIX, and programs that
+  use 'crypt' or 'crypt_r' should not need to change at all; however, system
+  integrators will need to install <crypt.h> and libcrypt from the separate
+  project.
+
+  In this release, if the configure option --disable-crypt is used, glibc
+  will not install <crypt.h> or libcrypt, making room for the separate
+  project's versions of these files.  The plan is to make this the default
+  behavior in a future release.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/config.make.in b/config.make.in
index 9e5e24b2c6..d9891b2cd8 100644
--- a/config.make.in
+++ b/config.make.in
@@ -96,6 +96,7 @@  cross-compiling = @cross_compiling@
 force-install = @force_install@
 link-obsolete-rpc = @link_obsolete_rpc@
 build-obsolete-nsl = @build_obsolete_nsl@
+build-crypt = @build_crypt@
 build-nscd = @build_nscd@
 use-nscd = @use_nscd@
 build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
diff --git a/configure b/configure
index 7a8bd3f817..ef18302215 100755
--- a/configure
+++ b/configure
@@ -676,6 +676,7 @@  build_obsolete_nsl
 link_obsolete_rpc
 libc_cv_static_nss_crypt
 libc_cv_nss_crypt
+build_crypt
 experimental_malloc
 enable_werror
 all_warnings
@@ -779,6 +780,7 @@  enable_all_warnings
 enable_werror
 enable_multi_arch
 enable_experimental_malloc
+enable_crypt
 enable_nss_crypt
 enable_obsolete_rpc
 enable_obsolete_nsl
@@ -1448,6 +1450,8 @@  Optional Features:
                           architectures
   --disable-experimental-malloc
                           disable experimental malloc features
+  --disable-crypt         do not build nor install the passphrase hashing
+                          library, libcrypt
   --enable-nss-crypt      enable libcrypt to use nss
   --enable-obsolete-rpc   build and install the obsolete RPC code for
                           link-time usage
@@ -3505,6 +3509,15 @@  fi
 
 
 
+# Check whether --enable-crypt was given.
+if test "${enable_crypt+set}" = set; then :
+  enableval=$enable_crypt; build_crypt=$enableval
+else
+  build_crypt=yes
+fi
+
+
+
 # Check whether --enable-nss-crypt was given.
 if test "${enable_nss_crypt+set}" = set; then :
   enableval=$enable_nss_crypt; nss_crypt=$enableval
@@ -3512,6 +3525,11 @@  else
   nss_crypt=no
 fi
 
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&5
+$as_echo "$as_me: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&2;}
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/configure.ac b/configure.ac
index ca1282a6b3..dc517017f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -302,11 +302,22 @@  AC_ARG_ENABLE([experimental-malloc],
 	      [experimental_malloc=yes])
 AC_SUBST(experimental_malloc)
 
+AC_ARG_ENABLE([crypt],
+              AC_HELP_STRING([--disable-crypt],
+                             [do not build nor install the passphrase hashing library, libcrypt]),
+              [build_crypt=$enableval],
+              [build_crypt=yes])
+AC_SUBST(build_crypt)
+
 AC_ARG_ENABLE([nss-crypt],
 	      AC_HELP_STRING([--enable-nss-crypt],
 			     [enable libcrypt to use nss]),
 	      [nss_crypt=$enableval],
 	      [nss_crypt=no])
+if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
+  AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled])
+  nss_crypt=no
+fi
 if test x$nss_crypt = xyes; then
   nss_includes=-I$(nss-config --includedir 2>/dev/null)
   if test $? -ne 0; then
diff --git a/conform/Makefile b/conform/Makefile
index 864fdeca21..74fbda0786 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -193,13 +193,11 @@  linknamespace-libs-thr = $(linknamespace-libs-isoc) \
 			 $(common-objpfx)rt/librt.a $(static-thread-library)
 linknamespace-libs-posix = $(linknamespace-libs-thr) \
 			   $(common-objpfx)dlfcn/libdl.a
-linknamespace-libs-xsi = $(linknamespace-libs-posix) \
-			 $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-xsi = $(linknamespace-libs-posix)
 linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)
-linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
-			  $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
 linknamespace-libs-POSIX = $(linknamespace-libs-thr)
 linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
@@ -209,6 +207,11 @@  linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
 linknamespace-libs = $(foreach std,$(conformtest-standards),\
 				   $(linknamespace-libs-$(std)))
 
+ifeq ($(build-crypt),yes)
+linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
+endif
+
 $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
 					$(linknamespace-libs)
 	LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \
diff --git a/crypt/Makefile b/crypt/Makefile
index 303800df73..3811b6e298 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -32,10 +32,6 @@  libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
 
 tests := cert md5c-test sha256c-test sha512c-test badsalttest
 
-ifeq ($(crypt-in-libc),yes)
-routines += $(libcrypt-routines)
-endif
-
 ifeq ($(nss-crypt),yes)
 nss-cpp-flags := -DUSE_NSS \
   -I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
diff --git a/elf/Makefile b/elf/Makefile
index 2dcd2b88e0..5b94f8d038 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -387,14 +387,21 @@  $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os
 CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag)
 endif
 
-# By default tst-linkall-static should try to use crypt routines to test
-# static libcrypt use.
+# We can only test static libcrypt use if libcrypt has been built,
+# and either NSS crypto is not in use, or static NSS libraries are
+# available.
+ifeq ($(build-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
+ifeq ($(nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
+else
+ifeq ($(static-nss-crypt),no)
+CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
+else
 CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
-# However, if we are using NSS crypto and we don't have a static
-# library, then we exclude the use of crypt functions in the test.
-# We similarly exclude libcrypt.a from the static link (see below).
-ifeq (yesno,$(nss-crypt)$(static-nss-crypt))
-CFLAGS-tst-linkall-static.c += -UUSE_CRYPT -DUSE_CRYPT=0
+endif
+endif
 endif
 
 include ../Rules
@@ -1115,7 +1122,6 @@  localplt-built-dso := $(addprefix $(common-objpfx),\
 				  rt/librt.so \
 				  dlfcn/libdl.so \
 				  resolv/libresolv.so \
-				  crypt/libcrypt.so \
 		       )
 ifeq ($(build-mathvec),yes)
 localplt-built-dso += $(addprefix $(common-objpfx), mathvec/libmvec.so)
@@ -1123,6 +1129,9 @@  endif
 ifeq ($(have-thread-library),yes)
 localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
 endif
+ifeq ($(build-crypt),yes)
+localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
+endif
 
 vpath localplt.data $(+sysdep_dirs)
 
@@ -1397,6 +1406,7 @@  $(objpfx)tst-linkall-static: \
   $(common-objpfx)resolv/libanl.a \
   $(static-thread-library)
 
+ifeq ($(build-crypt),yes)
 # If we are using NSS crypto and we have the ability to link statically
 # then we include libcrypt.a, otherwise we leave out libcrypt.a and
 # link as much as we can into the tst-linkall-static test.  This assumes
@@ -1412,6 +1422,7 @@  ifeq (no,$(nss-crypt))
 $(objpfx)tst-linkall-static: \
   $(common-objpfx)crypt/libcrypt.a
 endif
+endif
 
 # The application depends on the DSO, and the DSO loads the plugin.
 # The plugin also depends on the DSO. This creates the circular
diff --git a/elf/tst-linkall-static.c b/elf/tst-linkall-static.c
index e8df38f74e..d0f2592e67 100644
--- a/elf/tst-linkall-static.c
+++ b/elf/tst-linkall-static.c
@@ -18,7 +18,9 @@ 
 
 #include <math.h>
 #include <pthread.h>
-#include <crypt.h>
+#if USE_CRYPT
+# include <crypt.h>
+#endif
 #include <resolv.h>
 #include <dlfcn.h>
 #include <utmp.h>
diff --git a/manual/install.texi b/manual/install.texi
index 4bbbfcffa5..6e18f85b8b 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -230,6 +230,18 @@  libnss_nisplus are not built at all.
 Use this option to enable libnsl with all depending NSS modules and
 header files.
 
+@item --disable-crypt
+Do not install the passphrase-hashing library @file{libcrypt} or the
+header file @file{crypt.h}.  @file{unistd.h} will still declare the
+function @code{crypt}, as required by POSIX@.  Using this option does
+not change the set of programs that may need to be linked with
+@option{-lcrypt}; it only means that @theglibc{} will not provide that
+library.
+
+This option is for hackers and distributions experimenting with
+independently-maintained implementations of libcrypt.  It may become
+the default in a future release.
+
 @item --disable-experimental-malloc
 By default, a per-thread cache is enabled in @code{malloc}.  While
 this cache can be disabled on a per-application basis using tunables