diff --git a/configure b/configure
index 17f3f2654f81c3c986b205c0d47e925bacfaccce..3663e50d15005b2cecf43682dc49c4cec1317535 100755
--- a/configure
+++ b/configure
@@ -657,7 +657,7 @@ acx_pthread_config
 have_win32_dbghelp
 HAVE_IPV6
 LIBOBJS
-OSSP_UUID_LIBS
+UUID_LIBS
 ZIC
 python_enable_shared
 python_additional_libs
@@ -705,7 +705,8 @@ with_system_tzdata
 with_libxslt
 with_libxml
 XML2_CONFIG
-with_ossp_uuid
+UUID_EXTRA_OBJS
+with_uuid
 with_selinux
 with_openssl
 krb_srvtab
@@ -826,6 +827,7 @@ with_openssl
 with_selinux
 with_readline
 with_libedit_preferred
+with_uuid
 with_ossp_uuid
 with_libxml
 with_libxslt
@@ -1512,7 +1514,8 @@ Optional Packages:
   --without-readline      do not use GNU Readline nor BSD Libedit for editing
   --with-libedit-preferred
                           prefer BSD Libedit over GNU Readline
-  --with-ossp-uuid        build contrib/uuid-ossp, requires OSSP UUID library
+  --with-uuid=LIB         build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
+  --with-ossp-uuid        obsolete spelling of --with-uuid=ossp
   --with-libxml           build with XML support
   --with-libxslt          use XSLT support when building contrib/xml2
   --with-system-tzdata=DIR
@@ -1737,6 +1740,73 @@ fi
 
 } # ac_fn_c_try_cpp
 
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2195,73 +2265,6 @@ rm -f conftest.val
 
 } # ac_fn_c_compute_int
 
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
 # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
 # ---------------------------------------------
 # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
@@ -5614,11 +5617,40 @@ fi
 
 
 #
-# OSSP UUID library
+# UUID library
+#
+# There are at least three UUID libraries in common use: the FreeBSD/NetBSD
+# library, the e2fsprogs libuuid (now part of util-linux-ng), and the OSSP
+# UUID library.  More than one of these might be present on a given platform,
+# so we make the user say which one she wants.
 #
 
 
 
+# Check whether --with-uuid was given.
+if test "${with_uuid+set}" = set; then :
+  withval=$with_uuid;
+  case $withval in
+    yes)
+      as_fn_error $? "argument required for --with-uuid option" "$LINENO" 5
+      ;;
+    no)
+      as_fn_error $? "argument required for --with-uuid option" "$LINENO" 5
+      ;;
+    *)
+
+      ;;
+  esac
+
+fi
+
+
+if test x"$with_uuid" = x"" ; then
+  with_uuid=no
+fi
+
+
+
 # Check whether --with-ossp-uuid was given.
 if test "${with_ossp_uuid+set}" = set; then :
   withval=$with_ossp_uuid;
@@ -5640,6 +5672,31 @@ else
 fi
 
 
+if test "$with_ossp_uuid" = yes ; then
+  with_uuid=ossp
+fi
+
+if test "$with_uuid" = bsd ; then
+
+$as_echo "#define HAVE_UUID_BSD 1" >>confdefs.h
+
+  UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = e2fs ; then
+
+$as_echo "#define HAVE_UUID_E2FS 1" >>confdefs.h
+
+  UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = ossp ; then
+
+$as_echo "#define HAVE_UUID_OSSP 1" >>confdefs.h
+
+  UUID_EXTRA_OBJS=""
+elif test "$with_uuid" = no ; then
+  UUID_EXTRA_OBJS=""
+else
+  as_fn_error $? "--with-uuid must specify one of bsd, e2fs, or ossp" "$LINENO" 5
+fi
+
 
 
 
@@ -8775,7 +8832,66 @@ fi
 fi
 
 # for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+  # On BSD, the UUID functions are in libc
+  ac_fn_c_check_func "$LINENO" "uuid_to_string" "ac_cv_func_uuid_to_string"
+if test "x$ac_cv_func_uuid_to_string" = xyes; then :
+  UUID_LIBS=""
+else
+  as_fn_error $? "BSD UUID functions are not present" "$LINENO" 5
+fi
+
+elif test "$with_uuid" = e2fs ; then
+  # On OS X, the UUID functions are in libc
+  ac_fn_c_check_func "$LINENO" "uuid_generate" "ac_cv_func_uuid_generate"
+if test "x$ac_cv_func_uuid_generate" = xyes; then :
+  UUID_LIBS=""
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
+$as_echo_n "checking for uuid_generate in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_generate+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_generate ();
+int
+main ()
+{
+return uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_generate=yes
+else
+  ac_cv_lib_uuid_uuid_generate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate" = xyes; then :
+  UUID_LIBS="-luuid"
+else
+  as_fn_error $? "library 'uuid' is required for E2FS UUID" "$LINENO" 5
+fi
+
+fi
+
+elif test "$with_uuid" = ossp ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -lossp-uuid" >&5
 $as_echo_n "checking for uuid_export in -lossp-uuid... " >&6; }
 if ${ac_cv_lib_ossp_uuid_uuid_export+:} false; then :
@@ -8813,7 +8929,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ossp_uuid_uuid_export" >&5
 $as_echo "$ac_cv_lib_ossp_uuid_uuid_export" >&6; }
 if test "x$ac_cv_lib_ossp_uuid_uuid_export" = xyes; then :
-  OSSP_UUID_LIBS="-lossp-uuid"
+  UUID_LIBS="-lossp-uuid"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -luuid" >&5
 $as_echo_n "checking for uuid_export in -luuid... " >&6; }
@@ -8852,9 +8968,9 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_export" >&5
 $as_echo "$ac_cv_lib_uuid_uuid_export" >&6; }
 if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then :
-  OSSP_UUID_LIBS="-luuid"
+  UUID_LIBS="-luuid"
 else
-  as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP-UUID" "$LINENO" 5
+  as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5
 fi
 
 fi
@@ -9398,7 +9514,86 @@ fi
 fi
 
 # for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+  for ac_header in uuid.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uuid_to_string" >/dev/null 2>&1; then :
+
+else
+  as_fn_error $? "header file <uuid.h> does not match BSD UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+  as_fn_error $? "header file <uuid.h> is required for BSD UUID" "$LINENO" 5
+fi
+
+done
+
+elif test "$with_uuid" = e2fs ; then
+  for ac_header in uuid/uuid.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <uuid/uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uuid_generate" >/dev/null 2>&1; then :
+
+else
+  as_fn_error $? "header file <uuid/uuid.h> does not match E2FS UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+  for ac_header in uuid.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uuid_generate" >/dev/null 2>&1; then :
+
+else
+  as_fn_error $? "header file <uuid.h> does not match E2FS UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+  as_fn_error $? "header file <uuid/uuid.h> or <uuid.h> is required for E2FS UUID" "$LINENO" 5
+fi
+
+done
+
+fi
+
+done
+
+elif test "$with_uuid" = ossp ; then
   for ac_header in ossp/uuid.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "ossp/uuid.h" "ac_cv_header_ossp_uuid_h" "$ac_includes_default"
@@ -9406,19 +9601,42 @@ if test "x$ac_cv_header_ossp_uuid_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_OSSP_UUID_H 1
 _ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ossp/uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uuid_export" >/dev/null 2>&1; then :
 
 else
+  as_fn_error $? "header file <ossp/uuid.h> does not match OSSP UUID library" "$LINENO" 5
+fi
+rm -f conftest*
 
-    for ac_header in uuid.h
+else
+  for ac_header in uuid.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
 if test "x$ac_cv_header_uuid_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_UUID_H 1
 _ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uuid_export" >/dev/null 2>&1; then :
+
+else
+  as_fn_error $? "header file <uuid.h> does not match OSSP UUID library" "$LINENO" 5
+fi
+rm -f conftest*
 
 else
-  as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID" "$LINENO" 5
+  as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID" "$LINENO" 5
 fi
 
 done
diff --git a/configure.in b/configure.in
index b94db352e13dbc3066bb07588eaa040b73a5e5f3..80df1d76510c707009518ef253ecd29d9919b976 100644
--- a/configure.in
+++ b/configure.in
@@ -694,10 +694,38 @@ PGAC_ARG_BOOL(with, libedit-preferred, no,
 
 
 #
-# OSSP UUID library
+# UUID library
 #
-PGAC_ARG_BOOL(with, ossp-uuid, no, [build contrib/uuid-ossp, requires OSSP UUID library])
-AC_SUBST(with_ossp_uuid)
+# There are at least three UUID libraries in common use: the FreeBSD/NetBSD
+# library, the e2fsprogs libuuid (now part of util-linux-ng), and the OSSP
+# UUID library.  More than one of these might be present on a given platform,
+# so we make the user say which one she wants.
+#
+PGAC_ARG_REQ(with, uuid, [LIB], [build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)])
+if test x"$with_uuid" = x"" ; then
+  with_uuid=no
+fi
+PGAC_ARG_BOOL(with, ossp-uuid, no, [obsolete spelling of --with-uuid=ossp])
+if test "$with_ossp_uuid" = yes ; then
+  with_uuid=ossp
+fi
+
+if test "$with_uuid" = bsd ; then
+  AC_DEFINE([HAVE_UUID_BSD], 1, [Define to 1 if you have BSD UUID support.])
+  UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = e2fs ; then
+  AC_DEFINE([HAVE_UUID_E2FS], 1, [Define to 1 if you have E2FS UUID support.])
+  UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = ossp ; then
+  AC_DEFINE([HAVE_UUID_OSSP], 1, [Define to 1 if you have OSSP UUID support.])
+  UUID_EXTRA_OBJS=""
+elif test "$with_uuid" = no ; then
+  UUID_EXTRA_OBJS=""
+else
+  AC_MSG_ERROR([--with-uuid must specify one of bsd, e2fs, or ossp])
+fi
+AC_SUBST(with_uuid)
+AC_SUBST(UUID_EXTRA_OBJS)
 
 
 #
@@ -948,14 +976,26 @@ if test "$with_selinux" = yes; then
 fi
 
 # for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+  # On BSD, the UUID functions are in libc
+  AC_CHECK_FUNC(uuid_to_string,
+    [UUID_LIBS=""],
+    [AC_MSG_ERROR([BSD UUID functions are not present])])
+elif test "$with_uuid" = e2fs ; then
+  # On OS X, the UUID functions are in libc
+  AC_CHECK_FUNC(uuid_generate,
+    [UUID_LIBS=""],
+    [AC_CHECK_LIB(uuid, uuid_generate,
+      [UUID_LIBS="-luuid"],
+      [AC_MSG_ERROR([library 'uuid' is required for E2FS UUID])])])
+elif test "$with_uuid" = ossp ; then
   AC_CHECK_LIB(ossp-uuid, uuid_export,
-    [OSSP_UUID_LIBS="-lossp-uuid"],
+    [UUID_LIBS="-lossp-uuid"],
     [AC_CHECK_LIB(uuid, uuid_export,
-      [OSSP_UUID_LIBS="-luuid"],
-      [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP-UUID])])])
+      [UUID_LIBS="-luuid"],
+      [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP UUID])])])
 fi
-AC_SUBST(OSSP_UUID_LIBS)
+AC_SUBST(UUID_LIBS)
 
 
 ##
@@ -1075,10 +1115,27 @@ if test "$with_bonjour" = yes ; then
 fi
 
 # for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
-  AC_CHECK_HEADERS(ossp/uuid.h, [], [
-    AC_CHECK_HEADERS(uuid.h, [],
-      [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID])])])
+if test "$with_uuid" = bsd ; then
+  AC_CHECK_HEADERS(uuid.h,
+    [AC_EGREP_HEADER([uuid_to_string], uuid.h, [],
+      [AC_MSG_ERROR([header file <uuid.h> does not match BSD UUID library])])],
+    [AC_MSG_ERROR([header file <uuid.h> is required for BSD UUID])])
+elif test "$with_uuid" = e2fs ; then
+  AC_CHECK_HEADERS(uuid/uuid.h,
+    [AC_EGREP_HEADER([uuid_generate], uuid/uuid.h, [],
+      [AC_MSG_ERROR([header file <uuid/uuid.h> does not match E2FS UUID library])])],
+    [AC_CHECK_HEADERS(uuid.h,
+      [AC_EGREP_HEADER([uuid_generate], uuid.h, [],
+        [AC_MSG_ERROR([header file <uuid.h> does not match E2FS UUID library])])],
+      [AC_MSG_ERROR([header file <uuid/uuid.h> or <uuid.h> is required for E2FS UUID])])])
+elif test "$with_uuid" = ossp ; then
+  AC_CHECK_HEADERS(ossp/uuid.h,
+    [AC_EGREP_HEADER([uuid_export], ossp/uuid.h, [],
+      [AC_MSG_ERROR([header file <ossp/uuid.h> does not match OSSP UUID library])])],
+    [AC_CHECK_HEADERS(uuid.h,
+      [AC_EGREP_HEADER([uuid_export], uuid.h, [],
+        [AC_MSG_ERROR([header file <uuid.h> does not match OSSP UUID library])])],
+      [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID])])])
 fi
 
 if test "$PORTNAME" = "win32" ; then
diff --git a/contrib/Makefile b/contrib/Makefile
index 8dc40f7de0033d372995390a7706ca22cf778fdc..b37d0dd2c318f722628caef69c510b2ef99d9044 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -64,7 +64,7 @@ else
 ALWAYS_SUBDIRS += sslinfo
 endif
 
-ifeq ($(with_ossp_uuid),yes)
+ifneq ($(with_uuid),no)
 SUBDIRS += uuid-ossp
 else
 ALWAYS_SUBDIRS += uuid-ossp
diff --git a/contrib/uuid-ossp/.gitignore b/contrib/uuid-ossp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6c989c787297ee6470129a330de3809945d4a69d
--- /dev/null
+++ b/contrib/uuid-ossp/.gitignore
@@ -0,0 +1,6 @@
+/md5.c
+/sha1.c
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/uuid-ossp/Makefile b/contrib/uuid-ossp/Makefile
index 9b2d2e3ff93c3d50053aa95bf2bac7913ea36537..335cc7ef50a8e9d2fedf9bb434ce0cb5fd1e133f 100644
--- a/contrib/uuid-ossp/Makefile
+++ b/contrib/uuid-ossp/Makefile
@@ -1,12 +1,21 @@
 # contrib/uuid-ossp/Makefile
 
 MODULE_big = uuid-ossp
-OBJS = uuid-ossp.o
+OBJS = uuid-ossp.o $(UUID_EXTRA_OBJS)
 
 EXTENSION = uuid-ossp
 DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql
 
-SHLIB_LINK += $(OSSP_UUID_LIBS)
+REGRESS = uuid_ossp
+
+SHLIB_LINK += $(UUID_LIBS)
+
+# We copy some needed files verbatim from pgcrypto
+pgcrypto_src = $(top_srcdir)/contrib/pgcrypto
+
+PG_CPPFLAGS = -I$(pgcrypto_src)
+
+EXTRA_CLEAN = md5.c sha1.c
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
@@ -18,3 +27,6 @@ top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 include $(top_srcdir)/contrib/contrib-global.mk
 endif
+
+md5.c sha1.c: % : $(pgcrypto_src)/%
+	rm -f $@ && $(LN_S) $< .
diff --git a/contrib/uuid-ossp/expected/uuid_ossp.out b/contrib/uuid-ossp/expected/uuid_ossp.out
new file mode 100644
index 0000000000000000000000000000000000000000..986843c8976441fe1826cb89c177aa37b1282f18
--- /dev/null
+++ b/contrib/uuid-ossp/expected/uuid_ossp.out
@@ -0,0 +1,91 @@
+CREATE EXTENSION "uuid-ossp";
+SELECT uuid_nil();
+               uuid_nil               
+--------------------------------------
+ 00000000-0000-0000-0000-000000000000
+(1 row)
+
+SELECT uuid_ns_dns();
+             uuid_ns_dns              
+--------------------------------------
+ 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_url();
+             uuid_ns_url              
+--------------------------------------
+ 6ba7b811-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_oid();
+             uuid_ns_oid              
+--------------------------------------
+ 6ba7b812-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_x500();
+             uuid_ns_x500             
+--------------------------------------
+ 6ba7b814-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_generate_v1() < uuid_generate_v1();
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT uuid_generate_v1() < uuid_generate_v1mc();
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011';
+ ?column? 
+----------
+ 00000011
+(1 row)
+
+SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+           uuid_generate_v3           
+--------------------------------------
+ 3d813cbb-47fb-32ba-91df-831e1593ac29
+(1 row)
+
+SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+           uuid_generate_v5           
+--------------------------------------
+ 21f7f8de-8051-5b89-8680-0195ef798b6a
+(1 row)
+
+SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
+ ?column? 
+----------
+ t
+(1 row)
+
+SELECT uuid_generate_v4() <> uuid_generate_v4();
+ ?column? 
+----------
+ t
+(1 row)
+
diff --git a/contrib/uuid-ossp/sql/uuid_ossp.sql b/contrib/uuid-ossp/sql/uuid_ossp.sql
new file mode 100644
index 0000000000000000000000000000000000000000..29fba21b3f75e8af8e316890171b1a9247b10cb0
--- /dev/null
+++ b/contrib/uuid-ossp/sql/uuid_ossp.sql
@@ -0,0 +1,22 @@
+CREATE EXTENSION "uuid-ossp";
+
+SELECT uuid_nil();
+SELECT uuid_ns_dns();
+SELECT uuid_ns_url();
+SELECT uuid_ns_oid();
+SELECT uuid_ns_x500();
+
+SELECT uuid_generate_v1() < uuid_generate_v1();
+SELECT uuid_generate_v1() < uuid_generate_v1mc();
+
+SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+
+SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011';
+
+SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+
+SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
+SELECT uuid_generate_v4() <> uuid_generate_v4();
diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c
index 8f99084df3487d48f86291aab45cf10625955639..f8c33d2b4698fb85fd9b05e8810638acd4f2d59f 100644
--- a/contrib/uuid-ossp/uuid-ossp.c
+++ b/contrib/uuid-ossp/uuid-ossp.c
@@ -1,40 +1,113 @@
 /*-------------------------------------------------------------------------
  *
- * UUID generation functions using the OSSP UUID library
+ * UUID generation functions using the BSD, E2FS or OSSP UUID library
  *
  * Copyright (c) 2007-2014, PostgreSQL Global Development Group
  *
+ * Portions Copyright (c) 2009 Andrew Gierth
+ *
  * contrib/uuid-ossp/uuid-ossp.c
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
+
 #include "fmgr.h"
 #include "utils/builtins.h"
 #include "utils/uuid.h"
 
 /*
- * There's some confusion over the location of the uuid.h header file.
- * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you
- * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know
- * what other systems do.
+ * It's possible that there's more than one uuid.h header file present.
+ * We expect configure to set the HAVE_ symbol for only the one we want.
+ *
+ * BSD includes a uuid_hash() function that conflicts with the one in
+ * builtins.h; we #define it out of the way.
  */
-#ifdef HAVE_OSSP_UUID_H
-#include <ossp/uuid.h>
-#else
+#define uuid_hash bsd_uuid_hash
+
 #ifdef HAVE_UUID_H
 #include <uuid.h>
-#else
-#error OSSP uuid.h not found
 #endif
+#ifdef HAVE_OSSP_UUID_H
+#include <ossp/uuid.h>
 #endif
+#ifdef HAVE_UUID_UUID_H
+#include <uuid/uuid.h>
+#endif
+
+#undef uuid_hash
 
-/* better both be 16 */
-#if (UUID_LEN != UUID_LEN_BIN)
+/*
+ * Some BSD variants offer md5 and sha1 implementations but Linux does not,
+ * so we use a copy of the ones from pgcrypto.  Not needed with OSSP, though.
+ */
+#ifndef HAVE_UUID_OSSP
+#include "md5.h"
+#include "sha1.h"
+#endif
+
+
+/* Check our UUID length against OSSP's; better both be 16 */
+#if defined(HAVE_UUID_OSSP) && (UUID_LEN != UUID_LEN_BIN)
 #error UUID length mismatch
 #endif
 
+/* Define some constants like OSSP's, to make the code more readable */
+#ifndef HAVE_UUID_OSSP
+#define UUID_MAKE_MC 0
+#define UUID_MAKE_V1 1
+#define UUID_MAKE_V2 2
+#define UUID_MAKE_V3 3
+#define UUID_MAKE_V4 4
+#define UUID_MAKE_V5 5
+#endif
+
+/*
+ * A DCE 1.1 compatible source representation of UUIDs, derived from
+ * the BSD implementation.  BSD already has this; OSSP doesn't need it.
+ */
+#ifdef HAVE_UUID_E2FS
+typedef struct
+{
+	uint32_t	time_low;
+	uint16_t	time_mid;
+	uint16_t	time_hi_and_version;
+	uint8_t		clock_seq_hi_and_reserved;
+	uint8_t		clock_seq_low;
+	uint8_t		node[6];
+} dce_uuid_t;
+#else
+#define dce_uuid_t uuid_t
+#endif
+
+/* If not OSSP, we need some endianness-manipulation macros */
+#ifndef HAVE_UUID_OSSP
+
+#define UUID_TO_NETWORK(uu) \
+do { \
+	uu.time_low = htonl(uu.time_low); \
+	uu.time_mid = htons(uu.time_mid); \
+	uu.time_hi_and_version = htons(uu.time_hi_and_version); \
+} while (0)
+
+#define UUID_TO_LOCAL(uu) \
+do { \
+	uu.time_low = ntohl(uu.time_low); \
+	uu.time_mid = ntohs(uu.time_mid); \
+	uu.time_hi_and_version = ntohs(uu.time_hi_and_version); \
+} while (0)
+
+#define UUID_V3_OR_V5(uu, v) \
+do { \
+	uu.time_hi_and_version &= 0x0FFF; \
+	uu.time_hi_and_version |= (v << 12); \
+	uu.clock_seq_hi_and_reserved &= 0x3F; \
+	uu.clock_seq_hi_and_reserved |= 0x80; \
+} while(0)
+
+#endif   /* !HAVE_UUID_OSSP */
+
 
 PG_MODULE_MAGIC;
 
@@ -51,6 +124,8 @@ PG_FUNCTION_INFO_V1(uuid_generate_v3);
 PG_FUNCTION_INFO_V1(uuid_generate_v4);
 PG_FUNCTION_INFO_V1(uuid_generate_v5);
 
+#ifdef HAVE_UUID_OSSP
+
 static void
 pguuid_complain(uuid_rc_t rc)
 {
@@ -114,100 +189,294 @@ special_uuid_value(const char *name)
 	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
 }
 
+/* len is unused with OSSP, but we want to have the same number of args */
+static Datum
+uuid_generate_internal(int mode, const uuid_t *ns, const char *name, int len)
+{
+	uuid_t	   *uuid;
+	char	   *str;
+	uuid_rc_t	rc;
+
+	rc = uuid_create(&uuid);
+	if (rc != UUID_RC_OK)
+		pguuid_complain(rc);
+	rc = uuid_make(uuid, mode, ns, name);
+	if (rc != UUID_RC_OK)
+		pguuid_complain(rc);
+	str = uuid_to_string(uuid);
+	rc = uuid_destroy(uuid);
+	if (rc != UUID_RC_OK)
+		pguuid_complain(rc);
+
+	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
+}
+
+
+static Datum
+uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
+{
+	uuid_t	   *ns_uuid;
+	Datum		result;
+	uuid_rc_t	rc;
+
+	rc = uuid_create(&ns_uuid);
+	if (rc != UUID_RC_OK)
+		pguuid_complain(rc);
+	string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
+				   ns_uuid);
+
+	result = uuid_generate_internal(mode,
+									ns_uuid,
+									text_to_cstring(name),
+									0);
+
+	rc = uuid_destroy(ns_uuid);
+	if (rc != UUID_RC_OK)
+		pguuid_complain(rc);
+
+	return result;
+}
+
+#else							/* !HAVE_UUID_OSSP */
+
+static Datum
+uuid_generate_internal(int v, unsigned char *ns, char *ptr, int len)
+{
+	char		strbuf[40];
+
+	switch (v)
+	{
+		case 0:			/* constant-value uuids */
+			strlcpy(strbuf, ptr, 37);
+			break;
+
+		case 1:			/* time/node-based uuids */
+			{
+#ifdef HAVE_UUID_E2FS
+				uuid_t		uu;
+
+				uuid_generate_time(uu);
+				uuid_unparse(uu, strbuf);
+
+				/*
+				 * PTR, if set, replaces the trailing characters of the uuid;
+				 * this is to support v1mc, where a random multicast MAC is
+				 * used instead of the physical one
+				 */
+				if (ptr && len <= 36)
+					strcpy(strbuf + (36 - len), ptr);
+#else							/* BSD */
+				uuid_t		uu;
+				uint32_t	status = uuid_s_ok;
+				char	   *str = NULL;
+
+				uuid_create(&uu, &status);
+
+				if (status == uuid_s_ok)
+				{
+					uuid_to_string(&uu, &str, &status);
+					if (status == uuid_s_ok)
+					{
+						strlcpy(strbuf, str, 37);
+
+						/*
+						 * PTR, if set, replaces the trailing characters of
+						 * the uuid; this is to support v1mc, where a random
+						 * multicast MAC is used instead of the physical one
+						 */
+						if (ptr && len <= 36)
+							strcpy(strbuf + (36 - len), ptr);
+					}
+					if (str)
+						free(str);
+				}
+
+				if (status != uuid_s_ok)
+					ereport(ERROR,
+							(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+							 errmsg("uuid library failure: %d",
+									(int) status)));
+#endif
+				break;
+			}
+
+		case 3:			/* namespace-based MD5 uuids */
+		case 5:			/* namespace-based SHA1 uuids */
+			{
+				dce_uuid_t	uu;
+#ifdef HAVE_UUID_BSD
+				uint32_t	status = uuid_s_ok;
+				char	   *str = NULL;
+#endif
+
+				if (v == 3)
+				{
+					MD5_CTX		ctx;
+
+					MD5Init(&ctx);
+					MD5Update(&ctx, ns, sizeof(uu));
+					MD5Update(&ctx, (unsigned char *) ptr, len);
+					MD5Final((unsigned char *) &uu, &ctx);
+				}
+				else
+				{
+					SHA1_CTX	ctx;
+
+					SHA1Init(&ctx);
+					SHA1Update(&ctx, ns, sizeof(uu));
+					SHA1Update(&ctx, (unsigned char *) ptr, len);
+					SHA1Final((unsigned char *) &uu, &ctx);
+				}
+
+				/* the calculated hash is using local order */
+				UUID_TO_NETWORK(uu);
+				UUID_V3_OR_V5(uu, v);
+
+#ifdef HAVE_UUID_E2FS
+				/* uuid_unparse expects local order */
+				UUID_TO_LOCAL(uu);
+				uuid_unparse((unsigned char *) &uu, strbuf);
+#else							/* BSD */
+				uuid_to_string(&uu, &str, &status);
+
+				if (status == uuid_s_ok)
+					strlcpy(strbuf, str, 37);
+
+				if (str)
+					free(str);
+
+				if (status != uuid_s_ok)
+					ereport(ERROR,
+							(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+							 errmsg("uuid library failure: %d",
+									(int) status)));
+#endif
+				break;
+			}
+
+		case 4:			/* random uuid */
+		default:
+			{
+#ifdef HAVE_UUID_E2FS
+				uuid_t		uu;
+
+				uuid_generate_random(uu);
+				uuid_unparse(uu, strbuf);
+#else							/* BSD */
+				snprintf(strbuf, sizeof(strbuf),
+						 "%08lx-%04x-%04x-%04x-%04x%08lx",
+						 (unsigned long) arc4random(),
+						 (unsigned) (arc4random() & 0xffff),
+						 (unsigned) ((arc4random() & 0xfff) | 0x4000),
+						 (unsigned) ((arc4random() & 0x3fff) | 0x8000),
+						 (unsigned) (arc4random() & 0xffff),
+						 (unsigned long) arc4random());
+#endif
+				break;
+			}
+	}
+
+	return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf));
+}
+
+#endif   /* HAVE_UUID_OSSP */
+
 
 Datum
 uuid_nil(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_UUID_OSSP
 	return special_uuid_value("nil");
+#else
+	return uuid_generate_internal(0, NULL,
+								  "00000000-0000-0000-0000-000000000000", 36);
+#endif
 }
 
 
 Datum
 uuid_ns_dns(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_UUID_OSSP
 	return special_uuid_value("ns:DNS");
+#else
+	return uuid_generate_internal(0, NULL,
+								  "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
 }
 
 
 Datum
 uuid_ns_url(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_UUID_OSSP
 	return special_uuid_value("ns:URL");
+#else
+	return uuid_generate_internal(0, NULL,
+								  "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
 }
 
 
 Datum
 uuid_ns_oid(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_UUID_OSSP
 	return special_uuid_value("ns:OID");
+#else
+	return uuid_generate_internal(0, NULL,
+								  "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
 }
 
 
 Datum
 uuid_ns_x500(PG_FUNCTION_ARGS)
 {
+#ifdef HAVE_UUID_OSSP
 	return special_uuid_value("ns:X500");
-}
-
-
-static Datum
-uuid_generate_internal(int mode, const uuid_t *ns, const char *name)
-{
-	uuid_t	   *uuid;
-	char	   *str;
-	uuid_rc_t	rc;
-
-	rc = uuid_create(&uuid);
-	if (rc != UUID_RC_OK)
-		pguuid_complain(rc);
-	rc = uuid_make(uuid, mode, ns, name);
-	if (rc != UUID_RC_OK)
-		pguuid_complain(rc);
-	str = uuid_to_string(uuid);
-	rc = uuid_destroy(uuid);
-	if (rc != UUID_RC_OK)
-		pguuid_complain(rc);
-
-	return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
+#else
+	return uuid_generate_internal(0, NULL,
+								  "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
 }
 
 
 Datum
 uuid_generate_v1(PG_FUNCTION_ARGS)
 {
-	return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL);
+	return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL, 0);
 }
 
 
 Datum
 uuid_generate_v1mc(PG_FUNCTION_ARGS)
 {
-	return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL);
-}
-
-
-static Datum
-uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
-{
-	uuid_t	   *ns_uuid;
-	Datum		result;
-	uuid_rc_t	rc;
-
-	rc = uuid_create(&ns_uuid);
-	if (rc != UUID_RC_OK)
-		pguuid_complain(rc);
-	string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
-				   ns_uuid);
-
-	result = uuid_generate_internal(mode,
-									ns_uuid,
-									text_to_cstring(name));
-
-	rc = uuid_destroy(ns_uuid);
-	if (rc != UUID_RC_OK)
-		pguuid_complain(rc);
+#ifdef HAVE_UUID_OSSP
+	char	   *buf = NULL;
+#elif defined(HAVE_UUID_E2FS)
+	char		strbuf[40];
+	char	   *buf;
+	uuid_t		uu;
+
+	uuid_generate_random(uu);
+
+	/* set IEEE802 multicast and local-admin bits */
+	((dce_uuid_t *) &uu)->node[0] |= 0x03;
+
+	uuid_unparse(uu, strbuf);
+	buf = strbuf + 24;
+#else							/* BSD */
+	char		buf[16];
+
+	/* set IEEE802 multicast and local-admin bits */
+	snprintf(buf, sizeof(buf), "-%04x%08lx",
+			 (unsigned) ((arc4random() & 0xffff) | 0x0300),
+			 (unsigned long) arc4random());
+#endif
 
-	return result;
+	return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL,
+								  buf, 13);
 }
 
 
@@ -217,14 +486,19 @@ uuid_generate_v3(PG_FUNCTION_ARGS)
 	pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
 	text	   *name = PG_GETARG_TEXT_P(1);
 
+#ifdef HAVE_UUID_OSSP
 	return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name);
+#else
+	return uuid_generate_internal(UUID_MAKE_V3, (unsigned char *) ns,
+								  VARDATA(name), VARSIZE(name) - VARHDRSZ);
+#endif
 }
 
 
 Datum
 uuid_generate_v4(PG_FUNCTION_ARGS)
 {
-	return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL);
+	return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL, 0);
 }
 
 
@@ -234,5 +508,10 @@ uuid_generate_v5(PG_FUNCTION_ARGS)
 	pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
 	text	   *name = PG_GETARG_TEXT_P(1);
 
+#ifdef HAVE_UUID_OSSP
 	return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name);
+#else
+	return uuid_generate_internal(UUID_MAKE_V5, (unsigned char *) ns,
+								  VARDATA(name), VARSIZE(name) - VARHDRSZ);
+#endif
 }
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index b6b582e24c28f3cf0e9e486044bb1821ad3f6d97..7353c612b1f6721161c8b7e2c29e4b5955446922 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -869,17 +869,46 @@ su - postgres
        </listitem>
       </varlistentry>
 
+      <varlistentry>
+       <term><option>--with-uuid=<replaceable>LIBRARY</replaceable></option></term>
+       <listitem>
+        <para>
+         Build the <![%standalone-include[uuid-ossp]]>
+         <![%standalone-ignore[<xref linkend="uuid-ossp">]]> module
+         (which provides functions to generate UUIDs), using the specified
+         UUID library.<indexterm><primary>UUID</primary></indexterm>
+         <replaceable>LIBRARY</replaceable> must be one of:
+        </para>
+        <itemizedlist>
+         <listitem>
+          <para>
+           <option>bsd</> to use the UUID functions found in FreeBSD, NetBSD,
+           and some other BSD-derived systems
+          </para>
+         </listitem>
+         <listitem>
+          <para>
+           <option>e2fs</> to use the UUID library created by
+           the <literal>e2fsprogs</> project; this library is present in most
+           Linux systems and in Mac OS X, and can be obtained for other
+           platforms as well
+          </para>
+         </listitem>
+         <listitem>
+          <para>
+           <option>ossp</> to use the <ulink
+           url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID library</ulink>
+          </para>
+         </listitem>
+        </itemizedlist>
+       </listitem>
+      </varlistentry>
+
       <varlistentry>
        <term><option>--with-ossp-uuid</option></term>
        <listitem>
         <para>
-         Build components using the <ulink
-         url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID
-         library</ulink>.  Specifically, build the
-         <![%standalone-include[uuid-ossp]]>
-         <![%standalone-ignore[<xref linkend="uuid-ossp">]]> module,
-         which provides functions to generate
-         UUIDs.<indexterm><primary>UUID</primary></indexterm>
+         Obsolete equivalent of <literal>--with-uuid=ossp</literal>.
         </para>
        </listitem>
       </varlistentry>
diff --git a/doc/src/sgml/uuid-ossp.sgml b/doc/src/sgml/uuid-ossp.sgml
index c48106ba0f4ab8503637b2379157d0a4644e0e07..dbbea09313a4681b0297e069312b2780b40c8238 100644
--- a/doc/src/sgml/uuid-ossp.sgml
+++ b/doc/src/sgml/uuid-ossp.sgml
@@ -13,20 +13,6 @@
   are also functions to produce certain special UUID constants.
  </para>
 
- <para>
-  This module depends on the OSSP UUID library, which can be found at
-  <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
- </para>
-
- <note>
-  <para>
-   The OSSP UUID library is not well maintained, and is becoming increasingly
-   difficult to port to newer platforms.  If you only need randomly-generated
-   (version 4) UUIDs, consider using the <function>gen_random_uuid()</>
-   function from the <xref linkend="pgcrypto"> module instead.
-  </para>
- </note>
-
  <sect2>
   <title><literal>uuid-ossp</literal> Functions</title>
 
@@ -172,6 +158,39 @@ SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');
   </table>
  </sect2>
 
+ <sect2>
+  <title>Building <filename>uuid-ossp</></title>
+
+  <para>
+   Historically this module depended on the OSSP UUID library, which accounts
+   for the module's name.  While the OSSP UUID library can still be found
+   at <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>, it is not well
+   maintained, and is becoming increasingly difficult to port to newer
+   platforms.  <filename>uuid-ossp</> can now be built without the OSSP
+   library on some platforms.  On FreeBSD, NetBSD, and some other BSD-derived
+   platforms, suitable UUID creation functions are included in the
+   core <filename>libc</> library.  On Linux, Mac OS X, and some other
+   platforms, suitable functions are provided in the <filename>libuuid</>
+   library, which originally came from the <literal>e2fsprogs</> project
+   (though on modern Linux it is considered part
+   of <literal>util-linux-ng</>).  When invoking <filename>configure</>,
+   specify <option>--with-uuid=bsd</option> to use the BSD functions,
+   or <option>--with-uuid=e2fs</option> to
+   use <literal>e2fsprogs</>' <filename>libuuid</>, or
+   <option>--with-uuid=ossp</option> to use the OSSP UUID library.
+   More than one of these libraries might be available on a particular
+   machine, so <filename>configure</> does not automatically choose one.
+  </para>
+
+  <note>
+   <para>
+    If you only need randomly-generated (version 4) UUIDs,
+    consider using the <function>gen_random_uuid()</> function
+    from the <xref linkend="pgcrypto"> module instead.
+   </para>
+  </note>
+ </sect2>
+
  <sect2>
   <title>Author</title>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4b31c0a85e6f0f3d830cfa6234da170540dc2042..14119a15115cf9840e42c8155c567de5a454f193 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -163,11 +163,11 @@ with_perl	= @with_perl@
 with_python	= @with_python@
 with_tcl	= @with_tcl@
 with_openssl	= @with_openssl@
-with_ossp_uuid	= @with_ossp_uuid@
 with_selinux	= @with_selinux@
 with_libxml	= @with_libxml@
 with_libxslt	= @with_libxslt@
 with_system_tzdata = @with_system_tzdata@
+with_uuid	= @with_uuid@
 with_zlib	= @with_zlib@
 enable_rpath	= @enable_rpath@
 enable_nls	= @enable_nls@
@@ -240,7 +240,8 @@ DLLWRAP = @DLLWRAP@
 LIBS = @LIBS@
 LDAP_LIBS_FE = @LDAP_LIBS_FE@
 LDAP_LIBS_BE = @LDAP_LIBS_BE@
-OSSP_UUID_LIBS = @OSSP_UUID_LIBS@
+UUID_LIBS = @UUID_LIBS@
+UUID_EXTRA_OBJS = @UUID_EXTRA_OBJS@
 LD = @LD@
 with_gnu_ld = @with_gnu_ld@
 ld_R_works = @ld_R_works@
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index db930f5bb0e0313c067e2585e52e7acb65014e0f..5ff9e41212125bcc1030bae7ea52db22440d7959 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -602,9 +602,21 @@
 /* Define to 1 if you have the <utime.h> header file. */
 #undef HAVE_UTIME_H
 
+/* Define to 1 if you have BSD UUID support. */
+#undef HAVE_UUID_BSD
+
+/* Define to 1 if you have E2FS UUID support. */
+#undef HAVE_UUID_E2FS
+
 /* Define to 1 if you have the <uuid.h> header file. */
 #undef HAVE_UUID_H
 
+/* Define to 1 if you have OSSP UUID support. */
+#undef HAVE_UUID_OSSP
+
+/* Define to 1 if you have the <uuid/uuid.h> header file. */
+#undef HAVE_UUID_UUID_H
+
 /* Define to 1 if you have the `vsnprintf' function. */
 #undef HAVE_VSNPRINTF